The main idea behind content templating is to have a means to define new content by re-using already existing content. In this way, the content manager does not have to deal with complex content structures.
Content templates are content structures which
The former is embodied by configuration parameter inheritance and overloading, the latter by the placeholder mechanism. A concept to enable both of them is template inheritance.
Term | Description |
---|---|
content template | collective name for page templates and component templates |
page template | blueprint for a page variant, can be used to instantiate a page variant or create derived templates |
component template | blueprint for a component variant, can be used to instantiate a component or create derived templates |
pagelet | a page variant or a component |
pagelet definition | a development time blueprint that can be instantiated as a pagelet at runtime |
content structure | Nesting components into slots of other components, which sit in slots of components and so on and so forth, leads to complex tree-structures. In the context of the CMS the entire composition of a web page is called content structure. |
Basically, content templates are plain pagelets. Before the introduction of content templating, there were only two types of pagelets: page variants and components. With content templating, two additional types have been introduced: page templates and component templates.
Instead of choosing a pagelet definition and building a pagelet from scratch, a content editor can now choose a content template and derive a component or page variant from it. This variant then uses the already existing content structure made up by the template. The page variant or component inherits the type implicitly from the corresponding template.
Imagine one builds up a web shop from scratch. There will be requirements for different web page types, e.g.:
Well, a lot of different web page types. One may create them all from scratch. Set up all the pages (storefront entry points for page variants). Instantiate a page variant for each required web page type and compose the web page types by nesting components into slots. Give it a try and you will see; It's a huge pile of work!
Or you can use content templating! Usually all web pages of a shop have the same header and footer. So instead creating all web pages from scratch, one might create one page template with 3 slots for header, main content and footer. While header and footer slot are already filled, the main content slot remains empty. From this page template further page templates can be derived and the main content slot can be filled with a component holding slots for a breadcrumb component and/or a left navigation component, marketing slots etc. And it does not stop there, one can derive the next page templates from the before one. So the templates become more and more specialized. And yes, this works for component templates as well. This way one does not build up the storefront stone by stone, but evolves the entire CMS into more and more specialized niches.
The interface com.intershop.component.pmc.capi.pagelet.Pagelet
has been augmented with a flag template
to designate pagelet instances as templates. Similar to page variants and components, the page
flag differentiates between page templates and component templates. The parent relation constitutes the actual template inheritance. Only pagelets with template
set to true, i.e., content templates, may assume the parent role in this relation.
The following object diagram summarizes what has been said so far in a scenario with
In the same way that page variants or components inherit from content templates, it is possible to have a component template inheriting from another component template. This way, one can create entire content template inheritance chains with each link providing more content to its ancestor.
A configuration parameter represents a leaf in the content composition tree. The meaning of a configuration parameter definition depends on how you use it in other Intershop development artifacts (like ISML templates & pipelines). It can either represent the actual content in the CMS, such as text, images, links and so on, or determine the behavior embodied by a pipeline.
Configuration parameters are one type of elements that are re-used throughout template inheritance trees. This means, content templates, page variants or components can re-use the configuration parameter values of the parent template. A configuration parameter of a pagelet with a parent template may be in three different modes:
The usage of configuration parameter inheritance is pretty obvious. But why overloading? Imagine you have set up the entire content structure in the master repository and you share (for more detailed information refer to Concept - CMS - Content Sharing) the content into different channels, because the overall structure of a web shop page is for the most part the same even in different contexts. These channels might differ in locale or business model or both. So instead of using the one fits all approach, you may use overloading. While re-using the content structure in large part you can overload configuration parameters to fit in other components to tailor each storefront exactly to your needs.
Configuration parameter inheritance and overloading are locale-sensitive, i.e., localized configuration parameters are inherited and may be overridden per locale. Multiple configuration parameter values can be inherited or overridden only as a whole.
Configuration parameter inheritance and overloading does not affect the API of com.intershop.component.pmc.capi.pagelet.ConfigurationParameter
, com.intershop.component.pmc.capi.pagelet.ConfigurationParameterCtnr
and com.intershop.component.pmc.capi.pagelet.Pagelet
. For example, ConfigurationParameter.getValue()
and ConfigurationParameter.getValue(locale:LocaleInformation)
will behave as always. It becomes active only during pagelet rendering and is taken into account when content templates, page variants and components are edited in the back office.
The object diagram below shows a root template t
, i.e., a template without a parent, another template t'
inheriting from t
and a component p
inheriting from t'
. The configuration parameters of templates, components or page variants without a parent are generally considered as being in overloading mode, hence the configuration parameters a
, b
and c
of t
are marked accordingly. t'
overloads c
, and p
hides the value of b
, so the effective configuration parameter values are a=a
, b=null
and c=d
when p
is rendered in the storefront.
Placeholders are the primary means to extend already existing content structures in the shape of content templates. As such, placeholders provide the individual context for extension when a component, a page variant or other content templates inherit from a content template. The placeholder belongs to the inheriting pagelet/template, but is wired to the content template it wants to extend and that its owner inherits from.
The extensions allowed to be plugged into a placeholder are pagelets. This leaves only slots as the only target placeholders may eventually be connected to. When a pagelet based on a content template is to be rendered, the pagelet itself and all its ancestors along the inheritance chain are merged into one final content structure which then may be viewed as one simple pagelet with slots and other pagelets bound to the slots.
The picture below shows a pagelet together with its template from two perspectives:
When the pagelet above is about to be rendered in the storefront, the slots from its parent template will be treated as if they were owned by the pagelet itself. However, the result set of pagelets returned by Body Slot
will differ from that which would be returned if the template were to be rendered. The result set will contain all pagelets assigned to the slot itself and the pagelets assigned to the placeholder which is linked to the slot.
To have a slot within a content template extendable by inheritors, it needs to be made part of the outgoing interface of the template. This is done by creating so-called placeholder definitions. A placeholder definition of a content template is linked to a slot within the template and declares it as subject to extension. The set of all placeholder definitions of a content template is regarded as its outgoing interface. If a pagelet is derived from a template, it will be augmented with one placeholder per placeholder definition of its parent template. The placeholder is linked with the placeholder which in turn points to a slot.
What happens when a template or pagelet inherits from another template but the parent is not a root template?
The parent template cannot have any slots since it is based on a template again, and slots may only exist in root templates. The solution is that, as with slots, a template may declare its placeholders as extendable too. It must then provide a placeholder definition which points to one of its placeholders instead of a slot. Inheritors then have placeholders according to the outgoing interface.
Template inheritance is not the only way placeholders are created. Another possibility is template composition. Template composition means that a component template with at least one placeholder definition linked to its inner content structure, i.e., one of its slots or placeholders, is attached to a slot or placeholder of another content template. As with template inheritance, a placeholder will be created automatically for each placeholder definition. The following diagram outlines template composition using the example of a page template and a component template, both having one slot:
composition
.When page variant is rendered by using its render template, at first its slot is processed. Only a component template is assigned to that slot, so the next step is to render the component template. Again, only one slot is found that needs to be rendered. As this slot is the target of a placeholder definition, additional steps have to be carried out:
This section gives an overview of all Java artifacts involved in the placeholder concept. The diagram below shows a simplified version of the relevant CAPI interfaces and the relations among them.
The API of Pagelet
has been extended to cover the parent relation and provide accessor methods to retrieve all child pagelets/templates of a pagelet instance as well as all placeholder instances and placeholder definition instances.
PlaceholderDefinition
is the public interface of placeholder definitions. It refers to SlotDefinition
so that, as with slot instances, all placeholders pointing to a placeholder definition get informed about what types of components or component templates may be attached to them. Each placeholder inherits its model type from the slot it is eventually connected to. A placeholder definition may point to either a slot or a placeholder, but never to both of them. This is represented by the mutually exclusive relations targetSlot
and targetPlaceholder
.
An instance of Placeholder
is first and foremost an instance of ContentEntryPoint
, i.e., it may have several pagelets assigned to it whereas the assignments may be prioritized and time-restricted. A placeholder inherits its content type from the placeholder definition that the placeholder bases on. The attribute hideTargetContent
decides whether the content from above the placeholder inheritance chain is to be shown at rendering time or not. This content comprises all placeholders along the chain of placeholders, placeholder definitions, and the slot at the top. placeTargetContentOnTop
steers where the pagelets assigned to a placeholder are placed at rendering time, before or after the pagelets assigned to the placeholders and slot further up the inheritance chain.