Thank you for 2020

Despite everything 2020 threw our way, over at Aceik, we certainly had a lot to celebrate in 2020, including: 

  • PARTNERSHIPS: We partnered with a number of new clients including McGrath, RACQ and the Australian National Maritime Museum on some exciting new Sitecore projects. And we owe a huge thank you to our customers for your support throughout this year. We know it has been incredibly trying and we are grateful that you had our backs. THANK YOU! 
  • TEAM GROWTH: Our team and capabilities grew with the addition of 14 incredibly talented individuals including our first Chief Operating Officer/Creative Director, Head of HR and Quality Assurance Lead, to name a few. 
  • RECOGNITION: Sitecore promoted Aceik to their top partner tier, Platinum, named two of our team members Sitecore MVPs and awarded us the Sitecore Experience Award Honorable Mention 2020 for our work with RAA
  • PRODUCT DEVELOPMENT: Last year we launched our new training practice and in 2020, we added 2 new courses to the program, including Creating and Managing Content in Sitecore 10.x and Marketing Foundations for Sitecore 10.x. We wrote a top ranking blog for deploying Sitecore into Kubernetes as well as improving our existing offering – Sitecore Speedy.

Our 2021 plans are equally exciting and we’d love to share a couple with you:

  • Aceik is planning to expand our creative offering in our endeavour to provide our customers with a genuine end-to-end proposition. 
  • A rebrand is on the horizon.
  • Sustainable growth is based on insuring our customer success record. We are planning to continue to grow our team, to enable our growth and offering to our customers. Stay tuned for opportunities to join our team! (reach out to if you would like to work for Aceik).
  • It’s also time to diversify the team and so we’re looking to onboard 3 new pups as office mascots (kidding! But were you still reading?).

I know I say this a lot, but I truly mean it when I say, ‘thank you’. Your support has been invaluable and I’m looking forward to continuing our work together in 2021.


Jason Horne & Aceik team

Season’s Greetings and 2019 Wrap Up

‘Tis the season to be jolly and over at Aceik, we certainly have a lot to celebrate these holidays. What a year 2019 has been! For starters, we celebrated our 5th anniversary. But then we celebrated so much more:


We partnered with a number of new clients including RAA, City of Yarra, RACQ, Chisholm Institute and CMYKHub. Our partnerships with clients like Toyota, CPA, Unisuper and ANZIIF continued with new and exciting projects.

Team Growth

Our team and capabilities grew with the addition of 8 incredibly talented individuals. We added speciality skills in Sitecore Commerce and UX/UI. Aceik also welcomed Tim O’Neill, formerly of digital services agency Reactive and Accenture in an advisory capacity and Nicole Stirling, formerly Sitecore’s Marketing Director to assist with our marketing activities.


Sitecore announced that two of the four Australian Sitecore Technology MVPs were on the Aceik team, Jason Horne and Thomas Tyack.


We organised the first SUGCON event in Australia & New Zealand region and presented at Sitecore User Groups in Melbourne and Queensland.

Product Development

Our development team built two Sitecore modules and we shared these openly with the community. Aceik became a Contentful partner and built a new gym website on this platform. And we wrap up 2019 with the launch of our new training practice. Our first courses will be available from January 2020 and you can sign up here.

What are we getting up to in 2020?

Our 2020 plans are equally exciting and we’d love to share a couple with you:

  • Aceik is aiming to double the number of Sitecore MVPs on our team.
  • Sustainable growth is based on insuring our 100% customer success record. We are planning to continue to grow our team, starting with a new Senior Front End Developer (if you know of anyone who is looking, please let them know that we’re hiring!)

I know I say this a lot, but I truly mean it when I say, ‘thank you’. Your support has been invaluable and I’m looking forward to continuing our work together in 2020.

I wish you and your family and friends a safe and happy holiday.


Jason Horne & Aceik team

Sitecore PaaS and Ansible

Sitecore PaaS and Azure is a good match and the idea is to blend in Ansible for Sitecore PaaS infrastructure set up on Azure and vanilla Site deployment.

Why would you use Ansible? Using Powershell scripts with parameter files is the common approach. Ansible is a very valid alternate approach for organisations who have Ansible in their tech stack already or for those that prefer it over Powershell.

Let’s start with a brief overview of Ansible. Ansible is an automation tool to orchestrate configuration and deployment of software. Ansible is based on agent less architecture by leveraging the SSH daemon. The Ansible playbook is a well defined collection of scripts that defines the work for server configuration and deployment. They are written in YAML and consists of multiple plays each defining the work to be done for a configuration on a managed server. 

Ansible Playbooks help solve the following problems:

  1. Provision of Azure Infrastructure required to run Sitecore and the deployment of Sitecore. Ansible supports the ability to seperate the provision of the infrastructure from the deployment of the Sitecore packages into “roles”. These roles can then be shared between different playbooks essentially allowing for re-use and the configuration of different playbooks for different purposes.
  2. Modularise the environment spin up into tasks/plays instead of one monolithic command doing everything in one go.
  3. By executing a single playbook, all the required tasks are coordinated to be executed to result in a fully operational instance of Sitecore up and running and ready to be customised by the organisations development team

Ansible Playbooks help with workflow between teams:

  1. Provide flexibility for Developers and DevOps teams to work together on separate piece of work to achieve a common goal. A DevOps team can work on the Azure Infrastructure set up and Developers can work on Application set up and vanilla deployment  
  2. Once the environment is provisioned hand it over to Development team for each site to deploy the custom code and configuration on Vanilla site.

Ansible has list of pre-built modules for Azure that can be leveraged for Azure Infrastructure Spin up and deployment. A list is available here  

We have used the azure_rm_deployment module during the setup journey. The best thing I liked about Ansible was the ability to structure the parameters in a clean and organised fashion to ensure future extensibility is maintained. Ansible supports the use of multiple parameter file. This allows for both shared and environment specific parameter files. You will see the example later in the blog. 

All the ARM templates, play books and tasks are source controlled and Ansible tower can be hooked into the Source control of your choice.

This allows/enforces all changes to the templates, play books and tasks to be made locally and then commited to the source control repository using familiar tools. Asnible will then retrieve the lastest versions of these files from source control as the initial step on execution.

This option is more streamlined than having to manually upload the updated files to an online repository like a storage account and have Ansible/Azure access them using URLs.

Below is one of the example of the playbook. The roles mentioned here are just an example. You will need more roles for a complete azure infrastructure and Sitecore deployment 

Note the variables {{ env }} and {{ scname }}. They are passed from the Ansible tower job template into the playbook. This variables needs to be configured in the Extra VARIABLES field as shown below in the example job template. 

The env name is your target environment for which you want to spin up the Sitecore Azure environment. This could be dev, test, regression or production and the site name is the name of your website. This allows you to use same playbook to spin up multiple sites for multiple environment based on the extra variables passed in the job template in Ansible tower. This combination forms the path to the yml file which contains the definition of the parameters, per site, per environment. Below is the snapshot of the variable file structure. 

  • Each role in the Playbook is a Play/Task and the naming convention is fairly self-explanatory. 
  • Each task has a yml file and ARM template (json file). However it is not mandatory to have an ARM template for each of the tasks.
  1. Create the resource group just to have the tasks yml file and no arm template. 

2. Create the Redis Cache resource that will contain both the tasks yml file and the ARM template. 

There are tons of resources available in the Azure ARM template repo to get you started. You can then customize it to suit your projects requirements. Sitecore ARM templates are a good starting point which you can utilize to get some ideas. The idea is that you can grab snippets from these example to form your own ARM template. 

I will be writing more blogs on Azure and Sitecore so stay tuned.

Creating a custom SXA rendering with variants

In this blog post we’ll step through the process of creating a custom SXA rendering with variants.  For this example, we’ll create a rendering that is used to display information about cars.  By using a rendering with variants, we can add a Car rendering to our page, and depending on which variation we choose, we can display it with a different appearance and different fields.  We’ll create a Car rendering with 3 variations:

  • Summary
  • Specifications
  • Full Details


The first thing we need to do is create the template.  Even though some of the variations only display some of the fields, the template will have all of the fields for a car, and the variations will use only the fields they need.


This template was created in /sitecore/templates/Feature/Cars/Car.


The next step is to create the rendering.  Ours was created at /sitecore/layout/Renderings/Feature/Cars/Car.  The rendering should be a Controller Rendering.  Set the Controller (this one has been set to “Car”), and set the Controller Action to “Index”.  Set the Datasource Template to be the template we’ve just created (in this case, /sitecore/templates/Feature/Cars/Car), and the Datasource Location to “query:$site/*[@@name=’Data’]/|*[@@templatename=’Car’]”.  It’s important to set “Editable” to true so that the rendering will be available in the Toolbox.


To make the rendering appear in the toolbox, we need to add it to Available Renderings.  The Available Renderings folder is  found under the Presentation folder of your SXA site.  First add an Available Renderings item under the Available Renderings folder.  In this case, I’ve added one called Cars.  Once you’ve added the Available Renderings item, click “Edit” on the Renderings field, and add your new rendering (“Car”) to the list of renderings.


It doesn’t really matter what you call the Available Renderings item, or which Available Renderings item our rendering is added to, because the Available Renderings item is simply for filtering/organising the rendering in the content tree.  It doesn’t actually determine where it appears in the Toolbox.  The folder structure of where the rendering is located determines this.  For example, because this rendering is at /sitecore/layout/Renderings/Feature/Cars/Car, it will appear in the Toolbox under a new category of “Cars”.


Rendering Variants

This is where we setup the 3 variations of the rendering.  To start off, create a new Variants item called “Car” under the Presentation/Rendering Variants folder of your SXA site. Under that item, create 3 Variant Definition items for each of the variants we need.

When the variants have been added, they can be selected from the Variant dropdown list in the Experience Editor:


Under each of the Variant Definitions, we need to insert the fields to be displayed.  The desired layout of these fields will determine how we add the fields.  The fields can be grouped into sections, and the order and hierarchy of the fields directly matches the order and hierarchy of the HTML elements that get rendered.  This, coupled with the “Css Class” field allows you to have full control over the layout and appearance of the variant.   The beauty of this is that once this initial setup has been done, you can add as many variants to this rendering as you like without having to write any more code at all.

When adding the fields, it is important that the value of the “Field name”  matches the name of the field in the template.

As an example, the Summary variant has been created using this following structure:


The Css Class for the Image field has been set to “col-xs-3”, and the Css Class for the Car Details section has been set to “col-xs-9”.  The Tags for all of these items are using the default of “div”.  This configuration translates to the following HTML:

<div class="component car">
   <div class="component-content">
      <div class="col-xs-3 field-image">
         <img style="margin:0;" src="/-/media/458B8369BE6D40489797D75DDA8BB79D.jpg?h=114&la=en&w=200&hash=641FD08747F050B6AF1779E77E5BF2C24AB2CEC0" alt="" width="200" height="114" />
      <div class="col-xs-9">
         <div class="field-make">Holden</div>
         <div class="field-model">Commodore</div>
         <div class="field-year">2007</div>

And it looks like this:


As an example, we can have a completely different look for the same rendering by selecting the Full Details variant, which has been setup like this:


And it ends up looking like this:


There’s a great article that covers this in more detail at


This section covers the code that needs to be created in your solution.

First add a new Feature module to your solution, then add the following items:


using Sitecore.XA.Foundation.RenderingVariants.Repositories;

namespace YourBusiness.Feature.Cars.Repositories
   public interface ICarRepository : IVariantsRepository


using YourBusiness.Feature.Cars.Modes;
using Sitecore.XA.Foundation.Mvc.Repositories.Base;
using Sitecore.XA.Foundation.RenderingVariants.Repositories;

namespace YourBusiness.Feature.Cars.Repositories
 public class CarRepository : VariantsRepository, ICarRepository
     public override IRenderingModelBase GetModel()
         CarModel model = new CarModel ();
         return model;


No need to add our template fields in this instance

using Sitecore.XA.Foundation.Variants.Abstractions.Models;

namespace YourBusiness.Feature.Cars.Models
   public class CarModel : VariantsRenderingModel


Keep in mind that the controller must inherit from Sitecore.XA.Foundation.Mvc.Controllers.StandardController.  The Standard controller will handle the routing with default action result “Index”, so there’s no need to add our own, although we can override “Index” if we need to.

using YourBusiness.Feature.Cars.Repositories;
using Sitecore.XA.Foundation.Mvc.Controllers;
using Sitecore.XA.Foundation.RenderingVarients.Repositories;

namespace YourBusiness.Feature.Cars.Controllers
   public class CarController: StandardController
       protected ICarRepository CarRespository
       {   get; set;   }

       protected IVariantsRepository VariantsRespository
       {   get;  set;  }

       public CarController(ICarRepository, carRepository, IVariantsRepository variantsRepository)
           this.CarRespository = carRepository;
           this.VariantsRespository = variantsRepository;

       protected object GetVariantsModel()
           return VariantsRespository.GetModel();

       protected override object GetModel()
          return CarRepository.GetModel();


It is important that all SXA components should be wrapped in “component” and “component-content” divs. “Model.Attributes” adds styles from the rendering parameters.

@model YourBusiness.Feature.Cars.Models.CarModel

@if (Model.DataSourceItem != null || Html.Sxa().IsEdit)
   <div class="component-content">
      @if (Model.DataSourceItem == null) 
         foreach (VariantFieldBase variantField in Model.VariantFields) 
            @Html.RenderingVariants().RenderVariant(variantField, Model.Item, Model.RenderingWebEditingParams) 


<?xml version="1.0" encoding="utf-8"?>

<configuration xmlns:patch="" xmlns:set="">
            <configurator type="YourBusiness.Feature.Cars.Pipelines.RegisterCarServices, YourBusiness.Feature.Cars" />



Here we register the dependencies.

using Microsoft.Extensions.DependencyInjection;
using YourBusiness.Feature.Cars.Repositories;
using Sitecore.DependencyInjection;
using Sitecore.XA.Foundation.RenderingVariants.Repositories;

namespace YourBusiness.Feature.Cars.Pipelines
   public class RegisterCarServices : IServicesConfigurator
      public void Configure(IServiceCollection serviceCollection)
         serviceCollection.AddTransient<ICarRepository, CarRepository>();
         serviceCollection.AddTransient<IVariantRepository, VariantRepository>();


SXA Installation Pitfalls

When installing SXA on a fresh Sitecore instance, things will generally go pretty smoothly, however, when installing SXA on an existing Sitecore instance with customisations, it’s not necessarily quite so simple.  Here’s a summary of some of the issues that were encountered when recently installing SXA 1.4 onto a Sitecore 8.2.4 instance.  Hopefully this post will help if you encounter similar issues.

Dependency Injection

In this instance, there was code that was registering dependencies using wildcards.  Specifically, it was adding (among others) assemblies matching the pattern “*.Feature.*”.  This was wrongly picking up SXA assemblies and was giving errors in the Experience Editor like:

Error Rendering Controller: BrowserTitle. Action: Index: Could not create controller: 'BrowserTitle'.

To fix this, the Dependency Injection code was altered to exclude all assemblies matching the pattern “*.XA.*”.


The Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll file packaged in SXA 1.4 is an older version than what is being used throughout the solution we’re updating, so when trying to install the package, the installation failed halfway through. To fix this, the SXA install package was altered using 7-zip to replace the included DLL with the newer version.

Missing Rendering IDs (no null check)

This issue may be specific to this instance, and might be due to invalid data, but it’s worth mentioning, since SXA is not doing a null check and this problem may crop up for you, too.

When viewing a particular page, the following exception was thrown:

Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Source: Sitecore.XA.Feature.Composites
at Sitecore.XA.Feature.Composites.Pipelines.GetXmlBasedLayoutDefinition.InjectCompositeComponents.GetCompositeComponents(XElement layoutXml)
at Sitecore.XA.Feature.Composites.Pipelines.GetXmlBasedLayoutDefinition.InjectCompositeComponents.Process(GetXmlBasedLayoutDefinitionArgs args)

This turned out to be some renderings that had no ID, and SXA wasn’t doing a null check. The specific xmlLayout is shown below:

Editing the raw values and removing the renderings with a null ID fixes this problem.

To check if there were any other pages with this same problem, a small powershell script was written:

$items = Get-ChildItem -Path "master:/sitecore/content/Consumer/Home" -Recurse
foreach($item in $items) {
$renderings = Get-Rendering -Item $item
foreach($rendering in $renderings) {
if($rendering.ItemID -eq $null) {
Write-Host Item: $item.DisplayName $item.ID

Media Library/Project Folder

The SXA installation wants to create its own “Media Library/Project” folder, using a specific ID. If this item with the specific ID doesn’t exist, SXA will fail when creating a Tenant or Site.   Your instance may already have a folder by this name, in which case it will need to be renamed before the SXA installation, then it’s contents moved into the folder created by SXA.

Duplicate Navigation Controllers

For this instance, when adding the SXA navigation rendering to a page, the following exception occurs:

Multiple types were found that match the controller named 'Navigation'. This can happen if the route that services this request ('{*pathInfo}') does not specify namespaces to search for a controller that matches the request.

There may be other similar controllers in your instance where you get the same problem.

Geocoding Australian postcodes

While working on some code that allowed a user to perform a search using only a postcode, I discovered some strange behaviour with the Google Maps API.

According to the Google Maps API documentation (, component filtering allows you to filter by postal_code and country, which would suit this need perfectly. I gave this a try, and upon initial testing, it seemed that this was the solution, however, after further testing, it was found that for some postcodes (specifically, some in NSW and ACT), the geocoding query would return ZERO_RESULTS. Maybe this is because there is an overlap in the 2000 series postcodes ¯\_(ツ)_/¯.

An example of the URL I was using for this is shown below (note that postcode 2022 and country AU will return ZER0_RESULTS):

There are many examples on Stack Overflow of people using this format to search by postcode and claim this to be the solution, but most of them are either from other countries, where this probably isn’t an issue, or they mustn’t have discovered this issue.

According to the Google Maps API documentation, you can use administrative_area (among other fields) to “influence” results, so I tried adding the state to this field, and I found that this made everything work properly. That means that the following URL will geocode the postcode 2022:

The issue I had then was that if the user is searching only using the postcode, I had to find a way to provide the state for that postcode to Google so it could geocode the postcode properly. To do this, I created a function that gives me the state based on a postcode as shown below (although this is not a perfect solution, because new postcodes are added from time to time. Potentially a call to an Australia Post API or similar may work better going forward):

public static string PostcodeToState(int postcode)
var postcodes = new List();
postcodes.AddRange(Enumerable.Range(1000,1000).Select(x => new KeyValuePair("NSW",x)));
postcodes.AddRange(Enumerable.Range(2000, 600).Select(x => new KeyValuePair("NSW", x)));
postcodes.AddRange(Enumerable.Range(2619, 280).Select(x => new KeyValuePair("NSW", x)));
postcodes.AddRange(Enumerable.Range(2921, 79).Select(x => new KeyValuePair("NSW", x)));

postcodes.AddRange(Enumerable.Range(200, 100).Select(x => new KeyValuePair("ACT", x)));
postcodes.AddRange(Enumerable.Range(2600, 19).Select(x => new KeyValuePair("ACT", x)));
postcodes.AddRange(Enumerable.Range(2900, 21).Select(x => new KeyValuePair("ACT", x)));

postcodes.AddRange(Enumerable.Range(3000, 1000).Select(x => new KeyValuePair("VIC", x)));
postcodes.AddRange(Enumerable.Range(8000, 1000).Select(x => new KeyValuePair("VIC", x)));

postcodes.AddRange(Enumerable.Range(4000, 1000).Select(x => new KeyValuePair("QLD", x)));
postcodes.AddRange(Enumerable.Range(9000, 1000).Select(x => new KeyValuePair("QLD", x)));

postcodes.AddRange(Enumerable.Range(5000, 1000).Select(x => new KeyValuePair("SA", x)));

postcodes.AddRange(Enumerable.Range(6000, 798).Select(x => new KeyValuePair("WA", x)));
postcodes.AddRange(Enumerable.Range(6800, 200).Select(x => new KeyValuePair("WA", x)));

postcodes.AddRange(Enumerable.Range(7000, 1000).Select(x => new KeyValuePair("TAS", x)));

postcodes.AddRange(Enumerable.Range(800, 200).Select(x => new KeyValuePair("NT", x)));

postcodes.Add(new KeyValuePair("ACT", 2620));
postcodes.Add(new KeyValuePair("NSW", 3644));
postcodes.Add(new KeyValuePair("NSW", 3707));

return postcodes.Where(x => x.Value == postcode).Select(x => x.Key).FirstOrDefault();


Responsive Images and Sitecore


By February 2018 Australians already spent more than double the amount of time on smartphones than on their desktop1. With the greater variety of devices consumers use to access sites, it’s important to serve images which appropriately cater to those devices.

“Responsive images” describes a technique where an image is served to the browser depending (usually) on the width of the browser window. Desktop browsers would generally receive a larger version of the image with a greater download size, and mobile devices a smaller version better suiting the smaller display size of the device and being quicker to download.

One of our clients has a Sitecore 7.2 site which uses both MVC and legacy code in ASP.NET WebForms. The legacy code had multiple ways of handling image resizing, mostly inline HTML hard coding of dimensions. My aim was to provide a single C# library function that could work both with legacy code and new development and allow consistent results.


In the newer part of the website, the designer had used a JavaScript based image processor which would allow the browser to determine the optimal resolution of the image required and only request an appropriately sized image from the server.

As you can see from the above HTML sample each image tag has multiple URLs in the data-srcset attribute. From this list the JavaScript library determines the optimal size for the image, based on device and browser size, and only requests that version of the image from the server.

Sitecore provides a tool to provide the resized image files based on the request URL and also caches these resized images. We created a helper function that could take a Sitecore image as input and return all of the URLs representing valid image sizes as a delimited string. The valid sizes are determined by a setting in a config file. This return value is used to populate the data-srcset attribute of our img.


Sitecore 7.5 and beyond require a hash code to be added to the URL2 to prevent Denial of Service attacks by making numerous requests for images of various sizes. Because our new helper function now provides a centralised and configurable way to deliver the required URL string, this will be quite easy to change after the upgrade.



Monitoring and Debugging Interaction Processing in Sitecore 9 on Azure PaaS

When configuring a new instance of Sitecore XP or maintaining an existing one, you may encounter a situation where your interactions report shows far fewer interactions than expected.

Where are my interactions?

One possible cause is interaction processing which hasn’t kept up with the interactions being logged on your website. In some cases this can be so slow that it appears collection, processing, and reporting aren’t working at all. Here are a few things you can look at to help you diagnose your issue.


Are interactions being recorded?

SELECT TOP 10 * FROM xdb_collection.Interactions ORDER BY StartDateTime ASC
Run this command in each of your shard databases to see the recent interactions which have been recorded. Compare the interactions being logged with the expected number and frequency of interactions in the environment you’re looking at.


How many interactions are waiting to be processed?

SELECT COUNT(*) FROM xdb_processing_pools.InteractionLiveProcessingPool
This command will indicate the number of interactions waiting to be processed. Monitoring the number of records in this table can give you an indication of the number of new records being created and the number of new interactions which are being queued for processing.
If the number of records is steadily building up, either processing isn’t working or it’s working too slowly to handle the workload.
If you’re collecting interactions but not seeing the size of the live interaction processing pool change at all, there might be an issue with aggregation.

If Analytics reports don’t look quite right, there are some things you can try:

Disable device detection

We encountered an issue with slow processing on a recent project. After logging an issue with Sitecore support, they advised:
Device detection has been known to cause the slowness in rebuilding reporting DB.
Try disabling device detection to determine if this has been impacting the speed of processing.


Check the CPU usage on your processing role

If you’re consistently seeing a high level of activity, you may need to scale your processing instances up or out.

Time for more instances…

Check connection strings

Use the Server Role Configuration Reference to ensure you have the correct settings on each of your servers

Check Application Insights errors

Check in Application Insights for any repeated error messages that might indicate misconfiguration.


That’s more like it!

Helpful links

Changing renderings from rendering parameters to datasource

Recently, for one of our projects, we found that a large number of the client’s renderings were using rendering parameters unnecessarily. In order to allow for personalisation and a better Experience Editor experience, we recommended to the client that they change these renderings to use datasources instead.

The process (which may vary slightly for your instance) went something like this:
For each rendering to be converted:-

  1. Move the related rendering parameters template from its current folder (which in this case was a folder dedicated to rendering parameters) to a more appropriate folder for data item templates.
  2. Make sure that all sub-items are serialised when the template has been moved – I encountered what seems to be a bug with Unicorn, where it doesn’t serialise them. If you get this, you might need to reserialise, or save each sub-item manually.
  3. If the template currently has a name specific to rendering parameters, rename it to something more appropriate.
  4. If required, make sure that the _Standard Values are set.
  5. Where the rest of your site data lives, create a new folder which will be used to store items of the template in question. Set the insert options to add this template.
  6. Change the rendering’s datasource location to be the newly created folder.
  7. Change the rendering to have no rendering parameters template, and instead use a datasource template of the recently moved template.
  8. Remove the “Standard Rendering Parameters” template from the base templates of the new datasource template.
  9. Add a new item to Core DB with the path something like: /content/Applications/WebEdit/Edit Frame Buttons/Signup Form Button/Signup Form
  10. Set Fields for this new item to be a pipe-delimited list of fields that the content editors will need to edit (generally all of them).
  11. In the Visual Studio solution, move the rendering parameters model into the folder where the data items models live, and rename the file and class name if required.
  12. Change the namespace to match the new location.
  13. Inside the controller method (assuming the rendering is a Controller rendering), remove all code that uses the rendering parameters, and instead, set the datasource to be the RenderingContext.Current.Rendering.DataSource.
  14. Change the view using this rendering:
  15. Add a check for if (Model != null), and display a message if in experience editor mode.
  16. Add “using (BeginEditFrame…” and use the path of the folder for the webedit button you added earlier.
  17. Added a check for Sitecore.Foundation.SitecoreExtensions.Extensions.ItemExtensions.IsDerived using a configuration item for the template ID. Display a message if wrong template and skip the rest of the view.
  18. Changed all references to items in the Model be use @Editable(x => x.)


Downgrading Helix modules from Sitecore 8.2 to 7.2

Recently I had to update a Sitecore 7.2 site to use Helix architecture and bring some foundation modules in from a Sitecore 8.2 site.  There were several challenges with this process.  Here’s a few highlights:

Dependency Injection using Castle Windsor

For this site, Castle Windsor was being used for dependency injection.  In the Sitecore 8.2 site, dependencies are registered using a configurator in a .config patch.  This is not supported in Sitecore 7.2, so instead we have to do this in the Application_Start event in global.asax.cs.

In order to be able to use the same DI container throughout the code, I created a singleton container object (ContainerManager.Container):

public static class ContainerManager
   private static IWindsorContainer _container;
   public static IWindsorContainer Container
        if (_container != null) return _container;
        _container = new WindsorContainer();
        return _container;

Then in global.asax.cs, I used that container to register the dependencies:

protected void Application_Start(object sender, EventArgs e)
    _container = ContainerManager.Container;
    _container.Install(new RegisterGlassDependencies());

An example of the installer class for registering dependencies is shown below:

 public class RegisterGlassDependencies : IWindsorInstaller
   public void Install(IWindsorContainer container, IConfigurationStore store)

In order for injected constructor parameters to resolve for Controllers, it is necessary to use a custom controller factory which uses the DI container to resolve the controller. There’s a fair bit of overriding going on, so here it comes.

Code for the controller factory shown below:

public class WindsorControllerFactory : DefaultControllerFactory
       private readonly IWindsorContainer _container;
       public WindsorControllerFactory(IWindsorContainer container)
           _container = container;
       public override void ReleaseController(IController controller)
       public override IController CreateController(RequestContext requestContext,string controllerName)
           Assert.ArgumentNotNull(requestContext, "requestContext");
           Assert.ArgumentNotNull(controllerName, "controllerName");
           Type controllerType = null;
           if (TypeHelper.LooksLikeTypeName(controllerName))
               controllerType = TypeHelper.GetType(controllerName);
           if (controllerType == null)
               controllerType = GetControllerType(
           if (controllerType != null)
               return (IController)_container.Resolve(controllerType);
           return base.CreateController(requestContext, controllerName);

A pipeline was added with an “instead” patch for Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory.  This pipleine scans all assemblies and gets all classes based on IController then registers them with the Containermanager.Container.  Code shown below:

public class InitializeWindsorControllerFactory
       public virtual void Process(ScapiPipelineArgs args)
       protected virtual void SetupControllerFactory(ScapiPipelineArgs args)
           var container = ContainerManager.Container;
           //TODO: don't use hard-coded filter string
           var assemblies = GetAssemblies.GetByFilter("MyAssembly.*").Where(n => !n.FullName.StartsWith("MyAssembly.Service"))
               .Where(a => GetTypes.GetTypesImplementing<IController>(a).Any(x => x.Namespace != null && x.Namespace.StartsWith("MyNamespace")));
           foreach (var assembly in assemblies)
           var controllerFactory = new WindsorControllerFactory(container);
           var scapiSitecoreControllerFactory = new

Another pipeline was added with an “instead” patch for Sitecore.Mvc.Pipelines.Response.GetRenderer.GetControllerRenderer.  This pipeline allows us to use a custom controller renderer, as shown below:

public class GetControllerRenderer : Sitecore.Mvc.Pipelines.Response.GetRenderer.GetControllerRenderer
       protected override Renderer GetRenderer(Rendering rendering, Sitecore.Mvc.Pipelines.Response.GetRenderer.GetRendererArgs args)
           var renderer = base.GetRenderer(rendering, args);
           return !(renderer is ControllerRenderer) ? renderer : new CustomControllerRenderer(renderer as ControllerRenderer);

The custom controller renderer then allows us to use a custom controller runner as shown below:

public sealed class CustomControllerRenderer : ControllerRenderer
       public CustomControllerRenderer(ControllerRenderer renderer)
           ControllerName = renderer.ControllerName;
           ActionName = renderer.ActionName;
       public override void Render(System.IO.TextWriter writer)
           var controllerName = ControllerName;
           var actionName = ActionName;
           if (controllerName.IsWhiteSpaceOrNull() || actionName.IsWhiteSpaceOrNull())
           var controllerRunner = new CustomControllerRunner(controllerName, actionName);
           var value = controllerRunner.Execute();
           if (value.IsEmptyOrNull())

The custom controller runner then creates the controller using our custom controller factory with our DI container as a parameter.  This is our goal. Custom controller runner shown below:

public class CustomControllerRunner : ControllerRunner
       public CustomControllerRunner(string controllerName, string actionName)
           : base(controllerName, actionName)
       { }
       protected override IController CreateController()
           return CreateControllerUsingFactory();
       private IController CreateControllerUsingFactory()
           NeedRelease = true;
           var controllerFactory = new WindsorControllerFactory(ContainerManager.Container);
           return controllerFactory.CreateController(PageContext.Current.RequestContext, ControllerName);

There’s a few layers to it, but we got there in the end.

XUnit Tests

The tests that I moved over from the Sitecore 8.2 site used XUnit.  After moving them over, one of the errors I got in the Sitecore 7.2 site was:

Could not resolve type name: Sitecore.Data.DefaultDatabase, Sitecore.Kernel

To fix this,  for Sitecore versions prior to 8.2 all instances of ‘Sitecore.Data.DefaultDatabase, Sitecore.Kernel’ in the config files should be changed to ‘Sitecore.Data.Database, Sitecore.Kernel’.

One bit I got stuck on for a while was that there was a config file with this string in it that had not yet been added to the solution, but was there on the file system, and that was enough for this error to still be thrown.  It took a file system search for the string to track it down.