Widget Builder: Building a Related Content Widget Builder Widget

Thu Oct 22, 2015

Technical Skills: Intermediate to Advanced Widget Developer

This post demonstrates how to build a widget that displays a static list of “Related Content” pages stored in the Percussion content repository. The Widget takes advantage of an advanced feature of Percussion called a Content Finder.

What is a Content Finder?  

With Percussion CM1, content finders are used to locate content within the system. One of the Finders provided by CM1 is the Auto Widget Content Finder for use in CM1 Widgets. The Finder’s job is to take a set of parameters and return a list of Assets or Pages in the system that match a specific set of criteria or query to the Display template. The template can then do interesting things with the List.

The Auto Widget Content finder is accessed using the systems $rx.pageutils Velocity method.

A snippet of this Display Template code for returning lists of Content looks like this:

$rx.pageutils.widgetContents($sys.assemblyItem,

$perc.widget,

“Java/global/percussion/widgetcontentfinder/perc_AutoWidgetContentFinder”,

$params)

The only parameter above that matters to our custom Widget is $params. This variable needs to be setup in order for the Content Finder to work. The statement will return a List of matching content.

Setting up the Parameters

The Auto Widget Content Finder expects the $params variable to be setup to hold two values:

query:  The JCR SQL query for the content in the repository that the Widget should list.

max_results: The maximum number of items that the query should return.

JCR SQL is a standard for querying content from CMS repository databases.  Percussion provides basic support for querying content with JCR version 1.

The following query will return all Pages in the system:

select rx:sys_contentid, rx:sys_folderid from rx:percPage  where jcr:path like ‘%’

(this is not a good query for large sites!)

The most important part of the query above for the Widget Builder designer is the part that comes after the from keyword in the statement above. In the statement above rx:percPage indicates that we are running this query on all Percussion (perc) Pages.

Percussion Asset types can be queried by looking at the Asset’s type name in the Finder, and then pre-pending perc to the type name.

For example.  To get a list of all File Assets the following query could be used:

select rx:sys_contentid, rx:sys_folderid from rx:percFile

When working with Widget Builder widgets, the Prefix for the widget and the Widget Name can be used. If we were querying for all Assets in the system that were of the same type as my RelatedContent Widget below, the query would look like:

select rx:sys_contentid, rx:sys_folderid from rx:percRelatedContent

The main point here is that the from statement is responsible for telling the Auto Widget Content Finder what Asset Types it should search for.

The second part of our example Page query above is poorly written as it will return every Page in the system. You will almost never want this as it will make your Widget slow and will slow down publishing wherever it used.  

A common way to further restrict the query is by using the Path in the system. This is accomplished by using the built-in jcr:path field in the criteria for the JCR query.  Here is our Page query re-written to filter by a Path, I have a site named “widgetsite”.

select rx:sys_contentid, rx:sys_folderid from rx:percPage  where jcr:path like ‘//Sites/widgetsite/%’

This query is much better as it will only return Pages in the system that live under “widgetsite” in my site list.  For a custom Widget, the Site Location would be a custom field on the Widget.

Now with all that query stuff out of the way, the second parameter that the Auto Widget Content Finder needs is max_results.  This is a numeric value that tells the system to stop searching for content after that number of results is found.  For a short list like our Related Content widget, this would typically be limited at 5,10, or 15.  Specifying a limit is important to performance when publishing.    

Putting it All Together

Now that we understand the basics of the Auto Widget Content Finder and content repository JCR queries, we can stitch together our basic “Related Content” list widget.

We’ll do this section Step by Step.

Step 1.  Create the Widget

Using the Widget Builder, create a new Widget with the following properties.  Feel free to use your name as the developer and your Organizations “prefix” for the Widget but make sure the name is the same to simplify the walkthrough:


Step 2. Add Widget Fields

Step 3: Edit the Display Template

The template source is included in text form here for ease of copy and paste:

#set($query = "select rx:sys_contentid, rx:sys_folderid from rx:percPage  where jcr:path like '$location/%' AND rx:page_tags = '$tags'") ##
##
#set($params=$rx.string.stringToMap(null)) ##
#set($dummy=$params.put('max_results', $maxpages)) ##
#set($dummy=$params.put('query', $query)) ##
##
#set($finderName="Java/global/percussion/widgetcontentfinder/perc_AutoWidgetContentFinder") ##
##
#set($relresults=  $rx.pageutils.widgetContents($sys.assemblyItem, $perc.widget, $finderName, $params))##
##
#foreach($result in $relresults)##
#set($pagelink=$tools.esc.html($rx.pageutils.itemLink($perc.linkContext, $result)))##
#set($linkTitle=$rx.pageutils.html($result.node,"resource_link_title,sys_title", "-no-title-"))##
<a class="related-link" href="$!{pagelink}" alt="$!{linkTitle}" title="$!{linkTitle}">$!{linkTitle}</a><br />
$result.node.getProperty('rx:page_summary').getString()
#end##

Step 4.  Test The Widget

Add tags to Page Metadata on a couple of Pages in your target search Site Location.  In the screen shots below I am searching for a max of 10 Pages, in the (note the // ) Site Location that have a Tag of “test” applied to their Page Metadata.  

I prefer to test with a blank Page Template while writing Widgets.  This way there isn’t much clutter while testing the Widget.  If you do have a typo,  (they are unavoidable) you will see an “Assembly Error” where the Widget should appear on the page.  Fix any typos in your Widget’s Display template, Redeploy,  and refresh the Preview window to make the Assembly Error go away.  This often takes a couple of tries to get things right.

After fixing any typos like that in the demonstration error above, your fantastically designed “Related Content” widget should display a list of related content  by tag from the Site Location configured in the Widget. All that’s left from a Presentation perspective is to Style those classes in your main CSS resource file. 

The page links will generate in “Preview” mode when Previewing, and the Published mode when publishing.


The example template in the post does minimal error handling of user input. We’ll look at validating user input and sane defaults in a future post. Until this Widget has Validation enabled, it may make sense to lock it down at the Template level so that your Content Maintainers can’t go wild and do things like select 20,000 pages.   

Happy Widgeting!

Nate Chadwick
Nate Chadwick
Vice President of Products & Services | Percussion Software

N/A

comments powered by Disqus