We show a dynamic function that collects items and allows to link to a detail view of each item.
Click on the headings of the list entries to see their detail views. If you are offline, you might also change some parameters of the function that provides the list.
In this demo different things are of interest:
We discuss these questions in the following subsections.
The list, shown in the example is generated by a dynamic function. The function provider looks as follows:
<%@page buffer="none" session="false" trimDirectiveWhitespaces="true" taglibs="c,cms,fn" %>
<cms:formatter var="con" rdfa="rdfa">
<div>
<div class="headline"><h3 ${rdfa.Title}><c:out value="${con.value.Title}" escapeXml="false" /></h3></div>
<c:set var="folder">
<c:choose>
<c:when test="${fn:startsWith(param.folder,'/system') or fn:startsWith(param.folder,'/shared')}">
${param.folder}
</c:when>
<c:otherwise>
${cms.requestContext.siteRoot}${param.folder}
</c:otherwise>
</c:choose>
</c:set>
<%-- Define a Solr query --%>
<c:set var="solrQuery">fq=parent-folders:"${folder}"&fq=type:${param.type}&rows=${param.count}&sort=lastmodified desc</c:set>
<%-- Define a create path --%>
<c:set var="createPath">${param.folder}</c:set>
<%-- Collect the resources --%>
<cms:contentload collector="byContext" param='${solrQuery}|createPath=${createPath}article_%(number).xml'
preload="true" >
<cms:contentinfo var="info" />
<c:choose>
<c:when test="${info.resultSize > 0}">
<cms:contentload editable="true">
<cms:contentaccess var="content" />
<div>
<h4><a href="<cms:link>${content.filename}</cms:link>">${content.value.Title}</a></h4>
<hr />
</div>
</cms:contentload>
</c:when>
<c:otherwise>
Nothing found for query:<br/><em>${solrQuery}</em>
</c:otherwise>
</c:choose>
</cms:contentload>
</div>
</cms:formatter>
The most interesting part is the <cms:contentload>
-tag. It is used twice. Once, in the "outer" use, with preload="true"
as attribute and the attributes collector
and param
. The collector
attribute specifies which collector is used and the param
attribute configures the collector. In the example, we use the Solr-collector byQuery
and configure it with a Solr query and (after the |
) with the path and a name scheme that specifies where and under which name new resources are created.
Setting preload to true avoids loading the resources completely. The loaded information suffices to know, e.g., the number of results, as is read via info.resultSize
from the info object exposed by <cms:contentinfo var="info" />
. If we have at least one result, we start loading the content fully by the "inner" <cms:contentload>
. It takes over collector and param from the outer tag and the additional attribute editable="true"
enables us to edit, add and delete list entries.
The "inner" <cms:contentload>
's body is looped through for each collected content and via <cms:contentaccess>
we get access to the current content in the same way we get access to a content in a formatter. The link to ${content.filename}
by default links to the content itself. But, if a detail page for contents of that type is configured, <cms:link>
redirects the link to this detail page.
If detail pages for a content type are allowed (what is configured in the module configuration of the module where the resource type is defined), you can add a detail page via the sitemap editor. Therefore, go to the sitemap editor, open the "Add wizard" and choose the tab "Detail pages". Now you can select the detail page for your type and drop it in the sitemap.
In the example, we added the page "Article detail pages" as detail page for the type "documentation-demo-article". The page is marked as such a detail page in the sitemap by stating the type in brackets and using the type's icon for the page entry:
While the first part of the URL of the detail view of an article is quite clear: It is the detail pages URL, the last, content-specific part is not that obvious. In the demo, it is generated from the article's Title elements. This behavior is configured in the content type definition of the article. In the <appinfo>-part a mapping from the Title element to urlName is configured:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:include schemaLocation="opencms://opencms-xmlcontent.xsd" />
<xsd:element name="DocumentationDemoArticles" type="OpenCmsDocumentationDemoArticles" />
<xsd:complexType name="OpenCmsDocumentationDemoArticles">
<xsd:sequence>
<xsd:element name="DocumentationDemoArticle" type="OpenCmsDocumentationDemoArticle"
minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="OpenCmsDocumentationDemoArticle">
<xsd:sequence>
<xsd:element name="Title" type="OpenCmsString" />
<xsd:element name="Text" type="OpenCmsHtml" />
<xsd:element name="Image" type="OpenCmsVfsImage" minOccurs="0" />
<xsd:element name="Script" type="OpenCmsString" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="language" type="OpenCmsLocale" use="optional" />
</xsd:complexType>
<xsd:annotation>
<xsd:appinfo>
<layouts>
<layout element="Script" widget="TextareaWidget" configuration="10" />
</layouts>
<mappings>
<mapping element="Title" mapto="urlName" />
</mappings>
</xsd:appinfo>
</xsd:annotation>
</xsd:schema>
It is possible to map every other element instead of Title. If no element is mapped, the resource-id of the article content would be used for the content-specific URL part.