CQ - 将内容从一个页面移动到另一个页面

时间:2014-05-19 02:27:07

标签: cq5 jcr sling

我意识到这是一个非常具体的问题,但我想有人会遇到这个问题。所以我大约一年前创作了大约五十页左右。我们正在尝试使用标题和页脚中的新组件来修改页面。除主要内容区域中的内容保持不变外。因此,我试图将所有内容从旧页面移动到新页面,但只保留主要内容区域。问题是我不能仅仅将旧页面上的资源类型更改为指向新页面组件,因为内容不同,我在页眉和页脚中有一堆节点,我不会这样做#&# 39;不要。例如,这是我目前的内容结构:

旧内容

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 个答案:

答案 0 :(得分:1)

确实可以编写满足您需求的代码:

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中的文件夹结构弄清楚如何识别目标和目标页面,但基本逻辑应该相同

答案 1 :(得分:1)

你可以使用JCR API随意移动东西,我会

  1. 阻止用户访问相关内容。可以使用临时ACL完成,或者如果可以,可以通过关闭前端访问权来完成。
  2. 运行使用JCR API更改内容的脚本或servlet
  3. 检查结果
  4. 让用户再次访问内容
  5. 对于内容修改脚本,我建议修改单个页面的脚本(即您使用以/content/star-trek.modify.txt结尾的HTTP请求调用它),以便您可以在单个页面上运行它页面,测试,或一组页面一旦它的好。

    脚本从当前节点开始,递归到它以查找它知道如何修改的节点(基于它们的吊索:resourceType),修改它们并报告它在日志或其输出中所做的事情。

    要修改节点,脚本使用JCR Node API来移动东西(也许是Worskpace.move)。

答案 2 :(得分:0)

我在这里看到的结果的问题是你正在编写执行JCR操作的servlet来移动东西。虽然技术上有效,但它并不是一种可扩展或可重复使用的方法。你必须编写一些非常具体的代码,部署它,执行它,然后删除它(或者它永远存在于那里)。这是不切实际的,而不是完全RESTful。

以下是两个更好的选择:

我的一位同事编写了CQ Groovy控制台,它使您能够使用Groovy编写对存储库的更改脚本。我们经常将其用于内容转换,就像您所描述的那样。使用Groovy的好处在于它的脚本(不是编译/部署的代码)。如果需要,您仍然可以访问JCR API,但是控制台有一堆辅助方法可以使事情变得更加容易。我强烈推荐这种方法。

https://github.com/Citytechinc/cq-groovy-console

另一种方法是在AEM中使用批量编辑器工具。您可以导出TSV内容,进行更改,然后重新导入。您必须使用管理功能打开导入功能,但我已经成功使用了它。请注意,它有点错误,有数组值属性。