Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

How to perform pagination on Digital assets at the time of display its information?

Avatar

Employee Advisor

Using xpath query we can fetch the metadata from the repository and display the value of metadata on page.

But, if we are looking for pagination on top that. How can we achieve this? Can we implement display tag for the same?

 

Thanks

1 Accepted Solution

Avatar

Correct answer by
Level 7

Ok,well since you already are using the jcr:title the thing you have to do now is to follow the steps in the link (and the excerpt that I posted above) and register that jcr:title as a metadata property for images. Otherwise, there is no way for the assets method getMetadata() to know what other metadata there is. From the beginning that function only recognises the standard metadata properties hence why you don't see it in your map :)

So again, implement the changes to that the assets know of their new title property and then you can get also that one with the getMedata() method.

A bit of topic again but I still would recommend to get your hands dirty and try to change the code so that you use the standard property instead. It might pay off later on and it would be much easier to maintain and less extra properties to keep track of since it would be the standard CQ/AEM way of handling asset metadata. But thats just my preference and I also understand that it might take quite a while :)

I hope this will solve the issue
/Johan

View solution in original post

6 Replies

Avatar

Level 7

Hi Debal.
Are you trying to find all assets in the DAM and paginate those (and then show their individual metadata) ?

If so, the QueryBuilder API would work just great here. The following creates a new map of the search predicates and adds the path to the dam and the type to "dam:Asset".
 

Map<String, String> map = new HashMap<String, String>(); map.put("path", "/content/dam"); map.put("type", "dam:Asset");

The next part will handle the pagination for you:
 

map.put("p.offset", 0); map.put("p.limit", 20);

where the offset is the start of the resulting collection of asset and the limit it how many assets the result should contain. If we want to show 20 assets one each page we simply put the limit to 20. And for the first page we want the offset to be 0.  

 

Then we do the search with the following code and put our result in the SearchResult named result: 
 

Query query = builder.createQuery(PredicateGroup.create(map), session); SearchResult result = query.getResult();

After that we want to extract some metadata from our search. Why ? Well we want to see how many total results we had and how many pages it would take to display them all given the number of results we wanted to show on each page. This is all done by using the handy build in methods of the SearchResult. We put the total in the variable totalMatches and the numberOfPages with the following code:

// paging metadata int hitsPerPage = result.getHits().size(); // 20 (set above) or lower long totalMatches = result.getTotalMatches(); long offset = result.getStartIndex(); long numberOfPages = totalMatches / 20;

In the last step we want to iterate over our results and display the asset information (the metadata). This can be done with the following code:
 

for (Hit hit : result.getHits()) { //Something in the lines of... Asset damAsset = hit.getResource().adaptTo(Asset.class); Map<String, Object> metadata = damAsset.getMetadata(); String displayTitle = "No title" if(metadata.containsKey("dc:title")){ Object titleObject = metadata.get("dc:title"); if (titleObject instanceof Object[]) { Object[] titleArray = (Object[]) titleObject; displayTitle = (titleArray.length > 0) ? titleArray[0].toString() : displayTitle; } else { displayTitle = titleObject.toString(); } } logger.info("Asset title:" + displayTitle); }

Here we iterate over all the results and then adapt each hit to an asset from which we can retrieve it's metadata.
Then we log this one to the log :) Of course you will do something different with this :)

In the last step we want to handle the pagination this is done by using some other great built in features. It could look like this:
 

<% pageContext.setAttribute("result", result); %> <ul> <li> <a href="${currentPage.path}.${result.previousPage.index}.html">Previous</a> </li> <c:forEach var="page" items="{result.resultPages}"> <c:choose> <c:when test="${page.currentPage}"> <li><a href="">${page.index + 1}</a></li> </c:when> <c:otherwise> <li> <a href="${currentPage.path}.${page.index}.html">${page.index + 1}</a> </li> </c:otherwise> </c:choose> </c:forEach> <li> <a href="${currentPage.path}.${result.nextPage.index}.html">Next</a> </li> </ul>

And that would be a quick version of implementing pagination and asset metadata extraction together.

Once you see that this works, and of course handled the different query parameters sent to the page that you are on you could start to extract most of this into you own custom tag library.
There are a lot of great guides on that around. For more info about the querybuilder API take a look at this page: http://dev.day.com/docs/en/cq/current/dam/customizing_and_extendingcq5dam/query_builder.html

Good Luck
/Johan

Avatar

Employee Advisor

Hi Johan,

Thanks for your reply. But, I have 1 issue. I have created one custom metadata named: title and its name space : ./jcr:title

 When I am trying to execute - Map<String,Object> metadata = damAsset.getMetadata() 

jcr:title is not included in the map.

2.   metadata.containsKey("jcr:title") returns false.

For the reference I have attached 1 screenshot.

Please look into that issue. I need to perform[img]cutom-metadata.PNG[/img] this approach for custom metadata.

Thanks

Avatar

Level 5

Title for DAM is accessed in different way something like

    public String getTitle() throws Exception {

        if (isPage()) {

            return valueMap.get(JcrConstants.JCR_TITLE, "");

        } else {

                valueMap.get(DamConstants.METADATA_FOLDER+"/"+DamConstants.DC_TITLE, "");

        }

    }

Avatar

Level 7

Hi,
first of would it not be better to use the title metadata that is already there (dc:title) ?
Since you probably have your reasons for not doing so it could be possible to reach the metadata that you have created if you read this article.

http://dev.day.com/docs/en/cq/current/dam/metadata_for_digitalassetmanagement.html

It states that if the assets are about to use your own metadata properties (for edit and retrieval) you must first declare them for the dam assets like images. This is from the link:
 

You can make new metadata properties available for all assets by configuring the metadata dialog box.

Currently, metadata folders reside in /libs/dam/content/asseteditors/ and are organized as follows:

  • Format-specific metadata reside at the path image/format/formitems.xml: for example,image/jpeg/formitems.xml, which is used for all jpegs. 

  • Metadata for images that do not have a more specific metadata editor reside in image/formitems.xml.

This setup lets site owners better control their metadata vocabularies.

To configure a new metadata property so that it is available for any assets that have not been explicitly configured otherwise:

  1. Create /apps/dam/content/asseteditors/formitems (copy the form from/libs/dam/content/asseteditors/formitems).

  2. Add a new control and set the name to ./namespace:property e.g, ./dam:Example.

  3. Save your changes. After saving, all CQ DAM users can view and edit this property.

I would try and create you own namespaced property there and see if it solves your problem.
Good Luck 

/Johan

Avatar

Employee Advisor

Hi Johan,

Yes, have got your point. When I implemented that code , it  came to my mind to use dc:title namespace instead of jcr:title.

But, already I have implementd jcr:title .Now if I switch to dublin core metadata schema, then need to change in many places in my application.

 

Thanks

Avatar

Correct answer by
Level 7

Ok,well since you already are using the jcr:title the thing you have to do now is to follow the steps in the link (and the excerpt that I posted above) and register that jcr:title as a metadata property for images. Otherwise, there is no way for the assets method getMetadata() to know what other metadata there is. From the beginning that function only recognises the standard metadata properties hence why you don't see it in your map :)

So again, implement the changes to that the assets know of their new title property and then you can get also that one with the getMedata() method.

A bit of topic again but I still would recommend to get your hands dirty and try to change the code so that you use the standard property instead. It might pay off later on and it would be much easier to maintain and less extra properties to keep track of since it would be the standard CQ/AEM way of handling asset metadata. But thats just my preference and I also understand that it might take quite a while :)

I hope this will solve the issue
/Johan