This post describes a complete method for storing settings in Teamcity to avoid any committing them to Github. Settings will be merged into a separate settings file, referenced from web.config, both during Teamcity builds AND, through a Powershell script, also for developing locally.

Don’t store your passwords, keys, connectionstrings etc. in public

By now, everyone should be aware that it is a terrible idea to store secrets in cloud services, such as Github etc.. As descibed by many articles, a simple search on Github, reveals many secrets that should not be available publicly. And you never know when your private repo might be made public or when a colleague makes a mistake and pushes your private RSA key in a web.config in your code.

Find a private place for storage

You need to find a private place, preferable hosted on-site, behind thick firewalls and layers of security, to store your secrets. We were already using Teamcity to build, test and deploy a .net framework solution. So we want to utilize this to store our secret settings and merge them into the config during the build process. Teamcity also has a REST API that makes it possible to fetch the settings to use outside Teamcity, which we will need.

A solution for both Teamcity builds and local development

We need the settings to be available both during the Teamcity build for merging into the settings file, but also locally where we need to run the code during development. And during local development we want to be able to test out settings for different environments also.

Locally we typically build the code through Visual Studio, which through nugets such as SlowCheetah, has support for merging configs from different environments on build. But there are a couple of issues, such as the configs needs to be committed to Github, which we don’t want, and for web projects, such as mine, merging only happens on deploy or package, not on build. So we need a different approach.

Using the ‘file’ reference in appsettings

For developing locally we need to remember that we cannot store the settings in web.config, as this file is checked into Github. So instead we are making use of the “file” reference feature in .net config files. This enables us to store the secret settings in a different file, and NOT check that file into Github. Note that the ‘file’ reference differs from the ‘configsource’ reference as described here. This is important, because when using the ‘configsource’ reference, ALL of your settings must be in the referenced file, which is not the case with the ‘file’ reference. We only want to store secret settings in the referenced file, to not make life too difficult for developers.

Using Powershell to fetch settings and creating the settings file for local development

We will create a powershell script that takes an environment argument, and based on that, calls the Teamcity REST API, to fetch the settings. Then the script will create the secret settings file, referenced from the solution web.config. Every developer can then use that Powershell script to create settings for whatever environment he needs to test.

Using Teamcity Powershell buildstep to creating the settings file for Teamcity build

For the Teamcity build process, we will create a Powershellscript to be run in a Teamcity build step. This script will take the settings a environment parameters from teamcity and create the secret settings file so it is available for deployment with the rest of the build code.

The finished solution

Here is how I implemented the solution.

Teamcity configuration

We need to do 2 things in Teamcity.

1: Add the secret settings

Navigate to your build confguration and add your secret settings as ‘Configuration Parameters’. I am are prefixing the settings with “SecretAppSetting”, for later use.

Teamcity Parameters

Add your secret settings as Configuration Parameters

2: Setup a build step to create the settings file

Next, add a build step to run the Powershell script, you will create for this purpose below. Note that I am adding the Teamcity parameter “” which I will need later in the script, to determine where to save the settings file.

Teamcity Buildstep

Create a buildstep to run a Powershell script

Powershell script for Teamcity

Next I create the Powershell script to run in Teamcity to create the secret settings file. Note that the “Param” section in the first line, takes the arguments the we passed in the Teamcity buildstep, including the path for where Teamcity has checked out the files from Github. Using this information the scripts creates the settings file on disk, so that it will be available for the building and packaging in a later buildstep.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

Function CreateAppSetting {
  param([string]$key,[string]$value )
    $addElement = $doc.CreateElement("add");
    $addElement.SetAttribute("key", $key);
    $addElement.SetAttribute("value", $value);

$secretAppSettingsConfig = $checkoutDir + "\src\SecretAppSettings.config"
# Create the secret settings file
"<appSettings/>" | Out-File $secretAppSettingsConfig

$doc = [Xml](Get-Content $secretAppSettingsConfig)

CreateAppSetting 'MySecretSettingName1' $SecretSetting1
CreateAppSetting 'MySecretSettingName2' $SecretSetting2


Powershell script for developing locally

Next we need to create a different Powershell script to use locally on the developers computers to create local settings for development.

There is a couple of things to note. The line “$ParentFolder = Split-Path -Path $PSScriptRoot -Parent” is there to find out where to generate the settings file. This is a way to do that, which works in both Powershell editors and commandline (as opposed to dotting your way throughm that does note work the same in all places).

My Teamcity server is login protected, so there needs to be a “httpAuth” in the url and note that Teamcity is case-sensitive toward that argument… (that took some time to figure out!).

The line “$teamcityCredentials = Get-Credential -Message “Enter your TEAMCITY credentials (not your AD login)” prompts the user for credentials with a windows box that masks the input, which is better than writing it in clear text in a commandline.

And in the end, the scripts finds all Teamcity settings that prefixed with “SecretAppSetting.” and adds them as app settings.

So the idea is that the developers calls the Powershell script with an environment argument to generate settings for that environment.

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# Find the path where the script is executed to figure out where to generate the settings file
$ParentFolder = Split-Path -Path $PSScriptRoot -Parent
$secretAppSettingsConfig = $ParentFolder + "\SecretAppSettings.config"

        Write-Host "debug" -ForegroundColor "Yellow"
        $url = 'https://teamcityServer/httpAuth/app/rest/buildTypes/id:DebugStoresSettingsForLocalBuild/parameters'
        Write-Host "test" -ForegroundColor "Yellow"
        $url = 'https://teamcityServer/httpAuth/app/rest/buildTypes/id:BuildAndDeployTestBranch/parameters'
        Write-Host "prod" -ForegroundColor "Yellow"
        $url = 'https://teamcityServer/httpAuth/app/rest/buildTypes/id:BuildProd/parameters'
        Write-Host "Invalid or no environment in args. Usage: CreateLocalSettings <environment>" -ForegroundColor "Red"
        Write-Host "Valid environments: debug, test, vendor, preprod, prod" -ForegroundColor "Red"
        Break Script

Write-Host "Enter your TEAMCITY login (not your AD login)..." -ForegroundColor "Yellow"
$teamcityCredentials = Get-Credential -Message "Enter your TEAMCITY credentials (not your AD login)"

Write-Host "Calling teamcity to get settings..."
    $response = Invoke-RestMethod -Method GET -Credential $teamcityCredentials -Uri $url
   Write-Host $_ -fore green
   echo "Check teamcity connection or your credentials"
   Break Script

# clean out old values
"<appSettings/>" | Out-File $secretAppSettingsConfig

# read the cleaned xml doc
$doc = [Xml](Get-Content $secretAppSettingsConfig)

[bool]$settingsFound = $false;

echo "Setting values..."
# This loop finds all setting prefixed with "SecretAppSetting." and adds them as app settings
foreach ($setting in $ {
    if($ -like "SecretAppSetting.*"){        
        $settingName = ($,17);
        Write-Host "Found setting:" $settingName;
        $addElement = $doc.CreateElement("add");
        $addElement.SetAttribute("key", $settingName);
        $addElement.SetAttribute("value", $setting.value);
        $temp = $doc.SelectSingleNode("//appSettings").AppendChild($addElement);        
        $settingsFound = $true;

    Write-Host "saving file at:" $secretAppSettingsConfig -ForegroundColor "Green"
    Write-Host "Done!" -ForegroundColor "Green"
    Write-Host "No settings found!" -ForegroundColor "Red"

Changes in the .net solution

I need to make sure that the secret settings file is included in the solution as “content” so  that it is included in the packaging a deployment in Teamcity, as I am using a Visuai Studio buildstep in Teamcity. However it should NEVER be comitted to Github (More on that below).

Include Secret Settings file

Include Secret Settings file

Then I need to reference the file in web.config

Reference secret settings file

Reference secret settings file

Changes in Git/Github

Lastly, I need to make sure that the secret settings file is added to the .gitignore file, so that the file is never added to the Github repository.

Change passwords

If you already have had your connectionstrings, keys or any other secret setting added to a web.config or any other file in your Git repo, you need to remove all traces of it or change your passwords/keys etc.

Note that it is the nature of Git to keep all old commits so it is NOT a trivial task to get rid of all the old commits. It is easier to change your passwords for fresh ones.


During planning of a large migration for a customer, we needed to know what components was actually in use on certain types of pages. I chose to use Sitecore Powershell Extensions to extract that data.

You can find Sitecore Powershell Extensions here:

Sitecore Powershell script to list Renderings

The components mentioned above was included on “article” pages through renderings, so what I needed to was create a script that looped through all pages of template type “article” and picked out all the items in “final renderings”.

I wanted to output this to a comma separated file where its easy to filter and sort on the data on the fly in excel.

Here is the script I ended up with:

write-host 'Running script...'
Set-Location master:\content #this was nessesary in my case, because the original "home" item was deleted and SPE had a bug (now fixed)
$pages = get-item master:\content\MySite\articles | get-childitem -Recurse | where-object { $_.TemplateName -match "Article" }
$device = Get-LayoutDevice -Default
$Results = @();
$DataPath = "C:\MySite\ComponentsInUse.csv"

foreach($page in $pages){

    $renderings = Get-Rendering -Item $page -Device $device -FinalLayout

    foreach($rendering in $renderings){

        if($rendering.ItemID -ne $null)
            $renderingItem = Get-Item master: -ID $rendering.ItemID
            if($renderingItem -ne $null)
                $Properties = @{
                    RenderingItemName = $renderingItem.Name
                    RenderingItemID = $renderingItem.ID
                    RenderingItemPath = $renderingItem.Paths.Path
                    UsedOnPage = $page.Name
                    UsedOnPageID = $page.ID
                    UsedOnPagePath = $page.Paths.Path

                $Results += New-Object psobject -Property $Properties


$Results | Select-Object RenderingItemName,RenderingItemID,RenderingItemPath,UsedOnPage,UsedOnPageID,UsedOnPagePath | Export-Csv -notypeinformation -Path $DataPath

write-host 'Script ended'

Useful Sitecore Powershell Extensions links

You can find a lot more useful Sitecore Powershell Extensions information on Adam Najmanowicz blog:

Thanks to Bill Dinger for this post:

Sitecore error: The item “/sitecore/content/Applications/WebEdit/WebEdit Texts” was not found. It may have been deleted by another user.

This is one of the more difficult errors I have had to pinpoint, so I hope this blogpost will help whoever might experience the same issue. Below is a screenshot of the error I got:

Webedit text not found

The stacktrace of the error

The above error message was suddenly starting to get thrown from Sitecore out of the blue, everytime I tried to edit a page in the experience editor.

I had not edited any code even remotely related to this and the item that is mentioned in the error message, was there. And everything was still working for the other members of my team. The error seemed to be isolated to my local enviroment.

After rebuilding the solution, rebuilding indexes, checking all of the code mentioned in the stacktrace, deleting everything and starting over, copying a solution from a collegue, checking .NET versions, IIS settings, etc. I was quite at a loss of what to do.


Chrome’s caching seems to be the culprit

A collegue suggested trying a different browser, than the Chrome I always use, even though this clearly is a serverside error, right?! I fired up firefox, and everything worked fine… So the error was localized to Chrome. I then deleted all the cache from Chrome, and the error disappeared.

Too much caching...

Grumpy cat goes smashing

The conclusion of all this shenanigans seems to be that Chrome’s caching algoritms might be too aggressive when using the Experience Editor.

Clear your browser cache!

Sitecore’s implementation of MVC

Sitecore’s implementation of .NET MVC is sometimes a bit quirky. Every now and then, I run into some strange behavior, such as this example. This I have met before, but a colleague of mine presented me with a very nice solution, which i wanted to share.

A submit to a Sitecore controller hits all methods

As i’m sure many Sitecore developers that uses MVC has experienced, if you have a submit button on a page, Sitecore calls all the public methods that returns an ActionResult, which of course can have unfortunate consequences and is a strange behavior to begin with.

There are some ways to mitigate this, such as wrapping the button in a Html.BeginForm and passing the controller name and desired method to hit along like this:

@using (Html.BeginForm("MyController", "MyActionResultMethod"))
  <input type="submit" value="Confirm" />

However, this causes Sitecore to only return the rendered output from the view that the controller returns. So if your controller only is responsible for a small part on the entire page, you only get the output from that controller. This is another strange behavior from Sitecore’s MVC implementation.

Implement a custom ActionNameSelectorAttribute

A colleague of mine at Pentia showed me a elegant solution, implementing a custom ActionNameSelectorAttribute. This allows me to map the ‘name’ attribute of the submit button to an ActionResult method name. This way I no longer need to specify the method name in the BeginForm, which means Sitecore now returns the entire page as intended. The code looks like this:

using System.Reflection;
using System.Web.Mvc;
public class HttpParamActionAttribute : ActionNameSelectorAttribute
  public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
      return true;

    var request = controllerContext.RequestContext.HttpContext.Request;
    return request[methodInfo.Name] != null;

Now you need to add the name of the ActionResult method in your controller to the ‘name attribute of your button:

@using (Html.BeginForm())
  <input type="submit" name="MySubmitMethod" value="Confirm" />

And finally, your add the new attribute to your ActionResult method:

public ActionResult MySubmitMethod(…)

A nice solution to a quirky problem. Luckily Sitecore is reworking the MVC implementation. Hopefully it will be a bit more straight forward.

How many servers do I need to run Sitecore?

Warning: This post contains no code. But it does have very useful information for estimating Sitecore server setup size! 😉

The question above is frequently asked in a new Sitecore project. (Actually, if it isn’t, you should be worried). And there is no easy answer. It’s a bit like asking: “How big a house do I need?”.

The answer to both questions is “That depends”. (and no one is any wiser). Below I’ll list some of the things you need to consider, when trying to decide what kind and how big of a server setup you need. This won’t answer your question, but leave you with many more. However if you try to find some answers for those questions, you will be a lot better qualified for estimating your Sitecore server setup.

I will also provide a real world story to showcase a server setup that works for Sitecore and one that does not.

Sitecore’s minimum server setup

A while back I was starting up a new Sitecore project for a smaller client. They had a very tight budget and wanted real world advise for a minimum Sitecore Server Setup. They came from an older 6.0 Sitecore version with 1 Content Delivery Server (CD), 1 Content Management Server (CM) and 1 MSSQL server. 3 machines to run their (small) corporate website. There was also an integration to an older Dynamics AX server, containing ERM/CRM data. The client had around 5000 users, logging into the site 1-2 times a month (so quite a small site). The new site was a complete greenfield project (i.e. start from scratch) on Sitecore 8.0 (complete with Mongo, Solr, Analytics, etc.), and a reworked integration to Dynamics AX.

I asked around my colleagues at Pentia, to find some official recommendations from Sitecore or from other project we did at Pentia. And every time I asked the question, the answer was “That depends”, which of course it does. Part of the problem was that pretty much no one had done a Sitecore 8.0 project at that time and Sitecore 8.0 was a big change to Sitecore from previous versions. However, my colleague Thomas Stern (, had gone through the same ordeal and had pieced together this diagram during meetings at Sitecore:


Sitecore minimum server setup

Sitecore minimum server setup


10 servers. 10. Sitecore recommends 10 servers to run a small business site. That would be a complete no-go for the client, which was used to having 3 servers to run their site. Granted, Sitecore has become a much larger beast in the later years and targets much larger clients now. But smaller clients, like this example, still exists and has bought a Sitecore license, which gives them access to newer Sitecore versions too. I think Sitecore might have forgotten that, in these recommendations.


My minimum Sitecore Server setup recommendations

So I set out to create our own minimum Sitecore server setup recommendations for this small type of client. I considered the following things, which you also should do, when planning your server setup:

  • The amount of users and page hits
    • The most obvious parameter when estimating server needs is how many page hits are you going to have. And this is quite important. So try to find out some how. If you have an old site, run some statistics for a while. If not, do some sort of analysis.
  • Proper, fast performing, well thought out code.
    • Even if you do not have that many page hits, you can still get a badly performing site. This is often due to bad code, which is very common. Your developer needs to know the pitfalls of Sitecore and how to avoid them, to do a properly performing site.
    • At Pentia we have done Sitecore development since Sitecore was created. And since Sitecore was created at Pentia, we know a lot about Sitecore! We know what not to do when coding Sitecore and what the pitfalls are. Therefor I know that our code will be very well tailored for Sitecore and perform well. This means that the client can do with less CD servers and less CM servers.
  • Downtime
    • The client  would be OK with brief periods of downtime during deployments and upgrades. This means that having a single CD server would be an option. Having 2 CD servers would enable you to take 1 server down for an upgrade while the site would still be running. Having only 1 server, saves cost, but means that the site will be down during upgrades. Some clients (mainly smaller clients) are perfectly OK with this.
    • The triple redundant Mongo server setup is way, way overkill for a small client. Yes, Mongo needs 3 servers to be able to do upgrades and restoring without downtime, but smaller clients may not need 100% uptime, if it means saving 2 servers.
  • Amount of usage of Solr Search
    • If the site in question don’t use search very much, you might not need a standalone Solr server. The site in question did you search a bit, but has so few users, that it does not really justify a standalone Solr server. However, if your site uses search or filtering on searches a lot, you might need a standalone Solr server.
  • Amount of use of Sitecore Reporting and Analytics
    • The client in question was not planning on using Sitecore reporting or analytics much, if at all, to begin with. They might later, but then there is the option of adding a Reporting or Analytics server at that time.
  • Amount of caching and interaction with other systems
    • Oftentimes, interaction with 3rd party services or other systems that provide data or communicate with your site, are able to slow your site down. The user cannot see that your site is waiting for Dynamics AX to finish a webservice call to get data or something similar. To the user, it’s your site that is slow. Therefore you might need to do a lot of caching of data from the 3rd party services and store them on your servers RAM. This directly affects the amount of RAM your server needs.
  • How many editors work simultaneously
    • If you have many editors working at the same time, you might need more than 1 CM server.

There are many more factors to consider and many aspects will be different in your site, but the above points will help you along.

Below is the setup I ended up recommending for this particular client. I kept the server scale (i.e. RAM and CPU) the same.

  • 1 dedicated CD server to serve content to the users
  • 1 SQL server that holds all databases
  • 1 CM server that also doubles as Solr, Reporting server and Analytics server.
  • 1 MongoDB.
My minimum Sitecore server setup

My minimum Sitecore server setup

So we went from a 10 server setup to a 4 server setup, which I’m relieved to see perform just fine, with muscles to spare for even more future users.

A too small Sitecore server setup

After a while, the client decided, by themselves, to try to scale the servers down, in an attempt to save money on hosting. They told their provider to cut the CPU and RAM by half on all servers. We found out, when they called us because the site was down.

This is what a CD server with 2 CPU’s and 7 GB of RAM looks like:


CPU is maxed out

CPU is maxed out

This resulted in a site that either did not respond, timed out or responded in around 50+ seconds on a simple frontpage. You can safely assume that the above 4 server setup, with half the CPU and RAM, is not enough to run a small Sitecore site with normal use of search, reporting and analytics.

Consider cloud hosting

You should also consider using cloud hosting, such as Azure, which the client in question used. The great advantage here is that they are able to add or remove servers extremely fast and throttle the servers up or down as needed. This is extremely versatile and should not be under valued. If your analysis of your hardware needs was wrong, you can relatively easily correct your mistakes in the cloud.

However, it comes with trade offs. Usually, when hosting in Azure, your hosting partner, if you even use one, has no clue what Sitecore is and will be completely unable to help with any Sitecore related tasks. Be it setup of windows services that Sitecore needs, knowing what Sitecore requires or tweaking the server for Sitecore etc. This means that you need to spend time and money on handling these things yourself or pay someone else to do it.

You also don’t necessarily know where in the world your data lives, which can violate local legislation in some countries.

Finally, it can become quite expensive to host a site, and corresponding test and pre-production sites, in the cloud. You absolutely need to do the math on this before you decide.

So, how many servers do you need to run Sitecore?

There are many factors to consider, as you can see. There are no simple answer to this. You need to do an analysis of you needs and your circumstances. Counsel your Sitecore partner and try to come up with an answer that suits your needs.


Serving any content on a non-secure line will slowly kill your business

Google is pushing for all websites to serve all content on a secure connection only, using HTTPS. Google are backing this currently, through up-ranking sites that are running on HTTPS only and downranking sites that are using all or even some HTTP (not secure). Read more about this here.

Sometime during 2016, Google are changing their browser Chrome, to make it harder to achieve the “Green Lock” icon, thereby ensuring higher security. If not all of your content, including scripts, images, adverts etc, is served on HTTPS, you will not get the “Green Lock” icon that users know, that indicates that the site is safe.

These changes translates into: If your website is not running HTTPS only, you will not be at the top of the list in Google searches and your users on Chrome could be scared to use your site.

Expect other browsers such as Edge, Internet explorer or Firefox to implement similar functionality soon.

A green lock icon is what you want

Chrome is going to classify your content in 3 groups: “Secure”, “insecure” and “mixed content”.

Secure means that all of the content on a page is served over a secure connection. This will give your page the pretty green lock icon seen below:

Green Lock Icon

The Green Lock Icon ensures your users that the page is secure


Insecure could mean that there is no https, that there is https but the certificate is invalid or compromised in some way, that there is insecure script from another site loaded on the page which is always blocked by chrome and a few other things. This will result in “The red slashy lock icon of doom” (Google’s own term, I swear!).


This is what your users will see if your connection is not secure


Mixed content means that some of the content is secure but other parts is not. This could be that the text is served on a secure line but the images are not.

An important change that Chrome is bringing is that Mixed Content is now considered unsafe and will not have the Green lock icon, thereby not appearing to be entirely safe. This is important to understand! Websites that might appear OK in Chrome today, might, when Chrome Version 48 is pushed, appear to be unsafe.

Https, but not safe

There is HTTPS, but some content is using HTTP. No Green Lock Icon


Google Chrome version 48 introduces the “Security Panel” which lets the user drill down into where the content is coming from. I will talk about this in a later post, to avoid being too technical in this one.

Why Google are pushing HTTPS

Google are pushing for all websites to use HTTPS for all content, simply to make the World Wide Web a safer place for everyone. As simple as that. The disadvantages of using HTTPS over HTTP, is now so small, that the advantages outweighs the disadvantages.

Advantages of HTTPS

Not using HTTPS means that it is possible to capture and read data sent from a server to a user. For example, this could be the “Session cookie” that the ASP.NET framework, which almost all Microsoft based website uses, could be captured and read by a hacker. This cookie contains a readable key which could enable a hacker to impersonate a user, thereby gaining access to the users information on the website or even allow the hacker to buy items on the users creditcard. Using HTTPS completely eliminates this threat and many others, by encrypting all data, sent to and from the user, including cookies.

There are other advantages, such as it makes it impossible for ISP’s or wifi providers to inject adverts into the datastream, which can look like you are heavily using adverts on your website, even though you might have an entirely advert free site.

Lastly, using HTTPS identifies your website, through the SSL certificate, as actually being your website and not some other site that might have captured the users request.

Disadvantages of HTTPS

The main disadvantages to why not the whole world are already using HTTPS is simple: Performance. There is a performace hit on using HTTPS as the server and the client has to perform a “TLS handshake” and share security information in order to be able to encrypt and decrypt the data. Also the encryption/decryption itself is a slight performace hit.

Most of the performace hit is in the handshake. Once the connection is established, the encryption itself does not have a very large impact. There are ways to fine tune this however.

There a some hard-to-kill myths about using HTTPS, which is debunked here:

HTTPS becomes a requirement for HTML5 features in Chrome

Google Chrome is also going to require HTTPS to allow key HTML5 features to be available to the user and server. Features, such as using the users Camera, Microphone or even location data which many websites already use now to pinpoint the users location on some map oriented service, for example to guide the user to the nearest shop, will require full HTTPS. If your user’s security and privacy or your sites integrity does not convince you to serve HTTPS only, access to HTML5 features will.

How to handle the changes

First of all, don’t panic. Chrome version 48 is available now, but is not being pushed to users yet. So you do have time to create a battle plan.

What you need to do is to identify what changes are needed for your site to be able to run in HTTPS only. If you have a website that is already focusing heavily on security, you might not need to change anything. If you have a very simple site, you might get away with just flipping a HTTPS switch on your webserver.

But most likely you need to do an analysis of your website, to determine what action to take. Get started now, because the change for Chrome is coming and the change for Google search is already in effect.

More information

I will create more blogposts on the subject in the not too distant future, so make sure to subscribe to the blog and follow me on Twitter @Troels79.

For more in-depth information, please have a look at this presentation from Google:


Lately I have been implementing an integration from Sitecore to Axapta to show and create membership data for a client we have at Pentia. The client had their Sitecore site developed by a different consulting firm and they didn’t do a very good job. Hence the client asked us to take over, sort it out and create the Axapta integration into the existing site. It is always a challenge to take over a site developed by someone with a different approach to standards, quality and software development as a whole. Often times you find bits a peaces where you go ‘wtf where they thinking?’…

Setting up a different device to return ajax in Sitecore

Anyway, I had a page displaying a searchresult with a “Show more” button at the bottom. This button did an ajax call to the same url, adding, amongst others, an “ajax=1” query parameter. I then had setup an ‘ajax’ device in Sitecore that picked up that parameter.

Ajax device

Setting up the ajax device. not the querystring parameter


Then I setup a layout with no other content that a contentregion and connected that to the item containing the searchresult. On the searchresult item there’s a ajax-returning control tied up on the ajax device.

Item setup for ajax

Item setup for ajax

This is a method I have used before and it works fine. Only, it didn’t on this site. Here it didn’t return ajax, it returned the entire page again, on the standard layout.

Check your web.config

I spent some time figuring out what was going on here. It seemed that Sitecore did not at all pickup on the querystring and didn’t change the layout. I spoke to my colleague Alan Coates who suggested to write a pipeline processor for debugging the device detection in the “httpRequestBegin” pipeline. Something he did a number of times, on other projects which we took over from other consultant firms. He promised to write a blogpost about it, which I will link to when ready.

Instead I went back to the solution in visual studio and starting searching for device related settings and properties. In the web.config, I found a “device” setting in the website node which was set to the device that it kept returning:

Sitecore Device setting overrides detection

Sitecore Device setting overrides detection



It turns out that this setting overrides Sitecores automatic device detection. After removing this setting, everything works as intended.



Please leave a “Like” and/or use the share buttons, if you found this guide usefull

Sitecore notification bar

A client had a request to have a warning in the page editor when the authors was editing a cloned item.

I wanted to add a bar below the ribbon to do this and found the notification bar which is excatly that. This is what the end result looked like:

Notification bar example

Notification bar example


The getPageEditorNotifications pipeline

To do this you simply do a pipeline processor that hooks into the ‘getPageEditorNotifications’ pipeline which you configure in web.config like this:

  <processor type="CodeBuildPlay.Pipelines.ItemIsCloneWarning, CodeBuildPlay.Cloning"/>

Then you make a public class with method name ‘Process’ that has the ‘Sitecore.Pipelines.GetPageEditorNotifications.GetPageEditorNotificationsArgs’ as an argument, and you are done! Simple!

This is my code:


public void Process(GetPageEditorNotificationsArgs args)
   Item item = args.ContextItem;
   if (item == null)

   if (!item.IsClone)

   string message = "Be aware that this item is a cloned item!";

   PageEditorNotification warning = new PageEditorNotification(message, PageEditorNotificationType.Warning);

      warning.Icon = "Applications/16x16/warning.png";


Read more about the notification bar here:



Please leave a “Like” and/or use the share buttons, if you found this guide usefull.

This is the third post in my series about the Rich Text Editor (RTE) in Sitecore. You can find the first post which is about the basics of setting up the RTE here.

Copy-paste wrecks your day

Now you set up your editor and blocked access to the HTML edit buttons, so you might be thinking that you are safe and the authors cant possibly wreck your site now. Well, they are a ressourceful people those authors and it won’t take them long to figure out that they can copy-paste all kinds of HTML or even word-formatted text into your beautiful W3C compliant website. And having word formatted tags and other shenanigans in your website, definitely does not make it W3C compliant, uniform or maintainable.

Word formatted HTML (It rimes with 'Hell' for a reason)

Word formatted HTML (It rimes with ‘Hell’ for a reason)

Luckily the Rich Text Editor is a powerful tool and comes with mechanics to strip tags when pasting.

How to strip tags automatically

Under the hood of the RTE lies the Telerik RadEditor. This control has a property called “StripFormattingOnPaste” which is described on teleriks website here:

As you can see in the link above, the editor provides many different ways to strip tags. In this example we are going to use the MSWordRemoveAll option, which strips all those nasty word tags.

What NOT to do

Some guides on the internet will tell you that you can simply go into the filesystem in “www\sitecore\shell\Controls\Rich Text Editor” and start changing the markup and scripts of the editor. While this might work, it is NOT the way to do it. These files ships with Sitecore and as such can be overwritten at any time, when you either upgrade sitecore or install a sitecore patch. Generally you should never edit files that ships with Sitecore. In Pentia we live by this rule as we use a component based development approch, creating our custom code in well defined components which is then added ontop of Sitecore. This way we don’t break sitecore and keep the solution able to be updated or patched.

Using the EditorConfiguration class and SetupEditor method

Sitecore supplies a way to configure the editor without changing the files that comes with sitecore. You can extend the ‘Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration’ class and override the ‘SetupEditor’ method, where you can set all the settings you need on the editor. This method is then run everytime the editor is loaded.

To strip all word tags, simply do this:

using Telerik.Web.UI;
using Sitecore.Data.Items;

namespace CodeBuildPlay
  public class RichTextEditorConfiguration : Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration
    public RichTextEditorConfiguration(Item profile)
      : base(profile)

    protected override void SetupEditor()
      Editor.StripFormattingOptions = EditorStripFormattingOptions.MSWordRemoveAll;
      //Set additional properties of the Editor here if needed.

Alas, a caveat

All this applies to the Rich Text Editor. Unfortunately it is still possible to paste html directly into in the page editor in Sitecore. In the wededit version of the Rich Text Field, anything can be pasted and there is no way to strip anything. How Sitecore have missed this, is beyond me, but they confirmed, in a supportcase I opened, that there’s no way around it at the moment.

Text pasted from word in page edit

Text pasted from word in page edit




Please leave a “Like” and/or use the share buttons, if you found this guide usefull

This is the second post in a series about the Rich Text Editor (RTE) in Sitecore. You can find the first post which is about the basics of setting up the RTE here.

Restrict the Authors

So you have now created your own HTML Editor Profile and configured your site to using it. The authors can now no longer press a button to insert those nasty tables and use Comic Sans! Hooray!! Well… they can still switch to HTML mode and insert and edit the raw HTML of the field. So nothing is stopping them from googling their favourite spinning icon inside a table with text in Comic Sans and paste all of it into the HTML.

There are 2 places that the authors have access to the raw HTML. In the bottom of the Rich Text Editor, there is a pane that gives access to the raw HTML.

HTML edit button in editor

The HTML edit button in the Rich Text Editor

And in the Content Editor, just above a rich text field, there’s a link that says “Edit HTML” which does just that.

HTML edit button in the content editor

HTML edit button in the content editor

Configuring HTML access

Luckily Sitecore makes this task easy as it is possible to restrict access to these functions through access rights. This means that you can block HTML edit from your Authors while administrators still can edit HTML.

In the Core database, navigate to ‘/sitecore/system/Field types/Simple Types/Rich Text/Menu’. Here you will find the “Suggest fix” and “Edit HTML” which are shown as links in the Content Editor as seen above. We also want to remove the ‘Suggest fix’ as this function sometimes can break your HTML if you don’t know what you are doing.

Restrict HTML edit and suggest fix In the Content Editor

Restrict HTML edit and suggest fix In the Content Editor

Select the Edit HTML item and open the Access Viewer found in the menu under the Security tab. Here you will see what kind of access rights are assigned. You will need to find out which role your Authors have. Usually it will be the “Author” role, but this usually differs between various sites. Still having the Edit HTML, open the security Editor from the menu.

The Security Editor

The Security Editor

In this case the Authors don’t have any special rights assigned, so we need to select the using the “Select” button in the top left. This opens a pop up window where we can find the Authors role and select it. Then, ensuring that the Authors role is selected in the pane above, click the ‘x’ on the ‘Read’ column beside the Edit HTML item. Then do the same for the ‘Suggest fix’ item.

Remove the Read rights from both items

Remove the Read rights from both items

This fixed the problem in the content editor. Close the security editor and access viewer and navigate to ‘/sitecore/system/Settings/Html Editor Profiles/Rich Text XYZ/WebEdit Buttons/Edit html’ (the path of the profile of your Rich Text Editor), and repeat the process above to remove the Read access rights for the Authors.

Your Authors can now no longer Edit HTML in the Content Editor or in the RTE.

The next article in this series about the Rich Text Editor in Sitecore, will show you how to prevent your Authors from pasting formatted word text, HTML tags etc. directly into the editor, destroying your W3C validated site.


Please leave a “Like” and/or use the share buttons, if you found this guide usefull

Food by Aaberg

Fabulous favorite food from the Aaberg family!

Cooking with Sitecore

Diary of my experience working on great CMS called Sitecore

Visions In Code

Never look back

Cook 4 Passion

Food food fooooood. We love fooooooooood !!!


Sitecore, Digital Marketing, Work, Life and so on...

Down the DLL Rabbit Hole


Arash Sarfehjou

.NET code and tweaks

.NET code and tweaks

The grumpy coder.

.NET code and tweaks

Alan Coates - Sitecore/.NET blog

Pushing Sitecore to the limits and beyond

Laub plus Co

.NET code and tweaks

iStern Blog

A simple Code Blog

Brian Pedersen's Sitecore and .NET Blog

Sitecore, C#, ASP.NET, ASP.NET Core for developers