Opt-out from Inline Blocks support in ContentArea properties
WARNING: This post is no longer up to date because from CMS UI 12.23.3 inline blocks are no longer enabled by default.
They have to be turned on manually, more details here: https://world.optimizely.com/blogs/bartosz-sekula/dates/2023/5/inline-blocks-in-contentarea/
Or in the documentation https://docs.developers.optimizely.com/content-management-system/docs/inline-edit-settings
OLD BLOG POST BELOW:
In CMS 12.21.0 we added a way to create inline blocks inside each ContentArea property.
This feature is very powerful and has many advantaged as described in my previous blog post: https://world.optimizely.com/blogs/bartosz-sekula/dates/2023/5/inline-blocks-in-contentarea/
However, this also introduced issues for some clients, mostly non-MVC clients who rely on our API endpoints and always expected that each ContentAreaItem to have a non-null ContentLink.
For such cases in CMS UI 12.22.2 we added a way to opt-out from the ability to create inline blocks inside ContentArea.
This new setting is global and the default value is true
InlineBlocksInContentAreaEnabled is a new boolean property added to UIOptions class. You can set it directly in code or you can also use the appsettings approach as shown below:
"EPiServer": {
"CmsUI": {
"UI": {
"InlineBlocksInContentAreaEnabled": false
}
}
}
After turning that flag to false the link to create an inline block in each ContentArea property will no longer be available.
Of course it is still possible to use the Assets pane to create shared blocks within the folder structure or use the `For this page/block` folder as contextual storage.
Important note: It is no longer possible to create shared blocks from Content Area.
12.22.2 also introduces a way to configure the labels for inline blocks.
By default inline blocks labels are just their type names. It is fine if there are just a few but if the list of blocks is long it may be very problematic to find the block you need to edit (because in contrast to the On-Page-Edit here you don't see the view of the block). We added a way to instruct ContentArea to use a specific property from block type as a label.
In order to do it you can use the new InlineBlockNamePropertiesOptions which can be set via appsettings.json in the following way:
"EPiServer": {
"CmsUI": {
"InlineBlockNameProperties": {
"Contact": "Heading",
"Teaser": "Heading"
}
}
}
It is a simple Dictionary<string, string> of BlockTypeName / PropertyName
Of course both options classes can be set in c#:
services.Configure<UIOptions>(o => {
o.InlineBlocksInContentAreaEnabled = false;
});
services.Configure<InlineBlockNamePropertiesOptions>(options =>
{
options.Add("Teaser", "Heading");
});
More details available here: https://docs.developers.optimizely.com/content-management-system/docs/inline-edit-settings
This feels a little bit like more of a reaction to some of the comments from a few weeks ago, than something that has been thought through completely.
> Important note: It is no longer possible to create shared blocks from Content Area.
Does this mean we now can't click "Create a new block" in a content area??
If so, why? If not, could you please explain what it means :)
Hi, could someone please clarify where in appsettings.json "InlineBlockNameProperties" should be set? Is it at the root level, or under some other place like "Episerver", "Episerver:Cms", "Episerver:CmsUI", etc?
I tried a number of different places, with and without the suffix "Block" in the block type name, but I still see just the inline block type name in the UI, not the value of the specified property. Maybe I am doing something else wrong, but knowing for sure where the setting goes would make it easier to narrow down the problem.
Another question on this option: Must the property name specified refer to a regular stored block property, or could it be a getter with the "Ignore" attribute that computes a name for the block?
By the way, the documentation says that the "InlineBlocksInContentAreaEnabled" setting goes under "UIOptions" in appsettings.config, but the blog post says "Episerver:CmsUI:UI". Are they equivalent?
By the way, I agree with DOldfield that it is a problem that it is not possible to create blocks from a drop-down menu in content areas after opting out from inline blocks.
(What it means is what it says. After opting out, the combined button/dropdown turns into a plain button called “Select Content”. Blocks must be created by means of the Assets gadget and dragged into the content area or selected in the popover opened through the “Select Content” button.)
In a scenario where nested blocks are common (section blocks that contain a content area that contains several other blocks that are treated as a group when shown on the website), it is a rather tough requirement on editors to constantly keep track of which block they are in when creating a new block under “For this Block” in the structure.
Suppose a first nested block is created in the “For this Block” container of a section block. Then, when creating the next block in the section, the editor must remember to first go back to the section block, or else the next block will be a sub-block of the previous nested block and thus unavailable to the section block. This will cause a lot of frustration and support requests that would otherwise be unnecessary.
The old behavior, where “Create a new Block” in the dropdown automatically created a new block in the right “For this Page” or “For this Block” container was a lot more user-friendly and is now only available for inline blocks.
It is difficult to see a strong reason for why the opt-out for inline blocks would have to disable the “Create a new Block” function. It would be much better if the opt-out instead toggled the behavior of “Create a new Block” between creating a new inline block and creating a new shared block in the appropriate “For this …” container.
I have just updated the blog post and docs with more accurate json settings and c# snippet on how to opt-out and how to configure the properties.
About missing link `Create a new block` - that is true. After many user tests and content analysis it turned out that more than 90% of all the blocks being created are either placed in `For this page/block` or are shared blocks created in `For all sites/For this site` but used only once) and many complaints from our users that it is very hard to manage a page with multiple blocks (not even mentioning nested block scenarios) because each block has to be reviewed/published separately we have decided to move towards inline blocks in Content Area properties.
I understand it is problematic for you and I am really sorry for any inconvenience, however as of now it is not possible to support both inline blocks and the local blocks (For this page/block) from content area. You will need to use the Assets pane to create blocks and then d&d or select them from Content Area.
This is probably the most messed up set of updates that Optimizely has released recently for the CMS. It is causing us and our clients a number of issues due to the number of bugs and usability problems in the past 2 updates.
For one of our under-development projects, we had to revert back to May's update to avoid this mess. Judging by the direction Optimizely is taking on this feature, this new project codebase is at the risk of being "Legacy" already with an outdated Optimizely version (good bye future security and zero day updates) unless a big chunk of time and money is spent.
Other projects we have that are already in production are also in risk of missing out on Security features and Optimizely updates due to this behavior change. With the cost to update them to be compatible being very high.
My complaints about this update:
1- After "opting out" of the inline blocks "feature", we cannot directly create blocks for a content area using the "Select Content" dropdown. This means that content authors must take extra steps to:
a) find the "For this page/block" blocks folder.
b) Navigate through the block type selection dialog which could have a big number of blocks that can be created since we can't limit what blocks are available for which folder).
c) create the block.
d) find the block instance in the "For this page/block" folder which, depending on the size of the page, could have a big number of blocks already. 5) drag that block to the content area or select it from the pop up.
This is a nightmare for usability from a content author's point of view. 100x so if we are talking about nested blocks. There was clearly no thought put into this feature. Content migration/entry is now 10x slower than it needs to be.
2- The behavior change in the content area around inline blocks and not being able to get a valid ContentReference programmatically is causing us all sorts of bugs in existing sites. We have features that depend on having a ContentReference available when enumerating the items in a content area. These features are now either completely broken or not reliably functioning as expected. If we opt-out then we have #1 to worry about.
3- We just discovered a bug in which the CMS PropertyFor extension method is causing inline blocks to duplicate when the page is published. We are in the process of submitting a bug report ticket to Optimizely. I get that bugs slip through from time to time and that's fine.
4- The reason given for this change is how this new feature reduces the complaints users have about having to review and approve every block (and nested block) separately for every page... fair enough but honestly, I think the fix for this issue should've been made in the content workflow functionality of the CMS by having it automatically approve those blocks if the page containing them was approved. Fixing it there would mean no behavior change to any existing code and less headaches for everyone involved. Yes, there will be cases where the approval process is dealing with a block that exists in 2 separate pages and that is fine.. that's where the content author/reviewer will exercise their judgment and decide what to do about the content.
I like the idea of inline blocks and I this feature could've been introduced without breaking existing functionality/API behavior.I really hope this feature is removed and taken back to the drawing board.
With regards to labeling Inline Blocks. While it is great to see this feature implemented, the way it is implemented is lacking.
I don't think AppSettings.json should be concerned with content types and the way they are represented on the UI. We should be able to configure that through the use of C# and convention classes similar to Optimizely Search & Navigation. This way we have more flexibility in automating how the CMS selects a property as a label (for example: use reflection to find all blocks, for each block the property with a specific attribute, then give that property name to the CMS to be used as a label)
---
Another options is to introduce a new interface that can supply the CMS with a string value to be used as the label.
---
The current implementation using JSON in AppSettings.json is not the way to go. Any site with a lot of block types will now have to manage a big json array and keeping that in sync will be very annoying.
In summary, there are much better ways to implement this than the currently listed approach.
Thank you Raphael Yousuf for pointing out this: “b) Navigate through the block type selection dialog which could have a big number of blocks that can be created since we can't limit what blocks are available for which folder”
I previously did not think of that aspect, but it is acutally quite a serious user interface drawback.
As for “3- We just discovered a bug in which the CMS PropertyFor extension method is causing inline blocks to duplicate when the page is published”, it sounds like it might be at least distantly related to the bug https://world.optimizely.com/support/bug-list/bug/CMS-28932 that we reported to customer support about a month ago. (Not mentioned in the published bug report is the fact that if the last inline block in the nested content area is then deleted, any attempts to edit the page in the CMS interface will subsequently fail with a server-side exception.) Hopefully, that bug will be fixed soon.
The link above to the bug report does not work when clicked (automatically rewritten somehow) but it does work if the link text is copied/pasted.
I strongly agree with previous commenters that this opt-out is still breaking workflows for content editors and that I struggle to find a reason why it's impossible to restore old behavior or have them exist side-by-side. Having to create the blocks through the sidebar is in no imaginable way a UX improvement. I fully understand the rationale behind this functionality and think it's an overall improvement, but it requires changes in code, content modeling and editor workflows to apply and forcing it upon existing installations like this is causing lots of issues. Please reconsider giving the options to restore old behavior so our products and clients aren't stuck on older versions of the CMS.
Yes, we should not forget about the content modeling issues. Custom code that breaks due to inline block is in many cases easily fixed, but if the content model of a website that has a large base of existing content is not compatible with inline blocks, adapting can become really complicated.
The main content model problem is the fact that inline blocks cannot have language versions. If an existing model with a lot of existing content depends on some blocks being translatable, it can be quite difficult to migrate to a different model. But the loss of the name field is also a problem for block types that do not have a suitable substitute property. And sometimes the category field may also be important. (Maybe the ShowNameProperty and ShowCategoryProperty settings solve the latter problems, but someone claimed that the content of the name field is not saved for inline blocks.)
I did some more testing with InlineBlockNamePropertiesOptions (not sure what I did wrong previously that made me believe the statement in another comment that it could not be set in code) and noticed that for a block type with localized names, it is all the localized names that must be specified. For example, we have a project with a block type with the class name SectionBlock and a property called Heading that might be usable as a block name. The website has English and Swedish enabled. Since the block name has translations, it must be specified twice:
This can easily become cumbersome. Interestingly, the property name (which also has translations) should apparently be written as it is in the block type code.
This just seems to get more disappointing as the threads go on.
We won't be upgrading any customers for a while it seems.
I can confirm what somebody else wrote about “[InlineBlockEditSettings(ShowNameProperty = true)]” – the name property is shown in the inline block editing popover (as a required field), but its value is not saved.
So, what purpose does that setting fulfill? The documentation page only says that it makes the name field visible, not why one might want that to happen. As far as I notice, the only effect is that editors are forced to type something that is then immediately discarded when the popover is closed.
We have submitted a ticket with details about how inline blocks are duplicating themselves, while shared blocks are not affected. Our client is having issues publishing their content, since the Create a Block button now creates Inline Blocks by default, and these are broken. Now for them to publish content at all, they will now need to use the Assets pane to create Shared Blocks, which is utterly excruciating to create especially when they are nested at multiple levels. We have no option to roll back, because there could be any number of inline blocks created by any editors throughout our multisite setup, which has hundreds of pages.
I get and like the idea of inline blocks, but Optimizely should not have made this the default option with no proper opt out implementation (and no, this 'opt-out' that is simply the removal of the Create a Block button from Content Areas is not an acceptable implementation) when there are massive breaking changes to existing installations. This should have stayed in Labs for longer and had more thorough QA before being rolled out as a minor package update marked as "not breaking change". Until Inline Blocks can behave as Shared Blocks do, they cannot be the only way to use Create a Block button in Content Area; there is no feature parity to justify this massive breaking change in both functionality and workflow for our editors.
We hear you guys. A new version of CMS is coming soon, new inline blocks feature will be opt-in and will remain that way until we fix all the issues you all mentioned and submitted. Everything will work the same way as pre 12.21.0. A migration tool which converts inline blocks back to shared blocks is past QA and will be officially released today. It took us a while to realize we planned a very powerful feature in a very poor way. Very sorry for trouble. All future features which are so intruisive will be opt-in by default and will be consulted some time before the release to get feedback and allow you to plan to adjust delivery to new edit mode features accordingly.
12.22.3 has just been released. Inline blocks are now disabled by default. And `Create a new block` works as before.
For those who struggle to find inline blocks already created in the system we released a migration tool https://github.com/episerver/content-app-labs-block-enhancements nuget here: https://nuget.optimizely.com/package/?id=EPiServer.Labs.BlockEnhancements&v=1.2.2
Hi Bartosz,
There are a few bugs in the Convert Inline to Local blocks job functionality - I've had to pull the code from github and modify it to fix a few things:
I was going to push some suggested changes to github but realise that the repo doesn't allow changes.
All of the above is quite quick and easy to fix, but feel free to ask if you want my code to assist.
Kind regards
Matt
Oh and I just noticed that job is marked as being stoppable but it doesn't actually have a mechanism to allow it to stop execution part way through.
Thanks Matthew, makes sense. Maybe you can create a fork and create a cross-repo PR? Would that work for you?
Hi Bartosz,
Oh yep, good idea, I'll fork and create my own repo with those changes and link it here once done.
FYI, I've found more fundamental flaws/quirks in the conversion code:
I've made adjustments to rectify the first two points above.
Hopefully once I fork you can look at merging any of the code improvements that I have.
Kind regards
Matt
Oh, and I forgot to mention: the conversion in this tool only will convert the shallowest level of inline blocks (i.e. direct inline blocks are converted but if they contain any inline blocks within their properties, those are not converted). This is easily worked around by re-running the job again until there are no more to convert. If this is as per design, then I think it should be clearly documented as it may not be intuitive to users that the job needs to be subsequently rerun to get the now surfaced inline blocks converted too.
I get an access denied problem when trying to open the "Inline block converter". Looking at the source code for SharedBlocksConverterPluginController I guess this is caused by the usage of role CmsAdmin, which I think should be CmsAdmins (https://docs.developers.optimizely.com/content-management-system/docs/virtual-roles)?
Matthew Boniface , I don't see any forks or PRs. Are you still willing to contribute? Or would you like us to do that.
Hi Bartosz,
Sorry I missed your reply. I did try to create a PR at the time but the laptop I was working on was so locked down that I couldn't connect to github repos with it (or at least I couldn't figure it out) so couldn't get the code up. I no longer have access to the code changes I put together.
Kind regards,
Matt