Vulnerability in EPiServer.Forms

Try our conversational search powered by Generative AI!

Bartosz Sekula
Jul 24, 2023
(2 votes)

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:
Or in the documentation


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:

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: 

Jul 24, 2023


Frederik Vig
Frederik Vig Jul 24, 2023 05:04 PM

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.

  1. Instead of InlineBlockNamePropertiesOptions, create InlineBlockOptions. That way you can add more options and logically group them together. Otherwise you'll end up with settings/configuration all over the place. 
  2. "InlineBlockEditSettings is being obsoleted and will be removed in CMS 13." hopefully replaced by InlineBlockOptions mentioned above.
  3. "InlineBlockNamePropertiesOptions which can be set via appsettings.json" - we should be able to set this via code as well and support default, base types, interfaces etc.
  4. InlineBlockEditSettings.ShowNameProperty = true. This will show the Name property, but not save the value. I know multiple people have mentioned this before as well.
  5. Here's a simple suggestion:
    "InlineBlock": {
        "Disabled": false,
        "ShowNameProperty": false,
        "ShowCategoryProperty": false,
        "NameProperties": {
            "BlockData": "Name" // This would be nice: "BlockData": "Heading,Name", uses Name if Heading is empty.
            "IMySpecialBlock": "SpecialBlockPropertyName"
        "HiddenGroups": "Advanced, Settings, etc",
        "ExpandedGroups": true, // Groups/sections are expandable/collapsible. This would mean that they're all expanded, like now, by default
        "OtherOption1": "",
        "OtherOption2": ""

DOldfield Jul 26, 2023 11:09 AM

> 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 :)

Otto G
Otto G Jul 26, 2023 12:25 PM

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?

Otto G
Otto G Jul 26, 2023 02:20 PM

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.

Bartosz Sekula
Bartosz Sekula Jul 26, 2023 09:12 PM

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.

Raphael Yousuf
Raphael Yousuf Jul 27, 2023 04:29 AM

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.

Raphael Yousuf
Raphael Yousuf Jul 27, 2023 04:38 AM

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.

Otto G
Otto G Jul 27, 2023 08:31 AM

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 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.

Otto G
Otto G Jul 27, 2023 08:35 AM

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.

Rowan Bottema
Rowan Bottema Jul 27, 2023 08:39 AM

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.

Otto G
Otto G Jul 27, 2023 09:15 AM

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.)

Otto G
Otto G Jul 27, 2023 12:51 PM

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:

.Configure<InlineBlockNamePropertiesOptions>(options =>
    //options["Section"] = "Heading"; // Does not work
    //options["SectionBlock"] = "Heading"; // Does not work
    options["Sektion med inramning"] = "Heading"; // Works when Personal Language is set to Svenska under Language Settings
    options["Section with framing"] = "Heading"; // Works when Personal Language is set to English under Language Settings

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.

DOldfield Jul 27, 2023 02:09 PM

This just seems to get more disappointing as the threads go on.

We won't be upgrading any customers for a while it seems.

Otto G
Otto G Jul 27, 2023 03:51 PM

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.

btranorchard Jul 28, 2023 12:51 AM

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.

Bartosz Sekula
Bartosz Sekula Aug 1, 2023 06:51 AM

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.

Bartosz Sekula
Bartosz Sekula Aug 8, 2023 12:09 PM

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 nuget here:

Matthew Boniface
Matthew Boniface Aug 18, 2023 04:36 AM

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:

  1. SaveAction.SkipValidation on the new local blocks so they don't get blocked by validation.
  2. ConvertInlineBlocks.TryConvertContent: try/catch handling around _contentRepository.Get<IContent>(version.ContentLink) because [maybe it's just us] we had an issue where some content wouldn't load - seems worth having a try/catch so that it doesn't show as a failed conversion when it hasn't actually found any inline block content.
  3. ConvertInlineBlocksResult.ToString needs to have the FailedContentItems with a string.Join so that it actually outputs the content reference IDs correctly (also, I think it's nice to add a count of failutres before this too).
  4. ConvertInlineBlocks.Convert: Remove the '$' symbol before the FailedContentItems count

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


Matthew Boniface
Matthew Boniface Aug 18, 2023 06:06 AM

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.

Bartosz Sekula
Bartosz Sekula Aug 18, 2023 06:49 AM

Thanks Matthew, makes sense. Maybe you can create a fork and create a cross-repo PR? Would that work for you?

Matthew Boniface
Matthew Boniface Aug 21, 2023 01:28 AM

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:

  • It does not support Property Blocks (i.e. blocks that are a direct property on a content item)! This is a massive limitation as property blocks are widely used on projects and any inline blocks on these won't be converted.
  • The job includes converting inline blocks on PreviouslyPublished versions of content - the side affect of this is you can end up with many many created copies of the inline block now in the "For this" folder. This makes quite a mess - so in my code I've changed it to exclude PreviouslyPublished and it's much tidier. Ideally this would be added as an option, I suppose.
  • The admin UI for the job options is inaccessible (get 403 not authorised) on our codebase (I haven't tried it on Alloy so not sure if this is specific to our project).

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


Matthew Boniface
Matthew Boniface Aug 21, 2023 02:11 AM

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.

Martin Emanuelsson
Martin Emanuelsson Aug 22, 2023 12:59 PM

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 ( 

Bartosz Sekula
Bartosz Sekula Sep 1, 2023 05:47 AM

Matthew Boniface , I don't see any forks or PRs. Are you still willing to contribute? Or would you like us to do that.

Please login to comment.
Latest blogs
Getting Started with Optimizely SaaS Core and Next.js Integration: Creating Content Pages

The blog post discusses the creation of additional page types with Next.js and Optimizely SaaS Core. It provides a step-by-step guide on how to...

Francisco Quintanilla | Dec 1, 2023 | Syndicated blog

Stop Managing Humans in Your CMS

Too many times, a content management system becomes a people management system. Meaning, an organization uses the CMS to manage all the information...

Deane Barker | Nov 30, 2023

A day in the life of an Optimizely Developer - Optimizely CMS 12: The advantages and considerations when exploring an upgrade

GRAHAM CARR - LEAD .NET DEVELOPER, 28 Nov 2023 In 2022, Optimizely released CMS 12 as part of its ongoing evolution of the platform to help provide...

Graham Carr | Nov 28, 2023

A day in the life of an Optimizely Developer - OptiUKNorth Meetup January 2024

It's time for another UK North Optimizely meet up! After the success of the last one, Ibrar Hussain (26) and Paul Gruffydd (Kin + Carta) will be...

Graham Carr | Nov 28, 2023

Publish content to Optimizely CMS using a custom GPT from OpenAI 🤖

Do you find the traditional editor interface complicated and cluttered? Would you like an editorial AI assistant you can chat with? You can!

Tomas Hensrud Gulla | Nov 28, 2023 | Syndicated blog

Optimizely Graph and Next.js: Building Scalable Headless Solutions

Optimizely Graph harnesses the capabilities of GraphQL, an intuitive and efficient query language to, transform content within an Optimizely CMS in...

Szymon Uryga | Nov 27, 2023