- A little bit of history...
- The concept of Block editors
- The Block List editor
- So what does it do?
- Data Type and Block configuration
- A "real life" example
- Advanced data and logic in custom views
- Now it's your turn
A little bit of history...
Why do you have yet another property editor to consider when building out an Umbraco project? At the Codegarden Community Retreat in 2019, it was agreed that there is a need to standardise the way complex content is handled in Umbraco. Over the years there have been many examples of complex editors, both community packages and in Umbraco CMS: The Grid Layout editor, Nested Content, Stacked Content, Archetype, Bento and many more. These are all property editors that enable developers to provide simple and intuitive workflows for content editors while being highly configurable and customisable.
Many of the above examples have their own way of storing data, handling configuration and meta data and specific ways to render content.
Wouldn’t it be great if they were all built on the same foundation?
I think the answer here is obviously YES!
This lowers the point of entry for developers, as it will be a common, best-practice concept and makes it easier to collaborate/contribute to property editors.
In Umbraco 8, element types were added as the standard way to store the types used for complex editors. This means there is a clear differentiation between Document Types (the model for content nodes) and Element Types (the model for items used in property editors such as Nested Content).
In Umbraco 8.7 we’re extending this concept to handle storing the data in a standardised way, adding proper validation for Element Types and providing the foundation for future property editors.
The work at the retreat resulted in two Request for Comments (RFC). The first one for the underlying concept and data structure (RFC for Block Data Structure) and the second one for a new property editor based on the concept (RFC for Block Editor).
The concept of Block editors
The underlying foundation is called Block editors. A Block editor uses a specific data structure based on Element Types and has an API to create Property Editors and a number of helpful features that should make it easier to work with and, very importantly, document how to do this.
This article focuses on the Block List editor but if you are interested in creating your own Block editor you can find the documentation here.
The Block List Editor
The Block List Property Editor is basically a list of inner documents or blocks of content within a content node.
If you are at all familiar with Nested Content, you should be right at home as the default set up is very similar to that.
With the Block List editor you, as a developer, have a lot of control over how the blocks are displayed, edited and validated. You will also find the entire workflow for creating and updating blocks and types related to the Block List editor is intuitive and easier to work with.
So, what does it do?
The best way to run through the built-in features of the Block List editor is to have a look at how it is configured. In some ways, it’s similar to other property editors but there are some new workflows and features. They are there to make life as an Umbraco developer easier and help you craft a good editing experience.
Data Type configuration
When you want to use the Block List editor, you start by adding it to a property. This creates a new data type that is configuration for this Block List editor. The data type configuration looks like this:
An example of a new configuration for the Block List editor
Here you can set the overall configuration. You can control how many items are allowed by defining a minimum and/or maximum and you can control the editing experience by toggling the Inline editing mode:
Inline editing is similar to Nested Content and lets you edit the content of a block directly in the view. If inline editing is not chosen, an overlay will open up instead and you can edit the content here. The choice of which mode to use should be based on what gives the best overview when editing, whether there are many properties and settings to manage on a block and if you’re implementing custom representation of the content (custom block views) in the backoffice it can be nice to rely on the overlays for editing.
You also have the option to overwrite the width of the editor. Again, this can help the editing experience by making the editor view fit the content.
You can find detailed information for configuring a Block List in the documentation.
Let’s talk about the elephant in the room ;) The big “Add” button at the top of the configuration.
This is where the Block List editor configuration is a bit different from many other property editors. The list you create with the Block List editor is based on one or more blocks. Each block is based on an Element Type. Instead of having to create Element Types separately, you can start creating these directly from the configuration screen. All you have to do is push the “Add” button and you’re on your way.
When adding block you can either create a new Element Type or choose an existing. In the example there is an existing "Feature" Element Type.
From here you have the option to select an existing Element Type, if any are available, or create a new Element Type. Each block has individual configuration to allow for maximum flexibility and has a number of features to customise the editing experience. The configuration for a block looks like this:
Each block has separate configuration.
There are four main areas of configuration:
Here you can see how the block appears when accessed in the content section. You can customise the label for a block and this can be a static label or dynamic based on AngularJSexpressions. You can add a custom view, replacing the default representation with your own, by choosing an HTML file load and even a scoped CSS file to style your view.
Holds the types that are used for a block. The Content model is the Element Type for the block content and, if you want, you can add an Element Type for settings as well. The Settings model will show up as “Settings” in the Content section and both for inline and overlay editing. This is great for creating metadata or layout options for a piece of block content. If a model is selected here you can use this as a shortcut to edit the element type.
Another new feature in the Block List editor is the catalogue. The catalogue is what you see when you choose a block to add to a list in the Content section. It’s essentially a “block picker” and works in much the same way as other pickers in the Backoffice but allows for customisation of colors on the icon, text and background. You can even choose an SVG or thumbnail if you want to give your editors a preview of what a block looks like.
This is the default Block Catalogue showing icons and the name of the block.
A customised Block Catalogue using thumbnails to represent the content that each block can build. Makes quite a difference, right?
Finally, you can choose to hide the built-in editing view. This is useful if you’ve implemented a custom editing experience via a custom view.
You can find detailed information for configuring a block in the documentation.
A ‘real-life’ example
That’s a lot to take in! So, for the rest of the blog post, I’ll be working on an example in the 8.7 Starter Kit and you can play along and try it out for yourself.
We’ll add the functionality to create events in the Starter Kit and the Block List editor will be responsible for managing the dates on each event. If you want to follow along see the steps below. Make sure to use the exact naming for the document types, otherwise you'll run into trouble:
- New installation of Umbraco 8.7 with the Starter Kit installed
- Create a document type with a template named Events
- Make composition with Navigation Base and Content Base
- Allow to be created under the Home document type
- Create a document type with a template named Event
- Make composition with Navigation Base
- Allow to be created under Events document type
- Get this ZIP file, which contains templates etc. for our demo.
- Place the files of Views and the App_plugins respectively in your project. Overwrite the Events and Event .cshtml files.
Once the above is in place, add a content node called Events under the Home node and at least one event under there. We’ll name it Codegarden 2021 in this example.
Adding an event
If everything has gone right you should be able to view the frontend page for your event.
We want the ability to write something about each date of the event. We will use the Block List editor to manage the dates in a single property.
The Block List editor can contain one or multiple types of inner documents, in this example, we only need one type, which will be a date. Use the shortcut to edit the document type on the Info tab to create an ElementType and name it EventDate. We will give it three properties: Date, Headline and Description.
Since we are dealing with a simple data-set we will turn on “Inline editing mode”. Which will make the Block List editing experience be like the one you know from Nested Content.
Let’s create a bit of content to try out this new property.
Rendering Block List content
There are multiple ways to render the Block List property in your front-end, I will describe the two main ones here.
The HTML Helper
We have a HTML helper named Html.GetBlockListHtml() witch uses a partial view to render a block based on the Element Type Alias of the Content Model, these partial views should be located in \Views\Partials\BlockList\Components
Make a loop
The data of a property is a list of BlockListItem objects, which can be looped as in this example
Generally for both examples is that you will get a BlockListItem object which contains a property for the Content properties and one for Settings if the block has a Settings model.
To access the properties of a Block in a strongly typed maner you need to cast the Content or Settings to the ContentModel fitting for it.
In the above example we cast the Content with MyElementTypeAlias and stores this in a variable named blockItemContent.
You can see more details on rendering in the documentation.
Rendering event dates
In order to get our dates shown on the event page, all you need to do is remove the comments a few lines in our template event.cshtml.
Note that we use the default rendering and the partial view used for EventDate is defined in Views\Partials\BlockList\Components\EventDate.cshtml
Now it should look like this in our front-end:
Events rendered with the default renderer
Nesting Block List editors
Great, but in addition to this, we would like to add sessions with descriptions to each Event Date.
Since we want the ability to add multiple sessions on a given date, let’s use another Block List editor for managing sessions. To achieve this, we can add a new Block List property to the Event Date. We will name the property Sessions and create a new Block List editor with one block configuration based on a new ElementType that we name EventSession.
Now we have nested Block Lists that enable us to manage content on the appropriate level. Let's create some content for our sessions in our existing days:
Customising the editing experience
The editing experience has become a bit cramped and we do not have a great overview as we need to expand the dates in order to see the sessions. This can be totally fine in some cases but the Block List editor does have some easy to use features that can help improve this. To enhance the overview we will add custom labels for our blocks, this will make it easier to identify each session. We’ll also turn off the Inline Editing Mode for the Event Dates as the data set of these has grown and having to expand them hinders the overview.
Now we can have very large data sets for each Event Date and we adapted to this new scenario without changing our property-editor.
Labels make it easier to differentiate blocks.
Custom views for blocks
Applying the custom labels improved our overview but the headline itself does not give such a great impression of the content of a specific date. To improve our overview of the full program, we would like to display the main details about each session. This way, editors can easily get an overview of dates and sessions of this event.
To achieve this, we can overwrite the default representation of our block entries with a custom view. This view is part of your demo zip and therefore we will just pick that custom view and the stylesheet of it.
Now our content editors get a better overview of the dates of an event immediately when opening up the content node.
Customise the frontend rendering
Next, let’s add the event session to our front-end, this time we will not use the default rendering but just loop over the data in our razor view. Let's open the EventDate partial-view to add the code. (/Views/Partials/BlockList/Components/EventDate.cshtml)
Validating data of complex editors
Another great feature of this release is the complex validation which enables validation messages to appear at any place of your document. This enables the Block Editors to have errors presented at inner properties and through the UI we can lead editors to find their mistakes.
In the following example, I have added a Regex validation to the time property of EventSessions. This shows how I will be led back to my mistakes when publishing the Event.
Advanced data and logic in custom views
You have the ability to overwrite how your Blocks are presented in BackOffice by setting up your own custom view. A Custom View is a HTML file that will be interpreted by AngularJS, making it possible for you to use AngularJS Syntax and use the available data-model for your view.This
This can be used to make a different overview and you can even to build your own interface for editing your blocks.
In the above example, we use a custom view to display the EventDates headline with a list of the sessions below. The logic of this could be solved with inline angularJS syntax, by using the raw values of our block's data.
But sometimes we might want to do something where the data available isn't enough.
To get to this point let’s extend the example from above by adding an image for Event Date:
Add an Image property to the Event Date Element Type.
We want to display this image in our custom view, as shown in this screenshot:
Custom views for blocks with data and images from a nested Block List
But it's not that easy. The value we have available for our image is a UDI which is a string that identifies the image being used. To get useful data we need to request the data of the media item related to the UDI. This logic cannot be placed inline in our HTML file, therefore, we will create an AngularJS controller in a JS file which we will load into the backoffice and used by our custom view.
First let's write our controller and place it here “/App_Plugins/BlockListDemo/EventDate.controller.js” (This is part of the demo ZIP-file):
This code will load the data of a media item by using the entityResource API, which we have to inject in our controller. Additionally, we watch the value to update the Url if the image is changed.
In order for the Backoffice to know about this file we need to load it through a “package.manifest” file, this file can only exist inside the “~/App_Plugins/” folder. (This is part of the demo ZIP-file)
Now let's add the controller to our custom view and use the imageUrl to display the image in our custom view (~/App_Plugins/BlockListDemo/EventDate.html). These changes are commented out in the demo file, but lets run over what has been added;
First we need to initialize our controller for this view, we add the ng-controller attribute on the <button …> element.
Next we need to show the image, here we have added a <img …> tag which is only shown when there is a value of imageUrl.
The updated EventDate.html should look like this:
In this way we can have custom views that display complex data, provides WYSIWYG or completely customises the editing experience. You can enrich your block data with information from other content or even external data.
Learn more about custom views in our documentation here.
Now it’s your turn
I hope this post has given you a good idea of what the Block List editor enables you to achieve as a developer.
There are many built-in features that can help you provide a great editing experience for content editors with little effort. There are extension points to give you the power to provide highly customised workflows and tailored presentation of content. We’ve tried to make the Block List property editor as intuitive to use as possible while not shying away from allowing complexity where it is warranted.
We’re really happy with the result and we couldn’t have done it without the input and experience of many Umbraco developers and agencies. So a huge thank you to the MVPs that helped formulate the initial RFC and everyone who contributed in the discussion. To the community members that joined a live stream to give feedback on an early prototype. To our friends at our Gold Partners, ProWorks for providing dedicated developer resources in the early implementation phase. To all the many developers who have helped test the Block List editor in the 8.7 Release Candidate. You all deserve a massive H5YR 🙌
Now it’s your turn to use the Block List editor! We can’t wait to see what you build with it 🤩