OpenCms Documentation

Adding a content type

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 Resource types app and click "Add new resource type" in the toolbar ().

A dialog appears where you can select the module your type should be defined in. Choose the "my.template" module and click "OK". To get to another dialog where you can enter details for your new type. Fig. [type definition] shows it with the form already filled suitable for the type we want to add.

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 first three items are the most relevant ones:

  • 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. We recommend to use at least five digits and specify a range for your ids upfront.
  • Name is the programatic name of the type. It must be unique.
  • XPath element-name is the name of the content's main XML node. Since OpenCms 11 it is not ultimately necessary to make it unique, but it is preferrable to not break, e.g., the traditional way to localize the editor.You have to use field settings to not get into trouble with dublicate keys in the workplace message bundle when you have dublicated XPath element names.

Then you have two localizations:

  • Display name is the localized (in your workplace locale) name of the content type that is used, e.g., in the "Add wizard" used to drag&drop content on a container page.
  • Description is the localized (in your workplace locale) description of the content type that is used, e.g., in the "Add wizard" used to drag&drop content on a container page

The remaining options are typically already correctly pre-filled. If you want get the details, see here.

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="DemoContentData" type="OpenCmsDemoContentData"/>

	<xsd:complexType name="OpenCmsDemoContentData">
		<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="LinkURI" type="OpenCmsVarLink" />
		</xsd:sequence>
		<xsd:attribute name="language" type="OpenCmsLocale" use="required"/>
	</xsd:complexType>

	<xsd:annotation>
		<xsd:appinfo>
		    <resourcebundles>
                <propertybundle name="my.template.messages" />
            </resourcebundles>
			<FieldSettings>
                <Setting>
                    <PropertyName>Title</PropertyName>
                    <Widget>string</Widget>
                    <Default>%(key.type.demo-content.title)</Default>
                </Setting>
                <Setting>
                    <PropertyName>Text</PropertyName>
                    <Widget>html</Widget>
                    <WidgetConfig>height:400px,link,anchor,source,downloadgallery,formatselect</WidgetConfig>
                </Setting>
                <Setting>
                    <PropertyName>Image</PropertyName>
                    <Widget>imagegallery</Widget>
                    <WidgetConfig>{useformat:true}</WidgetConfig>
                    <Search>false</Search>
                </Setting>
                <Setting>
                    <PropertyName>LinkURI</PropertyName>
                    <Widget>file</Widget>
                    <Search>false</Search>
                    <Display>singleline</Display>
                </Setting>
            </FieldSettings>
		</xsd:appinfo>
	</xsd:annotation>

</xsd:schema>
  • In the schema, you find the "XPath element-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 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 built-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:
    • <resourcebundles>: Are bundles you use to localize messages. Here we localize the default value for the title.
    • <FieldSettings>: The field settings allow to specify the behavior of the single editor field that is specified via the sub-node "PropertyName". Here you specify the widget to use and many other things. Read more about the field settings here.
    • Many more options are present, see the topic on defining a contents behavior for more information.

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.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" val="value">
  <div>
    <div style="width:200px;float:right">
      <img style="width:100%" src="${value.Image.toImage}"/>
    </div>
    <div>
      <h2>${value.Title}</h2>
      <p>${value.Text}</p>
    </div>
    <div>
      <a href="<cms:link>${value.LinkURI}</cms:link>">Link</a>
    </div>
    <div style="clear:right;"></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.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 "Matching containers" field will appear, where you now choose the "Container types" alternative. 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.