Applying Helix code analysis to GitHub repos – Step by step

Whilst working alongside Rad Kozlowski, he recently created a GitHub action that can be applied to any Helix Github repo. This runs an automated analysis on the source to check for Helix compliance. HelixCheck was launched and I have set this up on a Helix Base feature branch with a tutorial below:

Step 1: In your GitHub repository select the ‘Actions’ tab. Here you will see a list of actions that are running on this repository:
Step 2: With your current actions visible, select ‘New workflow’, this will open the following screen where we will select ‘set up a workflow yourself’:
Step 3: This will open the new workflow screen:
Step 4: Delete the contents of this screen and replace with the HelixCheck action, I’ve added descriptive comments:
Below is the code to copy and paste, you can also find the file on Helix Base:
name: Helix Check on 9.2 branch

# Controls when the action will run. HelixCheck workflow will run on push
# events but only for the feature 9.2 branch 
    branches: [ feature/9.2.0 ]

# Set up the HelixCheck job
    name: Helix check
    runs-on: ubuntu-latest

# Check out the repo
      - name: Checkout
        uses: actions/checkout@v2

# Configure the Helix Check step
      - name: Helix Check
        uses: ethisysltd/helix-check@v1.0
        id: check
          solution-file: 'Helixbase.sln' # Set the name of your solution file here
          project-name: 'Helixbase' # Add the project name here. Helix Base naming is Helixbase.Feature.Hero for example so the project name is 'Helixbase'
          website-folder: 'website' # Older versions of Helix will use 'code' here, newer is 'website'
      # Output the HelixCheck results
      - name: Get the check result
        run: echo "Check result - ${{ steps.check.outputs.result }}"
      - name: Get the output time
        run: echo "The time was - ${{ steps.check.outputs.time }}"

Once you save the action you can then see an output of the results under Actions:

Any issues within the project relating to Helix compliance will now be listed here. This action can be applied to any event or any branch which means automated code analysis on any Helix GitHub repo, excellent work Rad!

Working with the with New csproj format in Sitecore: Issue#1 RazorGenerator.MsBuild

Many of us have been using precompiled views for a while in Sitecore and the new csproj format for .NET Core is something we’d like to utilise, but the new csproj format does present us with some challenges. One such issue presents itself when using RazorGenerator.MsBuild, which can cause the following issue when trying to compile the solution:

2>------ Build started: Project: Helixbase.Feature.Hero, Configuration: Debug Any CPU ------
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : Could not precompile the file '\Views\Layouts\Helixbase\Default.cshtml'. Ensure that a generator declaration exists in the cshtml file. 
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : A generator declaration is the first line of your cshtml file and looks like this: 
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : @* Generator: MvcHelper *@
1>C:\Users\nshac\.nuget\packages\razorgenerator.msbuild\2.5.0\build\RazorGenerator.MsBuild.targets(44,9): error : Valid host names: MvcHelper, MvcView, Template, WebPagesHelper, WebPage, RazorGenerator.Core.IHostProvider

As the error states, one way around this is to add the generator declaration in each view @* Generator: MvcHelper *@ although in our Sitecore Helix solution it’s not practical to add this to every view.

There seems to be an issue in RazorGenerator.MsBuild in that it looks for System.Web.Mvc in the csproj and can’t find it. One workaround for this is to add the following to every csproj:

<!--System.Web.Mvc this line only exists so that razorgenerator picks this up as an mvc project -->

Adding this enables us to use precompiled views per project rather than adding them to every view in our Helix modules. You can see this in action on Helix Base until a more permanent fix is made to RazorGenerator.MsBuild

Introducing ‘Host Base’ – now available on GitHub

For anyone wishing to get started with a basic Sitecore Host app you can find documentation online. However, sometimes it’s easier to see a working example, therefore I have created Host Base as a starting point for anybody wishing to create a Host application.

Ultimately, the same principle will apply as Helix Base but presently Host Base is a very basic example that runs as a plugin within the Identity Server application. We’re presently limited to creating plugins for current Sitecore Host applications (such as Identity) – With this in mind, hopefully it’s a helpful starting point.

The application currently very simply writes information to the logs, and reads values from configuration. Stay tuned for updates as it grows in functionality.

I hope this is useful for anybody wishing to get started with this exciting form of Sitecore development.

Introducing ‘Helix Base Modules’ – now available on GitHub

Since its conception, Helix Base has been adopted as a starting point for Sitecore development (using Helix conventions) by a large number of individuals and organisations alike.

It was created with efficiency in mind and therefore was setup in a manner that ensures it remains as ‘lightweight’ as possible. This results in features being restricted to a few basic examples. Due to the amount of requests to add functionality to the solution that had to be rejected, I have now created Helix Base Modules which is an area for any willing contributors to upload their Helix Base module. This repo enables additional functionality to the framework whilst avoiding bloating the solution.

In an attempt to streamline the solution, I have refactored the ‘fun’ module from Helix Base and used this as a starting point for the new repo.

Please feel free to submit any useful Helix Base modules that you have created, and share them with the rest of the development community.

Glass.Mapper performance – Sitecore ORM benchmark test

I recently gave a talk at the Manchester Sitecore User Group and part of this involved presenting information regarding the performance of Glass.Mapper. To ensure that reliable information exists in the public domain regarding the speed of some popular Sitecore ORM’s a GitHub repository now exists to perform a benchmark test and I thought I’d expand on the talk and write up some results.

I executed the tests from the repository on Sitecore 9.0.1 with a machine spec of Intel Core i7 7th Gen @ 2.40GHz with 16GB RAM, and the following are covered in the benchmark test:

Native Sitecore API
Glass.Mapper v5.1.0
Fortis v4.2.2
Synthesis v9.0.1

Each test was executed three times and each test itself runs the code 1000 times, so if you’d expect faster speeds – this is why. The results are listed below with an average taken of the three test executions. There is also an explanation that focuses on Glass performance as this is a topic I’d most like to address in this blog post.

1. ‘New’ test:

This is a basic test for a new item, the results are as follows…

Sitecore: 0, 0, 0 = 0ms
Glass: 8, 9, 8 = 8.33ms
Fortis: 1, 1, 1 = 3ms
Synthesis: 0, 0, 0  = 0ms

Glass creates proxy items which maps our data to objects that are CMS agnostic, and with the mapping running through a config pipeline it’s probably expected that the additional features result in a slower speed. Other object mapping frameworks wrap the Sitecore API calls, so we see a similar result to the native API.

2. ‘RenderFields’ test:

This is as the test above plus some field mappings…

Sitecore: 497, 495, 505 = 499ms
Glass: 300, 256, 306 = 287.33ms
Fortis: 526, 470, 480 = 492ms
Synthesis: 492, 512, 474492.66ms

It’s interesting to note that the native API on this occasion is slower than Glass. This is because Glass does not use the Render Field pipeline for fields other than Rich Text. Rendering fields is a very common action as a Sitecore developer, so the performance gain here is one of the more important ones in the test. Obviously, the templates used here are basic, for templates with more fields I’d expect Glass to offer an even bigger performance enhancement.

3. ‘Children’ test:

This test simply maps children of an item but doesn’t contain any field mappings for the child items…

Sitecore: 81, 42, 59 = 60.66ms
Glass: 119, 111, 123 = 117.66ms
Fortis: 80, 70, 72 = 74ms
Synthesis: 49, 42, 47 = 46ms

Again, Glass offers additional features meaning in this instance each child runs through the relevant configuration pipelines where Glass checks the likes of template enforcement etc. A more complex type match offers more features but a slower map speed, once again we’re in the ‘Feature vs Speed’ situation. The other frameworks only contain basic type matching which enables a faster result.

4. ‘ChildrenWithFields’ test:

This test is the same as the previous one, but on this occasion, we map children of an item including field mappings…

Sitecore: 5511, 5561, 5580 = 5550.66ms
Glass: 893, 661, 651 = 735ms
Fortis: 1122, 973, 968 = 1021ms
Synthesis: 1054, 959, 974 = 995.66ms

A practical example of this would be a Menu item for example and here we see an example of where mapping frameworks excel when compared to the native API. The reasons for this again relates to the Render Field pipeline. When it comes to rendering fields, once again it’s Glass that returns the fastest result.

Combined total for all tests:

Sitecore: 0 + 499 + 60.66 + 5550.66 = 6060.32ms
Glass: 8.33 + 287.33 + 117.66 + 735 = 1148.32ms
Fortis: 3 + 492 + 74 + 1021 = 1590ms
Synthesis: 0 + 492.66 + 46 + 995.66 = 1534.32ms


The test doesn’t factor in how much time it takes to configure the ORM or work with it (or without it) on a daily basis. It also doesn’t necessarily account for the trade-off between the amount of features the ORM supplies vs the time taken to render a page. Other factors to consider are the likes of any time savings afforded to us when using an ORM and writing unit tests for example, or assistance when writing SOLID class design and maintainable/reusable code. As ever, nothing boils down to speed alone, we must weigh up the overall efficiency of the framework which means including all contributing factors, so there’s scope for another post here, potentially a part 2 coming in future.

While Glass is slower than the Sitecore API for specific calls, in the combined totals we can see that for general use there is a significant performance gain. It would seem impossible that an ORM could offer a performance gain over a native API, but we can see here this isn’t the case.

Why not learn more about Glass and study the training course, something I’d highly recommend.

Sitecore placeholders as a Droplist

When it comes to selecting a placeholder in Sitecore we are required to enter text into a Single-Line Text field:

placeholder select

Obviously this introduces scope for a typo and potentially isn’t an ideal user experience. So I thought we’d look at changing this to a Droplist. The good news is the first step is a very straightforward task and we only need to update the Standard Rendering Parameters template found at /sitecore/templates/System/Layout/Rendering Parameters/Standard Rendering Parameters

The Placeholder field can be updated to a Droplist with a source query that filters anything that’s not a ‘Placeholder’ template (/sitecore/templates/System/Layout/Placeholder). We can use a query such as:

query:/sitecore/layout/Placeholder Settings//*[@@templateid='{5C547D4E-7111-4995-95B0-6B561751BF2E}’]

Our Standard Rendering Parameters template now appears as follows:

sitecore rendering parameters

And we can now select our placeholders from a Droplist:


Bear in mind that we have directly updated a Sitecore template, so any platform update will replace this change. We could serialize the Standard Rendering Parameters template but adding a vanilla template to source control is never a good idea. Food for thought.

Sadly our work isn’t quite finished, while this works for the Control Properties Dialog we also need to think about the Select Rendering Dialog incase a user wants to add a rendering from the Device Editor:

sitecore rendering selection

This is a sheer UI control found at:


So we need to find the XML Control that uses the class Sitecore.Shell.Applications.Dialogs.SelectRendering

This is found in \sitecore\shell\Applications\Dialogs\SelectRendering\SelectRendering.xml

Rather than manipulate the vanilla XML control, we can copy this file to the ‘override’ folder to ensure that our new control is used:


Edit the line:

<CodeBeside Type=”Sitecore.Shell.Applications.Dialogs.SelectRendering.SelectRenderingForm,Sitecore.Client”/>

And change this to the class in your project:

<CodeBeside Type=”Helixbase.Feature.Fun.SelectRenderingForm,Helixbase.Feature.Fun”/>

And for our code behind file we can copy the class ‘SelectRenderingForm’ which is found in Sitecore.Shell.Applications.Dialogs.SelectRendering of the Sitecore.Client.dll (or Sitecore.Shell.dll depending upon your version of Sitecore).

First we need to change the PlaceholderName property from an ‘Edit’ to a ‘Listbox’ type:

protected Listbox PlaceholderName { get; set; }

We then loop through our placeholder items and populate the Listbox (view below or on Gist)

 var database = Sitecore.Configuration.Factory.GetDatabase("master");

            var placeHolderItems= database.SelectItems("/sitecore/layout/Placeholder Settings//*[@@templateid='{5C547D4E-7111-4995-95B0-6B561751BF2E}']");

            foreach (var placeholder in placeHolderItems)
                this.PlaceholderName.Controls.Add(new Sitecore.Web.UI.HtmlControls.ListItem
                    Value = placeholder.Name,
                    Header = placeholder.Name

We can now see placeholders as a Droplist:


The Little Book of Sitecore® Tips volume 2 now available

littlebookofsitecore_newsFollowing volume 1 I’m pleased to announce the launch of volume 2 of The Little Book of Sitecore® Tips.

Just like the first book, these tips were created from my daily workings with the Sitecore experience platform and we now have another instalment in the ongoing series.

The main purpose of The Little Book of Sitecore Tips series is a light-hearted look at some useful Sitecore tips. These tips are targeted at all levels of user but whether you’re recapping or learning, I hope you find the material either useful, or of some entertainment value.

Your can order the next volume from the likes of Amazon or Barnes & Noble – The booklittlebookofsitecore_unicorn is also available as an eBook on the iBooks Store.

Thanks is due to the technical reviewers Michael West and Matthew Dresser – and the usual thanks to Tamas Varga who was as helpful as ever. Thanks is also due to Mr Helix Thomas Eldblom, and Dominic Hurst who supplied some nice reviews:


“Einstein once said: ‘The definition of genius is taking the complex and making it simple.’ – and this book does just that. It makes the complex simple and it is simply genius!”

“A must read from an author that doesn’t stop in his quest for learning, sharing and giving back.”


Using EnclosingTag, DisableWebEdit and ShowTitleWhenBlank when rendering fields in Glass

If we’re doing views right we’ll be doing views dumb (or replacing the layout service with JSS). In an ideal world our views would be free from helpers and business logic, they should simply render data from a model. Anybody who has been working with Glass for a while will know that the best way to achieve this is to create an editable field with GlassHtml, we simply pass a HtmlString to our view:

var myField = new HtmlString(_glassHtml.Editable(someitem, f => f.SomeField));

However, when rendering fields using the Sitecore API there are properties available from RenderFieldArgs (such as ‘EnclosingTag’) that Glass doesn’t use when rendering a field.

Fortunately, Glass calls the renderField pipeline when creating an editable field so I created a pull request to ensure we can use the following properties:

EnclosingTag – this is available when using @Html.Sitecore().Field as it is present in the render field pipeline as a field arg (renderFieldArgs.EnclosingTag). This can now be used in Glass to wrap our field in the chosen markup if the field value is not empty. Usage: new { EnclosingTag = “h2”}

DisableWebEdit – previously Glass forced renderFieldArgs.DisableWebEdit to false, this is now made optional with a ‘false’ default. There are instances where we may still want to pass in our field values as HtmlString but not allow it to be an editable field (when using EnclosingTag for example). Usage: new { DisableWebEdit = true }

ShowTitleWhenBlank – while it is possible to force this option across the Sitecore instance, we may still want to achieve this on a per field basis. This option will show a field title in the experience editor if the field is empty.  Usage: new { ShowTitleWhenBlank= “true” }

You can see an example implementation of the Glass features below (or using Gist):

public HtmlString CreateEditableExample()
return new HtmlString(_glassHtml.Editable(item, i => i.SomeField,
EnclosingTag = "h2", // Wrap the field in <h2>
DisableWebEdit = false, // Disable or enable web edit
ShowTitleWhenBlank = "true" // Show the field title if field is empty

This is available from the following pull request so be sure to update your version of Glass and begin (or continue) the good practice of simple view logic 🙂

Resolving workflow permission problems when using Habitat

If like the rest of us you’re a fan of Habitat you may find yourself experimenting with the solution and I wanted to draw attention to potential problems with workflow permissions when modifying the predicates for role serialization. Having disabled the serialization of feature roles:

<include domain=”modules” pattern=”^Feature Accounts .*$” />

I found that users cannot edit any data when workflow is enabled. A quick chat with Mr Eldblom revealed the following:

“This is an example of how to cleanly separate security into the modules. Each feature module has a feature role defined which sets rights on the feature fields. Thereby if a feature is added then users do not automatically get access to the fields in the feature.”

So if you remove serialization of the feature role, you lose the ability to edit content. This is because the permissions are assigned on the template fields:


In order for your editors to modify content you will need to edit these permissions and grant access to the template fields, in my case I removed the restrictions above. Once you update these permissions, the fields that were previously locked will now be editable again.

Hopefully this saves a few headaches.

Automating item unlocks when deleting Sitecore users

Working with a large team of content editors can present us with difficulties, and one of these problems presents itself when we delete a user. If a user has locked items, deleting the user still leaves their items locked.

Sitecore contains a rule /sitecore/system/Settings/Validation Rules/Item Rules/Security/Locked By Non Existing User and we can use this item rule to give us a visual indicator of which items are locked by none existing users. This can be applied globally by adding it to our Global Rules item found at /sitecore/system/Settings/Validation Rules/Global Rules item.

So we can see which items are locked, and as an individual a content editor can unlock their own files by selecting the ribbon option ‘My Items’ and then using ‘Unlock All Items’ which calls the a method in the Sitecore.Shell.Applications.WebEdit.Commands.UnlockAll class. However, this method executes in the context of the current user rather than our non existing user who has locked the items. So while this method isn’t suitable for what we’re looking for, we can use something similar.

Upon deleting users Sitecore calls the user:deleted event so we need to create a handler for this event. You can see this handler being patched in Helix Base, and the source used by the event but below is the source for the handler:

    public class RemovedUserEventHandler
        public void OnUserDeletedUnlockFiles(object sender, EventArgs args)
            if (EventDisabler.IsActive)

            var objList = new List<Item>();
            var userName = Event.ExtractParameter<string>(args, 0);

            Assert.IsNotNullOrEmpty(userName, "User name was null or empty");

            var lockedItems = Client.ContentDatabase.SelectItems($"search://*[@__lock='%{userName}%']");

            if (lockedItems == null || !lockedItems.Any())

            foreach (var lockedItem in lockedItems)
                objList.AddRange(lockedItem.Versions.GetVersions(true).Where(version =>
                    string.Compare(version.Locking.GetOwner(), userName, StringComparison.OrdinalIgnoreCase) == 0));

            ProgressBox.Execute(nameof(RemovedUserEventHandler), "Unlocking items", "Network/16x16/lock.png",
                UnlockAllItems, "lockeditems:refresh", Context.User, objList);

            SheerResponse.Alert($"Successfully unlocked {objList.Count} item(s) checked out by {userName}",

        private static void UnlockAllItems(params object[] parameters)
            Assert.ArgumentNotNull(parameters, nameof(parameters));

            if (!(parameters[0] is List<Item> parameter))

            var job = Context.Job;

            if (job != null)
                job.Status.Total = parameter.Count;

            foreach (var lockedItem in parameter)
                job?.Status.Messages.Add(Translate.Text("Unlocking {0}", (object)lockedItem.Paths.ContentPath));
                if (job != null)

Which we then patch in to the event:

      <event name="user:deleted">
        <handler type="Helixbase.Feature.ItemUnlock.Events.RemovedUserEventHandler, Helixbase.Feature.ItemUnlock" method="OnUserDeletedUnlockFiles" />

Upon deleting users, you should now see their files automatically unlocked.

You can also find this source on GitHub Gist.

Edit… since writing this blog post Michael West has created a useful script for SPE to transfer ownership from one user to another. This can be used in situations where you wish to maintain a record of a previous users locked items.