Solving the 'For This {0}' issue in Optimizely

Solving the 'For This {0}' issue in Optimizely

A solution for the incorrectly formatted folder name for custom content types

In Optimizely you can create custom content that is not inheriting from one of the standard types like a block or page. You do this by inheriting from one of the base classes like StandardContentBase, ContentBase or even BasicContent, depending on how many features you need like versioning and languages. There are some good blog posts out there that explain how to create such custom content and add things like UI elements — so I will not go into detail about it here. The problem I've had for a long time is that when you edit your custom content, the folder that usually states 'For This Page' or 'For This Block' will now be called 'For This {0}'. I finally took the time to investigate the issue and come up with a solution.

The assumption I've always had is that the label is missing for my custom content type and therefore the '{0}' part of the label is not formatted correctly. The question was how do I add the label? After some digging I found the XML localization resource that is responsible for this label.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<languages>
  <language name="English" id="en">
    <contenttypes>
      <blockdata>
        <name>Block</name>
      </blockdata>
      <pagedata>
        <name>Page</name>
      </pagedata>
    </contenttypes>
  </language>
</languages>

For each base content type there is a name variable that is used to format the folder name. What I needed now is to set this variable for my example type called CustomContent. Adding localization to the CMS is done by creating an XML file and putting it in the /lang folder of the project. I used the following XML containing a new section using the name of my example type.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<languages>
  <language name="English" id="en">
    <contenttypes>
      <customcontent>
        <name>Custom Content</name>
      </customcontent>
    </contenttypes>
  </language>
</languages>

Unfortunately this did not work initially and I later found out that it only works for primary types. Those other types such as BlockData and PageData are marked by a UI descriptor as primary types using the IsPrimaryType variable. The variable is used internally to identify which one of base types of a content type contains the information related to the UI elements like the folder name. In my case I'm not inheriting from any primary types and therefore there is no label.

To solve this I can turn my type, or even a custom base type, into a primary type by creating a UI descriptor. Note that you should use this at your own risk, because there is not much information available online about primary types and how to use them.

[UIDescriptorRegistration]
public class CustomContentDescriptor : UIDescriptor<CustomContent>
{
    public CustomContentDescriptor()
    {
        IsPrimaryType = true;
    }
}

The result is that the label is now displayed correctly. image.png As a final note — I hope that Optimizely will expand on the folder name localization so to make it more flexible and have a default value like 'Content'. It would be great if you could set the name for every content type, not just primary types, so that the folder name could be 'For This Article Page' for example. It would even make it more clear to the user what content is located in the folder. Cheers!