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.
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.
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>
<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>
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”:
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.
<cms:link>
-tag. This tag will manage the redirect from the URL of the resource of the list entry to its detail page.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.
OpenCms ships with a whole bunch of collectors. The most useful are the Solr collectors.
byQuery
(executes the exact query)byContext
(considers the request context automatically, in particular locale and site root)allInFolder
allInSubTree
NavPos
property:
allInFolderNavPos
allInSubTreeNavPos
allInFolderDateReleasedDesc
allInSubTreeDateReleasedDesc
collector.priority
property and then by Title
property:
allInFolderPriorityTitleDesc
allInSubTreePriorityTitleDesc
collector.priority
property and then by collector.date
property:
allInFolderPriorityDateAsc
allInSubTreePriorityDateAsc
allInFolderPriorityDateDesc
allInSubTreePriorityDateDesc
collector.priority
property and then by the collector.date
property:
allMappedToUriPriorityDateAsc
allMappedToUriPriorityDateDesc
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.
/system/modules/{mymodule}/functions/
.folder=/dev-demo/collector-with-detail-page/.content/article/
type=ddarticle
count=5
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;
String getCreateParam(CmsObject cms, String collectorName, String param)
throws CmsDataAccessException;
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;
org.opencms.file.CmsResource
objects that are gathered using the named collector.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" />
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.
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.
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.
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.
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" .../>
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
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.