Theming websites in Umbraco using SASS and HTML5 color picker

Sass is used as the stylesheet language for an Umbraco website that I’ve been building recently and one of the requirements of the project is for the content editors to be able to change the colours of the website depending on the brand colours.

Sass variable defaults work really well for this. It meant that I could create a default variable for a colour e.g.

$brand-color: #0074BE !default;

Then for each website in Umbraco I could essentially override that variable and when compiled, this value will be used instead:

$brand-color: #FFFFFF;

On a static website, this all worked great but I had to figure out a way to get this to work in Umbraco.

The first step was to allow the Content Editors to change the theme colours. I did this using the lightweight HTML5 Color Picker :

umbraco theming html color picker

These fields are stored as HEX which is perfect.

The next step was to get these HEX values into the Sass and to compile it. This was achieved by using LibSass Host for .NET .

What I ended up doing is creating an UmbracoApiController that was called from the Master view that then returns the CSS for that website:

@{ 
var siteId = UmbracoContext.Current.PublishedContentRequest.PublishedContent.Site().Id;
}

<link rel="stylesheet" href="/umbraco/api/css/get?id=@siteId">

As this is a Web Api controller, I had to pass the website id into it, in order to use it.

Now I needed to read in all the Sass files from the file system:

var sassFolderPath = HttpContext.Current.Server.MapPath("~/styles/sass/");
var sass = "";

foreach (var filePath in Directory.GetFiles(sassFolderPath, "*.scss", SearchOption.AllDirectories))
{
    sass += File.ReadAllText(filePath, Encoding.UTF8);
}

Once I had all that, I could then insert the HEX values from Umbraco into theme variables:

var homePage = UmbracoContext.Current.ContentCache.GetById(websiteId);
sass += ProcessColour("themeMainColour", "color-brand--main", homePage);
sass += ProcessColour("themeMainContrastColour", "color-brand--main-contrast", homePage);

private static string ProcessColour(string umbracoFieldName, string sassVariableName, IPublishedContent homePage)
{
    if (!homePage.HasValue(umbracoFieldName)) return "";

    var hex = homePage.GetPropertyValue(umbracoFieldName).ToString();
    return $"${sassVariableName}: {hex};\r\n";
}

The sass string variable can now be passed into LibSass to compile it and I get some lovely CSS back!

 var css = SassCompiler.Compile(sass, "input.scss").CompiledContent;

This CSS can then be returned in the HttpResponseMessage of the Api method.

I’ve added a whole lot of caching around this as well so one extra thing I had to do in order to expire the cache was to implement a ApplicationEventHandler so whenever the Homepage of a website is published, it expires the CSS cache for that website.

 

Theming websites in Umbraco using SASS and HTML5 color picker

AngularJS ui-sortable on a table in Umbraco

I was building a custom dashboard recently and needed to give the client the ability to change the sort order of how attributes were displayed on the website and it turned out to be a lot easier than I was expecting.

From the start I wanted it to work just like the reorder functionality on Document Types:

Umbraco Reorder

After a bit of digging, it seemed that this was using ui-sortable and is automatically included in Umbraco. You can find it in the folder \Umbraco\lib\angular\

This meant that I could attach ui-sortable to the <tbody> element of my table and assign the attributes data to the ng-model:

<table class="table">
    <thead>
        <tr>
            <th scope="col">Sort Order</th>
            <th scope="col">Attribute Name</th>
        </tr>
    </thead>
    <tbody ui-sortable ng-model="attributes">
        <tr ng-repeat="row in attributes" id="{{row.id}}">
            <td>{{row.sortOrder}}</td>
            <td>{{row.attributeName}}</td>
        </tr>
    </tbody>
</table>

Then, just like magic, you can drag and drop the rows in the table!

As the attributes are allocated to the ng-model of the table body, angular keeps the object in sync with the order displayed and then I could save that new order back to the database with ease.

AngularJS ui-sortable on a table in Umbraco