Umbraco 9 is built using .net 5, which is .net core. This allows us to utilise ViewComponents with BlockList editor within Umbraco.
- https://umbraco.com/products/umbraco-cms/umbraco-9/
- https://our.umbraco.com/documentation/reference/templating/mvc/ViewComponents-index/
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())
}
}
If we take the code above apart, we're doing a series of new things...
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
SiteMapTree ViewComponent has a specific implementation that we need to pass the AssignedContentItem.
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.
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.
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!
Top comments (0)