Inline blocks in ContentArea
WARNING: This post has been updated after releasing version CMS UI 12.24.0
Inline blocks are not enabled by default. Please scroll down to "How to enable this feature"
Introduction
EPiServer's most powerful property type ContentArea supports a number of use cases. Editors can store all kinds of content types there: pages, blocks, media, video, etc.
ContentArea does not just store references to those content items but additionally it stores their names, types and personalization information.
During the rendering phase property renderer loops through ContentAreaItems, applies personalization rules based on current identity and then tries to find a view for each item.
It is indeed quite flexible because it lets the editors to create any kinds of layouts using just a single property on a page or combining multiple ContentArea properties.
Editor can either select an existing IContent instance or decide to Create a new Block.
Blocks created via ContentArea were placed in `For this page/block` folders and were accessible through the Assets pane:
Because of the fact that each block is a separate IContent it is not possible to easily preview the changes, review by reviewers and finally to publish all items as once.
There were several attempts to solving this issue, one of them being the Block Enhancements Labs package:
https://nuget.optimizely.com/package/?id=EPiServer.Labs.BlockEnhancements
https://world.optimizely.com/blogs/bartosz-sekula/dates/2021/9/block-enhancements-update/
It is a bit cumbersome that after creating a page with several blocks inside editor has to remember to always go through each page dependency to make sure it is in correct state. That each dependent block also has to be sent for review or added a project item even though it is only used once on that single page.
Inline blocks inside ContentArea
In EPiServer.CMS 12.22.3 we are releasing a big improvement to ContentArea. It is now possible to store BlockData inside ContentAreaItem as plain object.
There are no more tricks required to synchronize a parent page with dependencies to publish them all at once. Editor just need to deal with a single piece of content (page, multi-channel content, ..) and is now allowed to inline blockdata and make them part of that parent content.
Nothing changes in regards to property definition in code, ContentArea is still defined the same way:
public virtual ContentArea ContentItems { get; set; }
It is still possible to limit available content types by using AllowedTypes attribute
[AllowedTypes(typeof(TeaserBlock), typeof(EditorialBlock), typeof(ContactBlock)]
public virtual ContentArea ContentItems { get; set; }
The UI also stays the same:
However, after clicking Create new block we are no longer going to create a new instance of block which would be visible in For this page folder.
Instead we would create a property bag and inline that property bag into ContentAreaItem instance and store it inside the parent content.
After choosing the type and filling in the details:
We can immediately see the result:
After changing that ContentAreaItem we no longer need to publish the block but instead will get a new version of the parent page.
That has several implications:
- Editor no longer needs to switch context to edit those inline blocks.
- Inline blocks inside ContentArea do not have publishing lifecycle on their own, they are part of the page.
- Those items also do not have approval workflow on their own. It is the parent content that has to be reviewed and approved.
- Those items will not be included in projects, only their parent content as a whole
Let's say we publish the page now but after a while editor decides to change the test on our ButtonBlock
In order to do that we can just run the Edit command or double click the content area item.
Change the properties:
And after saving the dialog we can immediately see the changes on the page:
As you can see a new page version was created. We can easily preview how the page will look like after the changes. We can also use the compare mode:
All properties mode
Inline blocks can be named as any other blocks however for some simple block types it may be that there is already a textual property which can be used instead (for example if you have a Heading property in your ContactBlock or TeaserBlock.
In order to do it you can use the new InlineBlockNamePropertiesOptions which can be set via appsettings.json in the following way:
"InlineBlockNameProperties": {
"Contact": "Heading",
"Teaser": "Heading"
}
It is a simple Dictionary<string, string> of BlockTypeName / PropertyName
After that for ContactBlock and TeaserBlock instances Name will no longer be displayed in Create new block dialog and also the value of Heading property will be used in Content Area editor.
View Mode Rendering
No special attributes or techniques are needed in order to render inline blocks. If you use our HtmlHelpers or TagHelpers they will render exactly the same as regular blocks.
If you have a display template defined for a specific block type then the runtime will pick it up and use.
Migration
If you have existing local or shared blocks which you would like to inline into ContentArea properties then you have two options:
- We added a utility command which converts ContentAreaItem to an inline version. The original IContent is not removed, you will need to clean up manually
- There is an admin mode plugin available in Block Enhancements Labs 1.2.2
The migration can be done in 3 steps:
- Convert shared blocks used only once to their respective `For this page` folder
- Make blocks from `For this page` inlined into ContentArea properties
- Remove empty folders from assets pane.
All the steps can be either run at once or separately. It's up to you.
It is also possible to run the migration the other way around. If you have inline blocks in the system and would like to turn them off and switch back to shared blocks then please use `Convert inline to shared` link or scheduled job. You can use `Dry run` to list all conten items containing inline blocks.
Changes to ContentArea `Create a new block` command
Prior to CMS 12.22.3 clicking on `Create a new block` link button:
Would create the new block inside `For this page` folder. After upgrading to CMS 12.22.3 it creates an inline blocks and embeds it inside ContentArea property.
Changes to shared content
Each shared item (essentially every content instance which has an ID and can be referenced by something else) will be clearly marked with `SHARED` label. Both in Forms view and in On-Page Edit.
Additionally when editing a shared block through `Quick Edit` we now display a warning if that item being edited is used more than once:
ContentAreaItem property
Another enhancement is that we added the possibility to define a single ContentAreaItem property. It looks as a regular ContentReference property but offers much more functionality.
Essentially it works as a ContentArea with a single item limitation applied.
public virtual ContentAreaItem MyContentItem { get; set; }
It is also possible to limit available content types by using AllowedTypes attribute
[AllowedTypes(typeof(TeaserBlock), typeof(EditorialBlock), typeof(ContactBlock)]
public virtual ContentAreaItem MyContentItem { get; set; }
The UI resembles a regular ContentReference:
However apart from storing just a reference it also allowes you to create and store an inline block inside:
This property will also work fine in OPE and will support display options, the same way as in ContentArea (we reuse ContentAreaRenderer).
Q&A
Q: What happens after upgrading to CMS 12.22.3? Is there any automatic content migration?
A: No. This is not a breaking release. Nothing will happen to your content. However, please be aware that inline blocks DO NOT HAVE content links on their own. They are just simple property bags.
Q: How to start using this new feature?
A: Please scroll down to `How to enable this feature`
Q: Is this also supported through the API
A: Yes. All the things you can do from Edit Mode are supported through our Management API
Q: Does ContentArea still support old functionality?
A: Yes, ContentArea still supports storing ContentReference, it still supports personalization, display options etc.
EPiServer.Labs.BlockEnhancements
That package is going away. All of its functionalities are now part of the main package. The last remaining feature is the migration tool described above.
There will be no further releases.
How to enable this feature
You can either use UIOptions.
services.Configure<UIOptions>(uiOptions =>
{
uiOptions.InlineBlocksInContentAreaEnabled = true;
});
or via appsettings.json
"EPiServer": {
"CmsUI": {
"UI": {
"InlineBlocksInContentAreaEnabled": true
}
}
}
Documentation for this feature can be found here https://docs.developers.optimizely.com/content-management-system/docs/inline-edit-settings
Comments