DEV Community

Cover image for Umbraco 9 - BlockList editor with added ViewComponents
Gareth Wright
Gareth Wright

Posted on • Updated on

Umbraco 9 - BlockList editor with added ViewComponents

Umbraco 9 is built using .net 5, which is .net core. This allows us to utilise ViewComponents with BlockList editor within Umbraco.

We've updated our blocklist implementation to use the following code to make use of ViewComponent invoking. The following code is an extract from the views/partials/blocklist/default.cshtml view.

@inherits UmbracoViewPage<BlockListModel>
@inject IOptions<OurConfiguration> _configuration
@inject IViewComponentSelector _selector;
@if (Model == null || !Model.Any()) { return; }

@foreach (var block in Model.Where(x => x?.ContentUdi != null))
{
    if (block.Content is SiteMapTree)
    {
        @await Component.InvokeAsync(block.Content.ContentType.Alias, Umbraco.AssignedContentItem)
    }
    else if (_selector.SelectComponent(block.Content.ContentType.Alias) is not null)
    {
        @await Component.InvokeAsync(block.Content.ContentType.Alias, block.Content)
    }
    else if (block.Content.ContentType.Alias.Equals(Form.ModelTypeAlias))
    {
        @await Html.PartialAsync("components/" + block.Content.ContentType.Alias + "/default", block.Content)
    }
    else
    {
        @await Html.CachedPartialAsync(
            "components/" + block.Content.ContentType.Alias + "/default", 
            block.Content,
            TimeSpan.FromSeconds(_configuration.Value.CacheDuration), 
            true,
            contextualKeyBuilder: (model, viewData) => (model as IPublishedElement)?.Key.ToString())
    }
}
Enter fullscreen mode Exit fullscreen mode

If we take the code above apart, we're doing a series of new things...

  1. We're injecting directly into our view, which allows us to inject our configuration and the IViewComponentSelector. https://docs.microsoft.com/en-us/aspnet/core/mvc/views/dependency-injection?view=aspnetcore-6.0

  2. SiteMapTree ViewComponent has a specific implementation that we need to pass the AssignedContentItem.

  3. We can now test to see if our block is a ViewComponent and Invoke it without having to type out each block. This is what the IViewComponentSelector is for, as it can tell us whether the block is a ViewComponent.

  4. If the block is a Form, we can avoid caching, as this is bad. Never cache a form, this can result in customer data being stored in cache and showing for another request.

  5. If the block is a simple block, without any logic and not a form, we can then cache it and serve it directly through a partial.

All components are then stored under components directly in the root of views. This is standard .net core practice for ViewComponents: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-6.0

This allows us to create components in Umbraco for the BlockList editor, then add renderings all within one area. This keeps everything nice and neat.

Any improvements or suggestions let me know!

Discussion (0)