loading table of contents...

Frontend Developer Manual / Version 2310

Table Of Contents

5.16 Rendering Container Layouts

There are various ways container layouts can be rendered. This section will describe the approach CoreMedia is using in the example banner bricks and themes. For this, you should have understood the basic concepts of view dispatching (see the Content Application Developer Manual for more details).


In CoreMedia's bricks and themes a container layout is a visual component that consists of a header and a grid. It is based on the model com.coremedia.blueprint.common.layout.Container. The header of a container layout can contain additional information like a teaserTitle or teaserText if the information is provided. The grid will arrange the items found in the model specifically based on the type of the container layout.

Typical beans implementing the interface com.coremedia.blueprint.common.layout.Container are com.coremedia.blueprint.common.layout.PageGridPlacement and com.coremedia.blueprint.common.contentbeans.CMCollection. Their viewtype property (also referred to as Layout Variant in Studio) determines which type of container layout will be used.

Involved Models and Views

The following class diagram gives an overview about the different models and views that are involved in the rendering of container layouts and their relation to each other. Every method in the corresponding model stands for a Freemarker template, for example, the asPortraitBanner method of the model CMTeasable stands for CMTeasable.asPortraitBanner.ftl.

Class diagram of Models involved in Container Rendering

Figure 5.3.  Class diagram of Models involved in Container Rendering



The package names of the corresponding models are omitted.

Although the interface Object does not exist in Java, CoreMedia decided to keep the diagram simple by introducing it instead of adding actual implementation classes which can inherit from java.lang.Object. The goal is to also visualize the fallback view.

Of course much more views do exist for the corresponding models in the Frontend Workspace. Here, only the views are shown that are covered by this section.


Renders the given bean as a portrait banner (see Section 6.4.14, “Example Portrait Banner”).


This view is used to render the outer HTML structure of the portrait container layout. It will utilize the partial views _portraitBannerContainerHeader and _portraitBannerGridItem.


Renders the header part of the portrait banner container based on the given bean. While a PageGridPlacement will not add any information for CMCollection the content of the teaserTitle is rendered.


Renders the given bean by including the view asPortraitBanner and wrapping it into an HTML structure that is needed to render it as a grid item.

The portrait banner grid does not support nested container layouts so whenever a com.coremedia.blueprint.common.layout.Container is encountered its items will be rendered as if they are part of the outer portrait banner container.


This view is just used for dispatching the viewtype with the id portrait to the view asPortraitContainer.


This view is included if the viewtype property is not set or there is no view asContainer[id] handling the selected viewtype id. So it acts as the default and also as a fallback.

As the definition of default might differ from one theme to another it is not contained in any banner brick but is located in CoreMedia's themes.

Using Container Layouts for the PageGrid

Let's see the container layouts in action. You will see the flexibility of the container layouts by using them in a PageGrid. You will be able to explicitly set the viewtype for a PageGridPlacement to render all its items in the portrait banner container layout or you can keep the default viewtype for the PageGridPlacement and add CMCollections which set the viewtype.

To have more variety, the landscape banner brick (see Section 6.4.10, “Example Landscape Banner”) will also be used.



The example will not cover how to render beans not implementing the com.coremedia.blueprint.common.layout.Container interface inside a PageGridPlacement or CMCollection if no layout is picked. You can see one possible solution in CoreMedia's example themes (shared-example-theme, for instance).

The approach will render non-container items as left-right banners that do not require a surrounding container layout to work. This also allows mixing container and non-container items in a single PageGridPlacement or CMCollection.


If you want to replay the example you need to do the following things in the Frontend Workspace:

  1. Create a new theme and add the bricks @coremedia/brick-page, @coremedia-examples/brick-portrait-banner and @coremedia-examples/brick-landscape-banner (see Section 5.1, “Creating a New Theme”).

  2. Create a template src/templates/com.coremedia.blueprint.common.layout/Container.asContainer.ftl with the following content:

    <#-- @ftlvariable name="self" type="com.coremedia.blueprint.common.layout.Container" -->
    <#list self.items![] as item>
      <@cm.include self=item view="asContainer" />

    Example 5.6. Container.asContainer.ftl

  3. Create a template src/templates/com.coremedia.blueprint.common.layout/PageGridPlacement.ftl with the following content:

    <#-- @ftlvariable name="self" type="com.coremedia.blueprint.common.layout.PageGridPlacement" -->
    <div id="cm-placement-${!""}" class="cm-placement"<@preview.metadata data=[bp.getPlacementPropertyName(self), bp.getPlacementHighlightingMetaData(self)!""]/>>
      <@cm.include self=self view="asContainer" />

    Example 5.7. PageGridPlacement.ftl

  4. (optional) To make images work you need to add responsive-image settings src/settings/Responsive Images.settings.json which could look like this to enable the crops used by the banner types:

      "enableRetinaImages": false,
      "responsiveImageSettings": {
        "portrait_ratio1x1": {
          "widthRatio": 1,
          "heightRatio": 1,
          "0": {
            "width": 300,
            "height": 300
        "portrait_ratio2x3": {
          "widthRatio": 2,
          "heightRatio": 3,
          "0": {
            "width": 300,
            "height": 450
        "landscape_ratio16x9": {
          "widthRatio": 16,
          "heightRatio": 9,
          "0": {
            "width": 480,
            "height": 270

    Example 5.8. Responsive Images.settings.json

  5. (optional) To adjust the MIME type / file extension of links to image variants add a property linkMimeTypeMapping for example next to responsiveImageSettings in the example above. The property configures a mapping of original image MIME type to the MIME type that should be used when building links to the variants. The respective JSON to map for example image/jpeg to image/png could look like this:

      "linkMimeTypeMapping": {
        "image/jpeg": "image/png"
      "responsiveImageSettings": {...}

    For details see ????.

  6. (optional) To have property responsive styling edit src/sass/_variables.scss:

    // Own variables first
    $cm-screen-sm-min: 800px;
    $cm-screen-lg-min: 1200px;
    $breakpoints: (
      "xs": "screen and (max-width: #{$cm-screen-sm-min - 1})",
      "xs-and-up": "screen and (min-width: 0)",
      "sm": "screen and (min-width: #{$cm-screen-sm-min}) and (max-width: #{$cm-screen-lg-min - 1})",
      "sm-and-up": "screen and (min-width: #{$cm-screen-sm-min})",
      "lg": "screen and (min-width: #{$cm-screen-lg-min})",
      "lg-and-up": "screen and (min-width: #{$cm-screen-lg-min})",
      "pt": "print"
    ) !default;
    // Dependency variables
    @import "?smart-import-variables";

    Example 5.9. _variables.scss

  7. Deploy the theme (see Section 5.6, “Importing Themes into the Repository”).

On the content side make sure that you prepare the following content in the CoreMedia Studio:

  1. Create a new page and use the newly uploaded theme

  2. Configure a page grid with 2 placements, e.g. placement1 and placement2 (see Section, “Editing a Page Grid” in Studio User Manual)

  3. Create two layout Variants for CMChannel below Options/Viewtypes and make sure to set the Layout field to portrait and landscape respectively (see Section, “Adding a Layout Variant” in Studio User Manual)

  4. Assign the layout variant portrait to placement1 and add some articles.

  5. Assign no layout variant (Default) to placement2 and add two collections: collection1 and collection2.

  6. Assign the layout variant landscape to collection1 and add some articles

  7. Assign the layout variant portrait to collection2 and add some articles


You should now see three container layouts: The first layout represents placement1. It has no header and all items are displayed as portrait teasers. The second and third layout represent the content of placement2. If the teaser title of collection1 and collection2 is set it will be rendered in the header. The items of the corresponding collections are rendered as defined by their layout variant (landscape and portrait).

Container layouts for PageGrid

Figure 5.4.  Container layouts for PageGrid

The following sequence diagrams demonstrates how each view is involved in the rendering of the page grid:

Sequence diagram showing view dispatching in the page grid

Figure 5.5.  Sequence diagram showing view dispatching in the page grid



In order to keep the diagram readable the sequence stops at asPortraitBannerContainer. This will be covered by the next section.

Nested Collections

CoreMedia's container layouts can also handle nested collections. Let's assume instead of having multiple articles in placement1 (see previous section) you have a single article article1 and a collection nestedCollection. The later also contains an article nestedArticle.

The following sequence diagram shows how the rendering works in this case. The starting point is where the view asPortraitBannerContainer is included:

Sequence diagram showing view dispatching for nested items

Figure 5.6.  Sequence diagram showing view dispatching for nested items

As you can see the inclusion of _portraitBannerGridItem in placement1 leads to another inclusion of _portraitBannerGridItem which also passes the metadata data of nestedCollection and its items property. This is important for the preview based editing as otherwise the hierarchical information about how the nestedArticle comes into the rendering (which is placement1 -> items -> nestedCollection -> items) is incomplete.

Search Results

Table Of Contents

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.