Building lists of content items that are linked with its detail views is a common task when creating a website. For example, a typical list of news displays the title, the teaser and maybe the creation date or information about the author per entry/news. Moreover, a list might offer pagination or simple filter options to the website’s visitors. Those lists are realized by “Collectors” in OpenCms, whereby “Detail pages” are used to show the complete details of a news article, an event, a product or any other type of resource/content. This chapter introduces how to implement such lists using collectors and how to link from list entries to their detail pages.

Creating lists with collectors

In the following subsections, we describe how to build a list with a collector. The first subsection, and the section about the available collectors, is all you need to get a list. The other subsections just describe extra features.

1.1 Using collectors in JSPs

OpenCms provides the tag <cms:contentload> to collect XML resources. The tag's body is rendered once for each collected content and <cms:contentaccess> is used to get access the content loaded in the current run:

<cms:contentload collector="..." param="..." editable="true">
   <cms:contentaccess var="content" /> ... 
</cms:contentlaod>
The attributes of <cms:contentload>
collector

The name of the collector that should be used.

param

Configuration parameter for the chosen collector. For standard collectors, the syntax is: [path]|[resource type]|[count] to specifiy from wich folder (path) how many (count) resources of which type (resource type) should be collected.

editable

Set this attribute to true, to enable the direct edit option for the list (entries can directly be added, removed or edited).

A very simple example of creating a list with links to detail pages looks as follows:

<%@page buffer="none" session="false" taglibs="c,cms" %> 
<%-- The JSP HTML should be surrounded by block element --%>
<div>	
  <%-- Read collector paramter, e.g. from request --%>
  <c:set var="folder" value="${param.folder}"/>
  <c:set var="type" value="${param.type}"/>
  <c:set var="count" value="${param.count}"/> 
    <ul>
    <%-- Use <cms:contentload> with new collector--%>
    <cms:contentload collector="myCollector" param="${folder}|${type}|${count}">
      <%-- Access the content --%>      
      <cms:contentaccess var="content" />
      <c:set var="link"><cms:link>${content.filename}</cms:link></c:set>
      <li><a href="${link}">${content.value.Title}</a></li>			
    </cms:contentload>
  </ul>
</div>

1.2 Opening a detail page on click

The code <a href="<cms:link>${content.filename}</cms:link>">${content.value.Title}</a> will create a link that points on the current resource collected by the <cms:contentload>-tag. If you want OpenCms to open the detail view by clicking on that link, you have to perform the following steps in order to create a “Detail page”:

  • Go to the sitemap editor and open the "Create page" dialog.
  • Select the detail page for the resource type you want to create a detail page for from the upcoming dialog and place it somewhere you like into the sitemap.

OpenCms configures the new detail page automatically for the opened sub-sitemap. This new page will be used as detail page for all instances of the selected resource type. Now the link (constructed by the above shown code snippet) opens the detail page. Find more information about detail pages here.

It is important, that the link to the list entry that should link to the detail view is sourrounded by the <cms:link>-tag. This tag will manage the redirect from the URL of the resource of the list entry to its detail page.

1.3 Creating new content items using collectors

Typically a collector allows the creation of new content instances of the resource type it collects by clicking on the “plus” symbol of the flyout-menu a list entry. This functionality is available if the attribute editable is set to true in <cms:contentload> and the used collector is configured to allow for such editing. New resources are created inside a configured folder (see (sub-)sitemap configuration and module configuration), typically below a /.content/ folder. 

1.4 Available collectors

OpenCms ships with a whole bunch of collectors. The most useful are the Solr collectors.

  • All resources matching a user defined Solr query:
    • byQuery (executes the exact query)
    • byContext (considers the request context automatically, in particular locale and site root)
  • All resources in a folder or sub-tree:
    • allInFolder
    • allInSubTree
  • All resources in a folder or sub-tree, sorted by the value of the NavPos property:
    • allInFolderNavPos
    • allInSubTreeNavPos
  • All resources in a folder or sub-tree, sorted by the value of the release date:
    • allInFolderDateReleasedDesc
    • allInSubTreeDateReleasedDesc
  • All resources in a folder or sub-tree, sorted by collector.priority property and then by Title property:
    • allInFolderPriorityTitleDesc
    • allInSubTreePriorityTitleDesc
  • All resources in a folder or sub-tree, sorted by collector.priority property and then by collector.date property:
    • allInFolderPriorityDateAsc
    • allInSubTreePriorityDateAsc
    • allInFolderPriorityDateDesc
    • allInSubTreePriorityDateDesc
  • All resources in a folder or sub-tree, mapped to a given URI and sorted by the collector.priority property and then by the collector.date property:
    • allMappedToUriPriorityDateAsc
    • allMappedToUriPriorityDateDesc

1.5 Drag & drop for lists

Imagine a JSP providing a list of resources by the usage of the <cms:contentload>.  To drop JSPs directly into a container page OpenCms offers dynamic functions.

  • Create a new dynamic function. Usually this resource is a part of the module and should be created in folder /system/modules/{mymodule}/functions/.
  • Select the JSP containing the collector. 
  • To define the collector parameters set the initial request parameters in the dynamic function. E.g., use:
    • folder=/dev-demo/collector-with-detail-page/.content/article/
    • type=ddarticle
    • count=5
  • Open a container page in ADE and drop the new dynamic function onto the page.

1.6 Implementing own collectors

In order to develop a collector, which can be used with the <cms:collector>-tag, the collector must implement the interface I_CmsResourceCollector. The package org.opencms.file.collectors already provides a standard implementation for this interface with A_CmsResourceCollector. Extend this class, if you develop your own collector. Following methods have to be implemented:

  • List<String> getCollectorNames();
    The method has to return the names of the collectors implemented by your collector class.
  • String getCreateLink(CmsObject cms, String collectorName, String param)
            throws CmsException, CmsDataAccessException;

    The method has to return the link that should be executed when a user clicks on the direct edit "new" button on a list created by the named collector. If this method returns null, it indicates that the selected collector implementation does not support a "create link", and so the "new" button will not be shown on lists generated with this collector.
  • String getCreateParam(CmsObject cms, String collectorName, String param)
            throws CmsDataAccessException;

    This method has to return the parameter that is passed to getCreateLink(CmsObject cms, String collectorName, String param). If this method returns null, it indicates that the selected collector implementation does not support a "create link", and so no "new" button will be shown on lists generated with this collector.
  • List<CmsResource> getResults(CmsObject cms, String collectorName, String param)
                       throws CmsDataAccessException, CmsException;

    The function has to return the list of org.opencms.file.CmsResource objects that are gathered using the named collector.

1.6.1 Configuration of resource collectors

Edit opencms-vfs.xml and add following line to <collectors>-node (replacing the class given here by your own collector class) and restart the Servlet Container afterwards.

<collector class="org.opencms.dev.demo.CmsSimpleResourceCollector" order="180" />

Detail pages

Content items like news or events are usually displayed using detail pages. This way you don’t need to create a separate page for each and every new content item; but all content items of a specific resource type can be displayed using the same page arrangement. ‘Detail pages’ can be created with the sitemap editor for all configured resource types. In addition this concept allows you to generate human readable URLs for contents that are not dropped onto a container page but created in the /.content/ directory automatically, e.g., when using the “create” option of collectors or creating content via drag & drop.

2.1 Usage of detail pages

  • Open the "Create page" dialog in the sitemap editor.
  • From tab "Type pages" drop the page for one of the listed resource types into the sitemap.

The detail page is automatically configured by OpenCms in the sitemap configuration file. Now links to a content of the detail page's resource type should automatically be redirected to an automatically generated URL that starts with the URL of the detail page and is extended by a content specific part (the filename, or, if configured a special urlName).

See here, to find out how to link to a detail page.

2.2 Configurations for detail pages

If detail pages are allowed for a special resource type or not can be configured in the module or the sitemap configuration. Furthermore, the content-specific URL part can be configured and the template of detail pages must be configured adequately.

2.2.1 Configuring the content-specific URL part

By default, the filename of the content's resource is used as content-specific part of the generated URL. But, this can be overwritten by a mapping configuration in the content type definition (the .xsd that defines the content's structure). To, e.g., use the "Title" element of a content as content-specific URL part, add the line:

<mapping element="Title" mapto="urlName" />

to the .xsd that defines the content's type. You can use any other content element as well.

The element's value is not mapped unchanged to the URL-part. It is manipulated to make up a valid URL.

2.2.2 Configuring the template for detail pages

Add the attribute detailview="true" to the <cms:container>-tag in the template JSP, where the XML content should be displayed. Usually it is the container that contains the main content of a page, e.g:

<cms:container name="centercolumn" type="center" width="450" detailview="true" .../>

2.3 URL generation for detail pages

Resources created via “drag & drop” are typically located in a directory that is configured either in the module configuration or in the sitemap configuration. Usually it is a sub-directory of a /.content/ folder of a sitemap. If no detail page is configured, the URL for a news article points directly the the article's resource, e.g., it would look like: http://www.example.com/en/.content/news/news_00005.html. By using detail pages the URL is changed to {detail page URL}{a generated title}{a suffix}. This technique offers the capability to auto-generate meaningful URLs without /.content/ in it.

By configuring a detail page for the resource type football-news at: /en/football/news/ will make a news article about the defender Rafael that is located at: /en/.content/football-news/news_0096845.html and whose "Title"-element is mapped to "urlName" available under:

http://www.example.com/en/football/news/rafael-hopes-for-brazil-chance.html

2.4 Detail-only containers

In some cases you may want to add related content to a detail view of a news article (this may also be any other content type displayed using content collector lists, to keep it simple we call this type ‘news’). The related content may be a photo gallery or something that you want to place in a side column. Since OpenCms 9 this is possible to use detail-only containers for such purposes. These containers will only be rendered in case the template is used for a detail view and the contained elements will be individual for each news item.

To use this feature, place additional container tags into your template with the attribute detailonly set to true like this:

<cms:container name="leftcontainerDetail" detailonly="true" type="left" width="230" />

Usually when placing a content element on a container page, the reference to this element is stored within the container page XML-content. With the elements in detail containers, this would not work, as there is only one detail page content for many news items.

When using the detail containers feature OpenCms will automatically create and manage a new container page XML-content for each news item. Within this content the element references will be stored. In case of the news /.content/news/news_0001.html this would be /.content/news/.detailContainers/news_0001.html. So by convention the file is placed in a subfolder to the news item location called .detailContainers and it is named like the news itself. During the rendering process the same convention is used to look up detail container elements. So deleting a .detailContainers-folder will remove all related elements to the present news.