Developing and rendering custom content blocks

This page describes how to define and render custom content blocks that can be grouped to form content compositions in implementations of the Content editor.

Compatibility note

Magnolia 6 UI framework is implemented in version 2 of the Content Editor module. Custom content editor and block definitions created in the Magnolia 5 UI framework are not compatible with this version of the module and must be migrated.

If you wish to keep using the existing 5 UI block and custom content editor definitions, you must install version 1.3.9 of the Content Editor module and use them with this version.

Block types

The Content editor provides predefined block types that you can use in your custom content editor app:

  • text - Compared to TextFieldDefinition, the text block implements a special LightRichTextFieldDefinition class, which features basic text formatting functions:

    Light RichText Field block with control box

    templateId: content-editor:blocks/text
    icon: text-block
    label: Text
    block:
      implementationClass: info.magnolia.editor.field.LightRichTextFormView
      properties:
        text:
          class: info.magnolia.editor.field.LightRichTextFieldDefinition
          linkableApps:
            - pages-app
            - dam-chooser
  • image - Configured using the ordinary 6 UI damLinkField and textField field types:

    templateId: content-editor:blocks/image
    icon: file-image
    label: Image
    block:
      properties:
        image:
          $type: damLinkField
          label: Image
          placeholder: Add image...
          buttonSelectNewLabel: Select new...
        imageAltText:
          label: Alt text
          $type: textField
          placeholder: Add alt text...
        imageCaption:
          label: Caption
          placeholder: Add caption...
          $type: textField
        imageCredit:
          label: Credits
          placeholder: Add credits...
          $type: textField
  • externalLink - Utilizing the PeekFieldDefinition class from the Magnolia Link Unfurl Module, a submodule in the Content Editor module.

    templateId: link-unfurl:components/externalLink
    icon: embed
    label: Embed content
    block:
      properties:
        url:
          class: info.magnolia.unfurl.ui.PeekFieldDefinition
          label: Embedded content
          validators:
            url:
              class: info.magnolia.unfurl.ui.UrlValidatorDefinition
              errorMessage: link-unfurl.components.externalLink.tabUrl.url.validation.errorMessage
  • video - A combination of the following 6 UI field types: checkBoxField, comboBoxField, damLinkField, expandingTextField, radioButtonGroupField, switchableField and textField.

Demo block types

The Magnolia Demo decorates the default Stories app and provides two additional block types you can use:

  • date

  • tour

These block types implement the 6 UI dateField and linkField, respectively. To see these blocks, you must have the Magnolia demo modules installed.

Defining a custom block

You can quickly create your own custom block using Magnolia CLI. The Magnolia CLI create-block command. The command creates a block based on the info.magnolia.block.BlockDefinition class and includes many commonly used fields as a starting point: text, page link, DAM image, multivalue and select.

To define a custom block, use a YAML definition file and apply the BlockDefinition class of the Content editor module.

  1. Create a YAML file in the blocks folder of your module and add the following required definition elements:

    1. The info.magnolia.block.BlockDefinition class.

    2. The templateId of your block.

    3. A block node, with a list of fields the content block consists of. Use the properties in the same way as the properties for the CompositeFieldDefinition.

      class: info.magnolia.block.BlockDefinition
      templateId: <module-name>:<the-path-to-the-block-relative-to-the-module>
      icon: <icon-name>
      label: <i18n-label>
      block:
        itemProvider:
          $type: jcrBlockGetIndexedChildNode
        properties:
          field1:
            <field1-property1>
            <field1-property2>
          field2:
            <field2-property1>
            <field2-property2>
            etc.
  2. Provide a template definition file and a template script for your block in the templates/blocks subfolder of your module.

  3. Optionally, in the i18n folder of your module, provide a file with i18n keys for labels and descriptions of the block’s fields.

Rendering blocks in a FreeMarker script

This section explains how to render block content in a page or a component template.

The cms:block directive

The Content editor module provides cms:block, a Magnolia FreeMarker directive for fetching and rendering block elements.

The directive expects a node of the type mgnl:block as argument, identifies the template definition of the block and calls the associated template script.

[#assign blocks = cmsfn.children(articleContent, "mgnl:block") /]
  [#list blocks as block]
    [@cms.block content=block /]
  [/#list]

Examples of block rendering

The examples show how to render blocks within a template script of a page or component template. Using the Magnolia directive cms.block, the template script of the block is executed during the rendering of the page or component.

  1. Get story content:

    [#assign articleContent = cmsfn.contentById(content.article, "") /]

  2. Get the blocks for that story:
    [#assign blocks = cmsfn.children(articleContent, "mgnl:block") /]

  3. Retrieve all blocks for a piece of content:

    [#if articleContent?hasContent]
      [#assign blocks = cmsfn.children(articleContent, "mgnl:block") /]
      [#list blocks as block]
        [@cms.block content=block /]
      [/#list]
    [/#if]

    Line 4: The Magnolia directive cms.block ensures that the template script associated to the passed block is called to render the block content.

  4. Retrieve two blocks, for instance to display an excerpt of a story in a list:

    [#if articleContent?hasContent]
      [#assign blocks = cmsfn.children(articleContent, "mgnl:block") /]
      [#list blocks as block]
        [#if block?index == 2]
          [#break]
        [/#if]
        [@cms.block content=block /]
      [/#list]
    [/#if]

    Line 7: The Magnolia directive cms.block calls the template script associated to the passed block content.

Feedback