Content Editor module
Content management Bundled: DX Core
Edition | DX Core |
---|---|
License |
|
Issues |
|
Maven site |
|
Latest |
2.1.8 |
The Content Editor module provides a platform for handling well-defined blocks of content in Magnolia.
The core of the platform is the Magnolia Content Editor submodule, implemented as the stories-app
submodule, which allows editors to create and edit stories in the Author instance using the Stories app.
Compatibility note Custom content editor and block definitions created in the Magnolia 5 UI framework must be migrated. |
Module structure
artifactID | |
---|---|
|
Parent reactor. |
|
Provides a free-form content editor. |
|
Provides a custom widgetset for the Content Editor. |
|
Provides the Stories app, the default Magnolia editor implementation. The app is not bundled with preconfigured Magnolia webapps. |
|
Provides a basic API for the blocks (content sections). |
|
Provides the functionality to render the blocks. |
|
Provides utilities for unfurling external web links. Unfurling means fetching and displaying metadata for a given URL, for example, a preview image, a title and description. |
Installing
Demo modules decorate the |
If you want to build your own custom implementation, add this dependency to your webapp:
<dependency>
<groupId>info.magnolia.editor</groupId>
<artifactId>magnolia-content-editor</artifactId>
<version>2.1.8</version> (1)
</dependency>
1 | Should you need to specify the module version, do it using <version> . |
If you intend to build custom blocks, add this dependency to your webapp:
<dependency>
<groupId>info.magnolia.block</groupId>
<artifactId>magnolia-block-templating</artifactId>
<version>2.1.2</version> (1)
</dependency>
1 | Should you need to specify the module version, do it using <version> . |
Want to create your own custom content blocks?
To define a custom block, use a YAML definition file and apply the BlockDefinition
class of the Content editor module.
-
Create a YAML file in the
blocks
folder of your module and add the following required definition elements.class: info.magnolia.block.BlockDefinition (1) templateId: <module-name>:<the-path-to-the-block-relative-to-the-module> (2) icon: <icon-name> label: <i18n-label> block: (3) itemProvider: $type: jcrBlockGetIndexedChildNode properties: field1: <field1-property1> <field1-property2> field2: <field2-property1> <field2-property2> etc.
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 theCompositeFieldDefinition
. -
Provide a template definition file and a template script for your block in the
templates/blocks
subfolder of your module. -
Optionally, in the
i18n
folder of your module, provide a file withi18n
keys for labels and descriptions of the block’s fields.
See Developing and rendering custom content blocks for more details on custom blocks. |
Content editor modules in Magnolia webapps and bundles
In the 6.2 branch of Magnolia, preconfigured Magnolia DX Core bundles or webapps contain version 1.3.15 of the module, which is compatible with the 5 UI framework. If you wish to use module version 2.1 (or higher), which is 6-UI-native and supports content internationalization, you must remove the 1.3.15 module first. |
Content internationalization (i18n)
Internationalization (i18n) of content is supported since version 2.1
of the Content Editor module. Block definitions and data structures created in the older versions of the module must be migrated.
Compatibility of content and block definitions
Flat vs nested content structure
The data model has changed for internationalized stories. Whereas in versions 1.3.x
and 2.0.x
of the module, the mgnl:block
elements are stored in a flat node structure,
stories └── story1 ├── 0 └── 1
in the i18n-supported version (2.1
and higher), the nodes are locale-nested under intermediate nodes of type mgnl:contentNode
, named blocks_de
and blocks
in this example:
stories └── story1 └── blocks_de │ ├── 0_de │ └── 1_de └── blocks ├── 0 └── 1
This must be reflected in your MultiJcrBlockDefinition
, where you need to add and enable the i18n
property.
Instead of the CurrentItemProvider
, the CompatibleBlockProvider
is set as the default provider, which can resolve both flat and nested block nodes. You do not need to declare it in your block definition.
- Example definition
-
blocks: label: Blocks $type: multiJcrBlock i18n: true blocks: - text
This applies only to the 2.0.x block definitions. Block definitions created for version 1.3.x (5 UI) of the module are not compatible with the 2.1 version and must be fully migrated.
|
Migrating content
There are two ways you can migrate the non-i18n blocks to the i18n-compatible hierarchy: using a version handler or a Groovy script.
We strongly recommend you have the latest version of the Content Editor before migrating your content. In versions prior to 2.1.3, the |
Version handler
When upgrading the Stories app submodule to version 2.1
or higher, all block nodes in the stories
workspace will be moved to intermediate nodes, see the MigrateBlockToIntermediateParentTask
task.
Groovy script
You can run the migration task in the Groovy app, especially in case a block node is stored in another workspace.
- Example Groovy script
import info.magnolia.editor.setup.MigrateBlockToIntermediateParentTask
import info.magnolia.module.InstallContextImpl
import info.magnolia.module.ModuleRegistryImpl
import info.magnolia.objectfactory.Components
import javax.jcr.Session
Session session = MgnlContext.getJCRSession("stories");
task = new MigrateBlockToIntermediateParentTask("stories", "/", "blocks");
task.execute(Components.newInstance(InstallContextImpl.class));
session.save();
The parameters in the MigrateBlockToIntermediateParentTask
:
-
stories
- workspace name -
/
- path -
blocks
- name of the intermediate node, the name of themultiJcrBlock
field.