Search the documentation
 Show GitHub edit links  Hide GitHub edit links
Documented since: 10.5.1 Latest revision for: 10.5.1 Valid for OpenCms: 10.5.2

This is a tutorial on how to define and configure a very simple content type. It is meant as a starting point for content definition and links to many more specific topics (in each of the sections).

What we will do

In the topic "Creating a template JSP" you learn how to create an OpenCms template starting with a static HTML prototype. In one of the steps, you shall define content types. Here we give a step by step example on defining a content type demo-content with

  • A title as string that is also mapped to the title property
  • An HTML text
  • An image
  • A link

Moreover we

  • Set up a suitable formatter for contents of the type
  • Configure the formatter to fit for containers of type center, which is the main container in the template defined in the topic "Creating a template JSP".

"Defining" and "Setting up" is maybe said to much. As far as possible, we just use the content as defined automatically and only explain the definition.

Adding a content type

A content type is always defined in a module. We assume there is a module my.template from "Creating a template JSP" to define the content type in. Open the Module management and choose the module my.template by clicking on the module's name in the list of modules.

Now there's an option "Add resource type"We use "content type" and "resource type" synonym here.:

Click the "Add resource type" option, and a dialog to enter details for your new type appears. Fig. [type definition] shows it with the form already filled suitable for the type we want to add.

Fig. [type definition]: The dialog for type defintion with the details for our type already inserted

The "Type id" is auto-generated by the system, you can change it, but it must be unique on the OpenCms installation. It's used internally to identify the content type. "Name" and "Schema type name" must be unique as well. The other values are optional. They are localized (in your workplace locale) information about the content that is used, e.g., in the "Add wizard" used to drag&drop content on a container page.

When you entered the details, click "Ok" and the add wizard will run. It adds the type definition to the module configuration, creates an example schema, a formatter and formatter configuration for the type. If you want to see the type definition, look out for demo-content in the opencms-modules.xml under {web-app home}/WEB-INF/config/. You will find a node resourcetype and a node explorertype. We will concentrate on adjusting schema, formatter and formatter configuration and leave configuration details aside.

If you want more information:

The content's schema

The wizard we ran to add the new content type, created a file demo-content.xsd under /system/modules/my.template/schemas/. The folder schemas/ below the module's main folder is (by convention) the suitable place for such schema files.

The schema describes the structure of the content and it's behavior. All schemas of content types have the same "structural wrapper" and a sequence (or choice) of content elements specific to the type. Here's the automatically generated schema, explanations follow.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  
  <xsd:include schemaLocation="opencms://opencms-xmlcontent.xsd"/>
  
  <xsd:element name="DemoContents" type="OpenCmsDemoContents"/>
  <xsd:complexType name="OpenCmsDemoContents">
    <xsd:sequence>
      <xsd:element name="DemoContent" type="OpenCmsDemoContent" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="OpenCmsDemoContent">
    <xsd:sequence>
      <xsd:element name="Title" type="OpenCmsString" />
      <xsd:element name="Text" type="OpenCmsHtml" />
      <xsd:element name="Image" type="OpenCmsVfsFile" />
      <xsd:element name="Link" type="OpenCmsVarLink" minOccurs="0" />
    </xsd:sequence>
    <xsd:attribute name="language" type="OpenCmsLocale" use="required"/>
  </xsd:complexType>

  <xsd:annotation>
    <xsd:appinfo>
      <mappings>
        <mapping element="Title" mapto="property:Title" />
        <mapping element="Title" mapto="urlName" />
      </mappings>
      <defaults>
        <default element="Title" value="Add a new title here" />
        <default element="Text" value="Add your text" />
      </defaults>
      <layouts>
        <layout element="Text" widget="HtmlWidget" configuration="downloadgallery" />
        <layout element="Image" widget="ImageGalleryWidget" configuration="{useformat:true}" />
      </layouts>
      <validationrules/>
      <relations/>
      <searchsettings containerPageOnly="true"/>
      </xsd:appinfo>
</xsd:annotation>

</xsd:schema>
  • In the schema, you find the "Schema type name" "DemoContent" that we specified for our content type. It's used in the "structural wrapper" that's similar for each content type.
  • The elements, that the content has, are are defined via the <xsd:element> nodes under <xsd:complexType name="OpenCmsDemoContent">/<xsd:sequence>. These are the nodes you alter specifically for your type. We just stick to the elements defined by default. A valuable hint for the element nodes concerns the type attribute. OpenCms has multiple build in schema types for various purposes. OpenCmsString is great for Strings, OpenCmsHtml for Html, OpenCmsVfsFile for internal links, OpenCmsVarLink for links that can be internal or external, ....
  • The part under <xsd:annotation>/<xsd:appinfo> specifies the behavior of the content. The auto-generated schema has some of the possible subnodes. In particular:
    • <mappings>: Mappings allow to map the value of elements in the content to properties or attributes of the resource. Moreover, some special mappings are available.
    • <defaults>: Elements can be filled with default values when you create a new content.
    • <layouts>: For each element a default widget is used depending on the elements type. You can alter that widget (or the widget's configuration) by using <layout> nodes.
    • <searchsettings>: The node specifies the behavior of the content wrt. search. The containerpageOnly attribute handles, if the content should be findalbe itself, or should only be index with the container pages it is placed on. Via <searchsetting> sub-nodes, you can specify the search behavior for each element separately.

For now, that's enough information on the schema. If you want to read more about it:

The formatter

The formatter is the JSP that renders a content as HTML. The "Add resource type" wizard created already a suitable formatter for the demo type. It is named demo-content-formatter.jsp and placed under /system/modules/my.module/formatters/. The formatters/ directory below the module's main folder is (by convention) the place where formatters should reside. Using the type name in the formatters name is also a good practice.

Here's the generated formatter:

<%@page buffer="none" session="false" trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="cms" uri="http://www.opencms.org/taglib/cms"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<cms:formatter var="content">
  <div class="margin-bottom-30">
    <div class="headline">
      <h3 ${content.rdfa.Title}>${content.value.Title}</h3>
    </div>
    <div class="row">
      <c:if test="${content.value.Image.exists}">
        <div class="col-md-4 col-sm-2 hidden-xs">
          <div class="thumbnail-kenburn">
            <div class="overflow-hidden">
              <cms:img src="${content.value.Image}" scaleColor="transparent"
                width="400" scaleType="0" noDim="true" cssclass="img-responsive" />
            </div>
          </div>
        </div>
      </c:if>
      <div class="${content.value.Image.exists ? 'col-md-8 col-sm-10 col-xs-12' : 'col-xs-12'}">
        <div ${content.rdfa.Text}>${content.value.Text}</div>
        <c:if test="${content.value.Link.exists}">
          <p>
            <a class="btn-u btn-u-small"
              href="<cms:link>${content.value.Link}</cms:link>">${paragraph.value.Link}</a>
          </p>
        </c:if>
      </div>
    </div>
  </div>
</cms:formatter>

There's not so much to say about the formatter. Just some general hints:

  • Do not forget to add the taglibs
  • You get access to the content via the content object that is exposed by the <cms:formatter> tag
  • Always surround all your HTML output with a <div> or an other block element. Otherwise your content will not render correctly in edit mode.

The formatter gives an impression on how content is accessed. For more details, see

The formatter configuration

The formatter configuration is an XML file that brings schema and formatter together. Moreover, it defines when a formatter can be used. The "Add resource type" wizard added the formatter configuration demo-content-formatter-config.xml under the folder /system/modules/my.template/formatters/. It's best practice to place the formatter configuration in the same folder as the formatter and name it similarly.

The formatter configuration has a whole variety of settings. Here's the configuration created by default:

Fig. [default configuration]: The formatter configuration as added by the "Add resource type" wizard

The setting, we are interested in most for the moment is what is named "Container width" in the sample configuration. Setting the width to "-1" will cause the formatter to fit in all containers. We want to restrict the matching containers, i.e., the ones the formatter is applicable in, to containers of type "center". Therefor, cut the "Container width" editor field from the configuration. An optional "Match" field will appear, where you now choose the "Container types" alternative to add a match. Then you enter the container type "center", as shown in the figure below.

Fig. [match by container type]: Configure the formatter to fit only in containers of type "center"

Of course, the other settings are also important, but now you are at the point where you can try to place a content of your newly created type in your template. Do so.

Further information

We talked about the "Add resource type" wizard, the schema, the formatter and it's configuration and linked to topics diving deeper in each of the three subjects. But there's more about content:

You can improve this page

Please contribute your suggestions or comments regarding this topic on our wiki. For support questions, please use the OpenCms mailing list or go for professional support.