When using any sort of CMS there are many ways to configure the editorial experience. One approach we'll demonstrate here is by creating resuable blocks with Nested Content and Umbraco's Modelsbuilder. Both of these tools are incorporated within a default Umbraco installation so there's no need for third-party dependencies or packages.

Imagine a situation where your designed template can be split into several separate sections
as shown below.

One option is to create a document type which contains the data types to cover all these blocks and elements in it at once. A more flexible alternative however, is to create separate blocks that can be created indefinitely and in an order that is desirable. Consequently these sections can also be used within multiple document types as you like.

For this particular example two individual blocks will be created.

  • BlockCTA: A so called "Call-To-Action" block containing a header text and button.
  • BlockTwoColumns: A block seperated into two columns that may contain either text, image or video.

The naming convention has been made equal to the intended functionality as much as possible with a prefix 'Block' to keep things clear.

Each block will have it's own controller, cshtml template and some css styling. In the Umbraco backoffice we'll create two document types, without a template, both containing some predefined data types.

Umbraco Backoffice set-up

Let's start in the Umbraco backoffice by creating the necessary document types.
Choose the option where no template will created alongside the type. We'll handle
this inside the blocks controller.

BlockCTA:

BlockTwoColumns:

For both blocks give permissions to use them as an 'Element type'. An Element type is meant to
be used in Nested Content, and not in the tree.

The final step is to create a new data type of type Nested Content as a container for the newly created blocks.

It's up to you where you want to utilize the type. In principle this could be any other document type you've created or will create in the future.

Back-end

Since we have two blocks there will also be seperate controllers for each of them. Of course it's possible to apply any logic you like here. One main controller will do the basics. Since Umbraco Modelsbuilder handles all the Object Relation Mapping for us we only need to find the right template file.

Depending on how you've set-up the Umbraco Modelsbuilder two models will already have been
generated inside the specified folder or, included in the final .dll. That's why we can reference to the models in the Umbraco.Web.PublishedModels namespace.

namespace Controllers.Blocks {
    public abstract class BlocksController<TModel> : SurfaceController {
        public virtual string ViewPath(IPublishedElement content) => string.Format("~/Views/Blocks/{0}.cshtml", content.ContentType.Alias);

        public virtual ActionResult Index(IPublishedElement content) {
            return PartialView(this.ViewPath(content), content);
        }
    }

    public class BlockCTA : BlocksController<Umbraco.Web.PublishedModels.BlockCTA> {
    }

    public class BlockTwoColumns : BlocksController<Umbraco.Web.PublishedModels.BlockTwoColumns > {
    }
}

The templates could look something like this. It's of course all up to you how you structure the html and want the lay-out to be.

@inherits Umbraco.Web.Mvc.UmbracoViewPage<Umbraco.Web.PublishedModels.BlockCTA>
<div>
<h2>@Model.Title</h2>
<h3>@Model.Subtitle</h3><a href="@Model.Button.Url">Click!</button>
</div>
@inherits Umbraco.Web.Mvc.UmbracoViewPage<Umbraco.Web.PublishedModels.BlockTwoColumns>
<div>
@Html.GetGridHtml(Model, "propertyAlias")
</div>

Some final words

It goes without saying that you're totally free to arrange any number of blocks
according to your wishes or that of your client. But please bear in mind this is
just one way way of configuring an editorial experience.

If you have any questions or remarks please feel free to contact FungyBytes via contact@fungybytes.com or give us a tweet @fungybytes

Why giving good development time estimates is hard

Developers hygiene. Some tips to stay on top.

For proper functioning and anonymous analysis of our website, we place functional and analytical cookies that have no or minor consequences for your privacy. These cookies may collect data outside of our website. By using this website you agree to the placement of these cookies.