Combine Umbraco 11, Contentment Icon Picker and Razor Views!

I am in the middle of building a new version of Owain.Codes in Umbraco 11 and I decided I wanted to be able to create my navigation with icons, but I wanted to be able to select the icons from the backoffice. 

On my project I've installed Contentment which is a fantastic package by Lee Kelleher. It allows you to do loads of cool things straight out the box. One of the Property Types that is available is Icon Picker and that's what I'm going to discuss. 

I've added the icon picker property type to my Document Type. 

I'm using strongly typed models and this makes using the Icon Picker really easy and to be honest, the documentation for Contentment is really good too so it was a case of just following the docs. 

Model.Icon

Will give me the icon name and also the colour selected, so for example, the icon selected in the image above would give me - 

icon-alt color-black

in my view. Pretty handy! 

But, what I had expected to happen was, if I used the following code - 

<div class="@Model.Icon">My Nav Item</div>

that I would then get the icon displayed. I didn't. 

What next?

I posted on the Umbraco Forum and Lee came with a fantastic suggestion on how to get this to all work together and here is the code that I've implement - I'll explain it all after the code snippet: 

@inherits UmbracoViewPage<IEnumerable<BlockListItem>>;
@inject Umbraco.Cms.Core.Services.IIconService _iconService

<style>
    .my-icon > svg {
        height: 20px;
        width: 20px;
        fill: blue;
    }
</style>
@if (!Model.AnyNotNull())
{
    return;
}

@foreach (var menu in Model)
{
    if (menu.Content is NavItem navItem && navItem.Link != null)
    {
        var iconCleaned = string.Empty;
        var myIcon = new Umbraco.Cms.Core.Models.IconModel();

        if(navItem.Icon != null)
        {
            iconCleaned = navItem.Icon.Split(' ').First();
            myIcon = _iconService.GetIcon(iconCleaned);   
        }
       
        <li class="nav-item active">
            <a class="nav-link" href="#">
              @if(myIcon != null)
              {
                   <i class="my-icon">@Html.Raw(myIcon.SvgString)</i>
              }
               
                Blog Home 2 <span class="sr-only">(current)</span></a>
        </li>
    }
}

Firstly, this is still a work in progress, but it works. 

I've had to get the icon name from the navItem.Icon by using Split on the string, the icon name is always the first value in the string.

At the top of the razor view, I've injected the Icon Service and this is used to get the SVG for the icon. 

I can then use the name and the SvgString extension to return the actual SVG. 

This now gives me the icon and renders it to the front end. 🎉

The only part I've not managed to get to work is the colour picker part of the icon picker.

Just now I'm having to hardcode the fill value of the svg.

I'm going to try and find a way but if not, then at least it's an icon picker that works and that was the original aim. 

Massive #h5yr to Lee for creating Contentment but also for answering my forum post. 

 

UPDATE - Since publishing this, it's come to my attention that I could possibly use Tag Helpers to do this. I'll give it a go and write another blog if I get it to work. 

Published on: 06 March 2023