AEM Querybuilder 获得引用

AEM Querybuilder Getting If Referenced

我帮助监督(质量保证)AEM 上的一个网站,该网站拥有大约 65,000 页、320,000 项资产和大约 300 名用户能够 post 并进行更改。非常有用的一件事是一位前 IT 员工为我们编写的脚本,该脚本使用 querybuilder servlet 进行查询并提取页面和资产的完整列表。我已经能够获取此输出并使用它构建各种自动报告。

我一直无法弄清楚的一件事是如何查明资产或页面是否被另一个页面引用。我关心的主要事情只是一个简单的 true/false 是否被引用。理想情况下,如果它可以在初始查询中并且不必对每个单独的资产进行查询,我会喜欢它,但如果这是唯一的方法,那么我想它在理论上是可以接受的。

我目前可以 运行 获取有关资产的一些信息的示例查询(我将此示例限制为 5 个结果):

http://localhost:4502/bin/querybuilder.json?p.hits=selective&p.offset=0&p.limit=5&p.properties=jcr%3acontent%2fmetadata%2fdc%3aformat%20jcr%3acontent%2fmetadata%2fdc%3atitle%20jcr%3apath%20&path=%2fcontent%2fdam&type=dam%3aAsset

有什么方法可以添加一个字段用于引用它吗?或者所有对它的引用的数组?

我们目前运行正在使用 AEM 6.2,但很快就会升级到 6.4。

谢谢!

根据您的要求,您可以利用 AssetReferenceSearch API,它可以提供页面中使用的资产的详细信息(节点类型 cq:Page).

您可以使用以下代码来完成您的任务 -

package org.redquark.aem.assets.core;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.servlet.Servlet;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.dam.api.Asset;
import com.day.cq.dam.commons.util.AssetReferenceSearch;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * @author Anirudh Sharma
 *
 */
@Component(
        service = Servlet.class, 
        property = { 
                "sling.servlet.methods=GET", 
                "sling.servlet.resourceTypes=cq/Page",
                "sling.servlet.selectors=assetreferences", 
                "sling.servlet.extensions=json", 
                "service.ranking=1000" 
                }
        )
public class FindReferencedAssetsServlet extends SlingSafeMethodsServlet {

    // Generated serial version UID
    private static final long serialVersionUID = 8446564170082865006L;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private static final String DAM_ROOT = "/content/dam";

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {

        response.setContentType("application/json");

        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        try {

            // Get the current node reference from the resource object
            Node currentNode = request.getResource().adaptTo(Node.class);

            if (currentNode == null) {
                // Every adaptTo() can return null, so let's handle the case here
                // However, it is very unlikely
                log.error("Cannot adapt resource {} to a node", request.getResource().getPath());
                response.getOutputStream().print(new Gson().toString());

                return;
            }

            // Using AssetReferenceSearch which will do all the work for us
            AssetReferenceSearch assetReferenceSearch = new AssetReferenceSearch(currentNode, DAM_ROOT,
                    request.getResourceResolver());

            Map<String, Asset> result = assetReferenceSearch.search();

            List<AssetDetails> assetList = new LinkedList<>();

            for (String key : result.keySet()) {

                Asset asset = result.get(key);

                AssetDetails assetDetails = new AssetDetails(asset.getName(), asset.getPath(), asset.getMimeType());

                assetList.add(assetDetails);
            }

            String jsonOutput = gson.toJson(assetList);

            response.getOutputStream().println(jsonOutput);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }
}

对应的AssetDetails模型class如下-

package org.redquark.aem.assets.core;

/**
 * @author Anirudh Sharma
 */
public class AssetDetails {

    private String name;
    private String path;
    private String mimeType;

    /**
     * @param name
     * @param path
     * @param mimeType
     */
    public AssetDetails(String name, String path, String mimeType) {
        this.name = name;
        this.path = path;
        this.mimeType = mimeType;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the path
     */
    public String getPath() {
        return path;
    }

    /**
     * @param path the path to set
     */
    public void setPath(String path) {
        this.path = path;
    }

    /**
     * @return the mimeType
     */
    public String getMimeType() {
        return mimeType;
    }

    /**
     * @param mimeType the mimeType to set
     */
    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }
}

现在,您可以通过以下请求调用此 servlet -

http://localhost:4502/content/we-retail/language-masters/en/men.assetreferences.json.

这将给出以下格式的输出

[
  {
    "name": "running-trail-man.jpg",
    "path": "/content/dam/we-retail/en/activities/running/running-trail-man.jpg",
    "mimeType": "image/jpeg"
  },
  {
    "name": "enduro-trail-jump.jpg",
    "path": "/content/dam/we-retail/en/activities/biking/enduro-trail-jump.jpg",
    "mimeType": "image/jpeg"
  },
  {
    "name": "indoor-practicing.jpg",
    "path": "/content/dam/we-retail/en/activities/climbing/indoor-practicing.jpg",
    "mimeType": "image/jpeg"
  }
]

您可以根据需要编辑资产详情class。

希望对您有所帮助。快乐编码!!!

有一个 OOTB servlet return 引用特定页面或资产的页面列表

要检查页面或资产是否被引用,请使用

https://localhost:4502/bin/wcm/references?
_charset_=utf-8
&path=<path of the page>
&predicate=wcmcontent
&exact=false

输出将是一个 json 响应,其中包含名称 'pages' 的引用数组。如果页面未被引用,它将是一个空数组。

这个 servlet 使用 ReferenceSearch API 另一个答案提到。如果您在 AEM 之外需要此值作为 JSON,您可以立即使用 OOTB,而无需编写自己的 servlet。