CQ - перемещение контента с одной страницы на другую
Я понимаю, что это довольно специфический вопрос, но я думаю, что кто-то сталкивался с этим раньше. Итак, у меня есть около пятидесяти страниц или около того, которые были созданы около года назад. Мы пытаемся обновить страницу новыми компонентами, особенно в верхнем и нижнем колонтитулах. За исключением контента в области основного контента, он останется прежним. Поэтому я пытаюсь перенести все со старых страниц на новые, но просто сохранить область основного контента. Проблема в том, что я не могу просто изменить тип ресурса на старой странице, чтобы он указывал на новые компоненты страницы, потому что содержимое отличается, и у меня будет несколько узлов в верхнем и нижнем колонтитулах, которые мне не нужны. Например, вот моя текущая структура контента:
Старый контент
star-trek
jcr:content
header
nav
social
chat
main-content
column-one
column-two
footer
sign-up
mega-menu
Новый контент
star-wars
jcr:content
masthead
mega-menu
main-content
column-one
column-two
bottom-footer
left-links
right-links
У кого-нибудь есть идеи о том, как переместить только контент в узле основного контента и каким-то образом удалить другие узлы. Я пытаюсь как-то сделать это программно, потому что я не хочу создавать 50 страниц с нуля. Любая помощь приветствуется!
3 ответа
Вы можете использовать JCR API для перемещения по желанию, я бы
- Запретить пользователям доступ к рассматриваемому контенту. Это можно сделать с помощью временных списков ACL или, если возможно, путем закрытия доступа к интерфейсу.
- Запустите скрипт или сервлет, который изменяет содержимое с помощью API-интерфейсов JCR.
- Проверьте результаты
- Позвольте пользователям снова получить доступ к контенту
Для сценария изменения содержимого я предлагаю сценарий, который изменяет одну страницу (т.е. вы вызываете его с помощью HTTP-запроса, заканчивающегося в /content/star-trek.modify.txt), чтобы вы могли запустить его либо на одной странице, для тестирование или на группе страниц, когда это хорошо.
Сценарий запускается из текущего узла, рекурсивно обращается к нему, чтобы найти узлы, которые он знает, как изменить (на основе их слинга: resourceType), модифицирует их и сообщает, что он сделал, в журналах или на своем выходе.
Чтобы изменить узлы, сценарий использует API-интерфейсы JCR Node для перемещения (и, возможно, Worskpace.move).
Действительно возможно написать код, который делает то, что вам нужно:
package com.test;
import java.io.File;
import java.io.IOException;
import javax.jcr.ItemExistsException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Node;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.core.TransientRepository;
import org.xml.sax.SAXException;
public class test {
public void test(Document doc) throws RepositoryException {
try {
// Create a connection to the CQ repository running on local host
Repository repository = JcrUtils
.getRepository("http://localhost:4502/crx/server");
System.out.println("rep is created");
// Create a Session
javax.jcr.Session session = repository.login(new SimpleCredentials(
"admin", "admin".toCharArray()));
System.out.println("session is created");
String starTrekNodePath = "/content/path/";
String starWarsNodePath = "/content/anotherPath"
Node starTrekpageJcrNode = null;
Node starWarstext = null;
setProperty(java.lang.String name, Node value)
boolean starTrekNodeFlag = session.nodeExists(starTrekNodePath);
boolean starWarsNodeFlag = session.nodeExists(starWarsNodePath);
if (starTrekNodeFlag && starWarsNodeFlag) {
System.out.println("to infinity and beyond");
Node starTrekNode = session.getNode(starTrekNodePath);
Node starWarsNodeFlag = session.getNode(starWarsNodePath);
//apply nested looping logic here; to loop through all pages under this node
//assumption is that you have similar page titles or something
//on these lines to determine target and destination nodes
//2nd assumption is that destination pages exist with the component structures in q
//once we have the target nodes, the following segment should be all you need
Node starTrekChildNode = iterator.next();//assuming you use some form of iterator for looping logic
Node starWarsChildNode = iterator1.next();//assuming you use some form of iterator for looping logic
//next we get the jcr:content node of the target and child nodes
Node starTrekChildJcrNode = starTrekChildNode.getNode("jcr:content");
Node starWarsChildJcrNode = starWarsChildNode.getNode("jcr:content");
// now we fetch the main-component nodes.
Node starTrekChildMCNode = starTrekChildJcrNode.getNode("main-content");
Node starWarsChildMCNode = starWarsChildJcrNode.getNode("main-content");
//now we fetch each component node
Node starTrekChildC1Node = starTrekChildMCNode.getNode("column-one");
Node starTrekChildC2Node = starTrekChildMCNode.getNode("column-two");
Node starWarsChildC1Node = starWarsChildMCNode.getNode("column-one");
Node starWarsChildC2Node = starWarsChildMCNode.getNode("column-two");
// fetch the properties for each node of column-one and column-two from target
String prop1;
String prop2;
PropertyIterator iterator = starTrekChildC1Node.getProperties(propName);
while (iterator.hasNext()) {
Property prop = iterator.nextProperty();
prop1 = prop.getString();
}
PropertyIterator iterator = starTrekChildC2Node.getProperties(propName);
while (iterator.hasNext()) {
Property prop = iterator.nextProperty();
prop2 = prop.getString();
}
// and now we set the values
starWarsChildC1Node.setProperty("property-name",prop1);
starWarsChildC2Node.setProperty("property-name",prop2);
//end loops as appropriate
}
Надеюсь, это должно поставить вас на правильный путь. Вы должны выяснить, как вы хотите определить целевую и целевую страницы, основываясь на структуре вашей папки в /content
, но основная логика должна быть такой же
Проблема с результатами, которые я вижу здесь, состоит в том, что вы пишете сервлеты, которые выполняют операции JCR, чтобы перемещать вещи. Хотя технически это работает, на самом деле это не масштабируемый или повторно используемый способ сделать это. Вы должны написать какой-то очень специфический код, развернуть его, выполнить, а затем удалить его (или он существует вечно). Это отчасти непрактично и не совсем ОТЛИЧНО.
Вот два лучших варианта:
Один из моих коллег написал консоль CQ Groovy, которая дает вам возможность использовать Groovy для создания сценариев изменений в репозитории. Мы часто используем его для преобразования контента, как вы описали. Преимущество использования Groovy в том, что это скрипт (а не скомпилированный / развернутый код). У вас по-прежнему есть доступ к JCR API, если вам это нужно, но в консоли есть несколько вспомогательных методов, которые еще больше упрощают работу. Я очень рекомендую этот подход.
https://github.com/Citytechinc/cq-groovy-console
Другой подход заключается в использовании инструмента Bulk Editor в AEM. Вы можете экспортировать TSV контента, внести изменения, а затем повторно импортировать. Вам придется включить функцию импорта с помощью административной функции, но я использовал ее с некоторым успехом. Осторожно, это немного глючит, со свойствами значений массива.