Thursday, September 09, 2010

dotCMS: paginate results from pulling related contents

Pull Related Content

In dotCMS, the #pullRelatedContent() macro is used to create a list of all content related to some base content through a named relationship.

Syntax for the call is as below. The nice thing about it is that the call doesn't care if your content inode refers to a child or parent to the relationship. For example, let's say you have a bunch of books and a bunch of authors linked through a relationship called book_authors. In the call below, content inode could the inode of a book or an author.

#pullRelatedContent("relationship name" "content inode" "limit" "sort by")

After the call, you will have a $list variable available that references a java.util.ArrayList with your results.

Paginating Content

When you have a query that you know will return a large set of results, you should paginate the results. This means showing only a portion of the results at a time with controls that let user go to the next/previous page or even click on a specific page number within the results. In dotCMS, the #pageContent() does this.

#pageContent("query" "sort by" "# per page" "# current page")

Actually, all it does is process your query and leave you with the following variables: list, totalResults and totalPages. You then output the actual pagination controls for yourself based on this information.

Paginating Related Content

Both #pageContent() and #pullRelatedContent() take query as a parameter and leave you with a $list - which means you cannot call #pageContent() on the results of #pullRelatedContent() (e.g. #pageContent(#pullRelatedContent(...), ...).

So how do you paginate related content?

The answer is that you need to use a relationship query in #pageContent(), providing the identity (not inode of the content whose related items you wish to show. I do this with my own macro, as below.

#macro ( paginateRelatedContent $relationshipName $baseInode )
   #set($x = 0)
   #set($x = $webapi.getIdentifierInode($baseInode))
   #if($x < 1)
      #set($x = $inode)
   #set($uQuery = "+type:content +live:true +deleted:false +${relationshipName}:${x}")
   #pageContent("$uQuery" "text1" "3" "$page")

Syntax is below.

#paginateRelatedContent("name of a relationship" "content inode")

Here is my post about this on the dotCMS Yahoo group: Paginate related content?

My dotCMS notes.