Friday, July 31, 2015

Sitecore Experience Profile - Logging Searches aka Internal Keywords

As discussed in my overview on the Sitecore Experience Profile, it is a powerful tool which provides in depth analytics and tracking of users of your Sitecore web site (both anonymous and identified). One interesting feature of the experience profile is the search terms or Internal Keywords. This allows any searches a user makes internally (by any custom searches) appear inside the experience profile.

To register search terms in the experience profile some code will need to be added into your custom search logic.
public void RegisterSearch(string searchterm)
    if (searchterm != null)
        if (IsTrackerEnabled())
            var interaction = Tracker.Current.Session.Interaction;
            interaction.CurrentPage.Register(new PageEventData("Search", new Guid(Items.SearchPageID)) { ItemId = new Guid(Items.SearchPageID), Data = searchterm, DataKey = searchterm, Text = searchterm });

private static bool IsTrackerEnabled()
    return Tracker.IsActive && Tracker.Current.Session != null && Tracker.Current.Session.Interaction != null;

Wednesday, July 29, 2015

Sitecore Experience Profiles How to Identify Users

In my Sitecore Experience Profiles and Identifying Users Overview post I covered the basics of Experience profiles, along with why it's beneficial to have identify users over anonymous users. In this post I will provide the code needed to actually identify the users - this will claim all of their data and assign it to one named profile.

Creating the user

The initial step is to "create" a user and populate some of the base data we know about them. This may be general information (Name and Title), contact details (especially email address) and even a picture. You would generally perform this action when a user is first defined: such as on registration onto your web site, or on submit of a contact form.
// Store visitors details
if (Sitecore.Analytics.Tracker.Current.Contact != null)
    // Email address
    var emailFacet = Tracker.Current.Contact.GetFacet<IContactEmailAddresses>("Emails");

    if (!emailFacet.Entries.Contains("Work Email"))
        IEmailAddress email = emailFacet.Entries.Create("Work Email");
        email.SmtpAddress = txtEmail.Text;
        emailFacet.Preferred = "Work Email";

    // Personal details
    var personalFacet = Tracker.Current.Contact.GetFacet<IContactPersonalInfo>("Personal");
    personalFacet.FirstName = txtFirstName.Text;
    personalFacet.Surname = txtSurname.Text;
    personalFacet.JobTitle = txtRole.Text;
The code above is ensuring there is a current Sitecore analytic tracker and then assigning the details of the user to is. Once this action is complete the user is identified and all of their past/future data (based on cookie/session) is assigned to them.

Identifying a user

If the user visits again in the future, perhaps on a different device, their session will no longer be associated to them. This means that all data will once again be assigned to another anonymous profile, which is no good when you are trying to build the complete picture on a user (their browsing habits, goals reached, campaigns partaken in and so on). Therefore the following code could be run when a user identifies themselves (such as on login).
var identifiers = Sitecore.Analytics.Tracker.Current.Contact.Identifiers;

if (identifiers.IdentificationLevel == ContactIdentificationLevel.Anonymous)
Once this has run, if a match is found, the users data is stored against their experience profile, and the customer insight continues.

Sitecore Experience Profiles and Identifying Users Overview

Sitecore customer experience profiles provide a high level overview of the customer and provide insight into their experiences across all channels which ultimately builds up into a full picture of that customer.

In Sitecore 8 the basic flow for the analytics collection is as follows:

  • The user access the web site (desktop browser).
  • As the users browses the web site (and completes actions) the data profile is building up inside the MongoDB session.
    • If the user is unknown the session is stored against an anonymous user, however if identified the data is stored against a known contact.
  • Once the session ends/expires the data is flushed into the Experience Database where it will be displayed via Experience profiles and Experience Analytics in the Sitecore administration area.

Known users

The ultimate goal here is to create known users which then allows interactions to be tracked across all channels (desktop, mobile, email etc.). A user is generally identified via their email address (which can be gathered from logging in, completing a form or subscribing to a newsletter). 

To create a contact record a call can then be made via code to the Sitecore API to store the visitor's details (it may just be an email address, but can be full contact information and even picture) - all of their data from anonymous browsing is also retained against their new contact record.

On future visits (where the session may have ended or the cookie deleted) you can also identify a user by email address (in code) to ensure all data is stored against their profile and not an anonymous one. 

What can we track?

I like to think of a customer's Experience Profile as a puzzle. There are many pieces of the puzzle which can be used to build up the picture, and like the puzzle you can often make out the whole picture without having all of the pieces. On that note, without going into every piece  available, here are some of the features of the Experience Profile (each contact card):
  • User details (including photo)
  • Visits (as well as each page visited and for how long)
  • Pattern/profile matches
  • Campaigns
  • Downloads
  • Searches


Sitecore is the market leading CMS when it comes to marketing automation and analytics. Just from this quick overview it is evident just how powerful having Experience Profiles of customers can be, especially considering it works on every channel and integrates with Sitecore's marketing activities. Another point to consider is bringing in external information into the profiles from external sources such as CRM.

My follow-up post (Sitecore Experience Profiles How to Identify Users) has the code required to create the users and identify them on subsequent visits.

Monday, July 27, 2015

Windows server 2012 moving the SMTP mailroot folders

By default, the SMTP mailroot folders (badmail, Drop, Pickup and Queue) will be stored on the C drive - C:\inetpub\mailroot to be precise. For the purpose of backups or some other reason, you may have moved inetpub to another drive (D drive for example). To have the local SMTP sever pickup the relocated mailroot folder you will need to follow these steps:
  • Install IIS 6 scripting tools
    • Launch the server manager
    • Click Add roles and features
    • Select Role-based or feature-based installation and select the the current server
    • Expand Web Server (IIS) > Management Tools > IIS 6 Managament Compatability and then check IIS 6 Scripting tools 
    • Click next > Add Features and complete the installation
    • There should now be an AdminScripts folder in the C:\inetpub directory, this will contain adsutil.vbs which is used to update the mailroot folders.
  • Stop the SMTP server (this is done from the IIS 6 Manager)
  • Open up the command prompt in administrator mode and run the following commands - changing the the new folder directories as required:
    • cscript.exe C:\inetpub\AdminScripts\adsutil.vbs set smtpsvc/1/badmaildirectory D:\inetpub\mailroot\Badmail
    • cscript.exe C:\inetpub\AdminScripts\adsutil.vbs set smtpsvc/1/dropdirectory D:\inetpub\mailroot\Drop
    • cscript.exe C:\inetpub\AdminScripts\adsutil.vbs set smtpsvc/1/pickupdirectory D:\inetpub\mailroot\Pickup
    • cscript.exe C:\inetpub\AdminScripts\adsutil.vbs set smtpsvc/1/queuedirectory D:\inetpub\mailroot\Queue
  • Start up the SMTP server again (this is done from the IIS 6 Manager)

Migrating from SharePoint to Sitecore


For use as an external web site (as opposed to an internal intranet) SharePoint has progressed forward since the 2003/2007 versions and has many positive aspects. However, in more advanced areas such as marketing automation, e-commerce and custom data structures (everything is a list) it is lacking and may not be the best solution. Sitecore on the other hand is market leading in these areas (including marketing features), which leads to migrating from SharePoint to Sitecore.

The first step

As with any migration process, the first step you should follow is to identify what type of migration is going to take place. It is this that will affect the scope of the migration, the steps taken and ultimately the plan of action.Some examples of types of migrations are:
  • Like for like migration - in which case, very detailed requirements will need to be created to ensure nothing is missed.
  • New site (reusing majority of old content) - in this case you would create requirements of the new Sitecore site, see which elements (content, code or design) can be migrated from the old SharePoint site and to what level these elements can be migrated.
  • Migration of selected content - this may occur when a greenfields site is being created where some selected content (perhaps product information/history or other list data) is required but nothing else (page templates, widgets and unwanted content).

From the top down

The following list contains common SharePoint elements which are commonly included in an external web site, and what they could be potentially created as in your new Sitecore web site.

Master pages and page layouts - In SharePoint a master page contains the look and feel of the web site (base HTML/style) along with any shared components common across the site (navigation and footer for example). A page layout will contain field controls and web parts which are relevant only to pages using that layout. In Sitecore the master page(s) would be created as a layout(s) and the page layout content could be migrated to sublayouts/renderings which are added to placeholders (both on the layout and inside the sublayouts/renderings themselves). 

Pages - A page in SharePoint uses a page layout to display content - which may be web parts, lists/libraries or HTML blocks. In Sitecore you would simply create a page template (which would contain general fields such as metadata and title etc.). This page template would then contain the required sublayouts/renderings which contain the content of the page (a layout would be used in place of a master page as well).

Web Parts - In SharePoint a web part is essentially a user control which contains front-end and back-end code which performs a given task/action. This web part may also interact with the SharePoint data (lists for example). In Sitecore a sublayout/rendering has a similar concept to a web part, being that it is a user control with front-end/back-end code which can be re-used (multiple times in the same item/page as well). Code can also be re-used when migrating from a web part to sublayout/rendering - just remember that any SharePoint data sources will be replaced as well.

Lists (custom, calendar, announcements, etc.) - When it comes down to it, everything in SharePoint is stored as a list. Whether it be a custom list, or one of the out of the box types, they can be migrated to custom templates in Sitecore. The benefit of custom templates is that there are more data types to choose from, and you can inherit from other templates (so common elements across your SharePoint lists are defined in one template in Sitecore).

Document/Picture libraries (lists) -SharePoint is known for it's document management capabilities, however document/pictures are ultimately stored in a list (with versions). Documents and images can be migrated to the Sitecore media library. The benefit here is that, these images can then be referenced in any other custom templates which means less data replication and easier updating of content.

Workflows - Workflows are another one of the features that SharePoint is well known for. Workflows in Sitecore are very easy to setup and the visual aspects of creating workflows makes it a simple task. There are also several workflows included out of the box which gives a good starting point.

User accounts - Sitecore much like SharePoint have their own accounts built into the CMS, active directory accounts and even custom accounts (stored in database or LDAP for example). There should be no issue using the same source for user accounts when migrating from SharePoint to Sitecore.

Programmatic migrations

There are methods available to migrate content from SharePoint to Sitecore, rather than having to move it manually one item at a time. SharePoint offers a service which can be called from within code, with the data then used to create Sitecore items. This method may require some manual intervention to organize/clean the data as required, but should take care of much of the manual migration process.


Sitecore is the market leading CMS with a lot more available out-of-the-box than SharePoint. When planning your migration, it's a good idea to consider what the best way to implement the business requirements in Sitecore would be, and perhaps what else Sitecore may bring to the table that could exceed requirements delivering a stronger solution that ultimately leads to more engaged users.

Sitecore and custom 404 not found and custom error pages

In Sitecore if an page or other media asset is not found, the user is redirected to the default 404 page.
If you wish to show a custom page instead, there are settings which can be configured in the web.config file. Under the "/configuration/sitecore/settings/setting" element there are two settings which control the behavior of the 404 page:

  • ItemNotFoundUrl - When a URL does not correspond to: a content item or Sitecore media item.
  • LinkItemNotFound - When a link inside a rich text field does not exist, the URL is replaced with this value.
  • LayoutNotFoundUrl - For items which does exist but which has not been assigned a layout.
  • ErrorPage - For any general errors in Sitecore.

Friday, July 24, 2015

Sitecore page editor is showing JSON objects on the page

In Sitecore I noticed that when entering page editor mode, that JSON objects were being output all across the page. It did not happen however when not in page editing mode.

In my case this was occuring because the layout file did not contain a form element with runat set to server. John West discusses this error in detail and provides other potential causes on the Sitecore blog.

Thursday, July 23, 2015

SMTP configuration for mail relay on web server

The following errors can occur on a fresh web server where you are trying to send SMTP email in the code (a contact form for example).

  • No connection could be made because the target machine actively refused it - SMTP server has not been installed on the server. 
    • Open server manager
    • Click manage > Add roles and Features
    • Select role-based or feature based installation
    • Select the local server
    • Select Features from the left menu (not Server Roles)
    • Check the SMTP Server feature
  • Mailbox unavailable. The server response was: 5.7.1 Unable to relay for - because mail relay has not been setup on the server
    • Open the IIS6 Manager
    • Select properties for SMTP Server
    • Select the General tab set the IP address setting to be the servers IP instead of All Unassigned
    • On the Access tab, click the Relay button, then add the server's IP address and
  • Unable to read data from the transport connection: net_io_connectionclosed - the web site in IIS is still trying to connect to a SMTP server.
    • Open IIS Manager
    • Select the web site
    • Under ASP.NET select SMTP E-mail
    • Select the Store e-mail in pickup directory option and set the value to C:\inetpub\mailroot\Pickup
    • On the C:\inetpub\mailroot\Pickup directory give access to the account IIS_IUSRS

IIS error - value does not fall within the expected range

A site was stopped in ISS and when I attempted to start it the error "Value does not fall within the expected range" would occur. This error occurred because one of the bindings somehow contained an invalid character (in this case a space). Fixing up the binding then allowed the site to be started.

Wednesday, July 22, 2015

Migrating from Ektron to Sitecore


A migration from one CMS to another is no simple task, and if not planned and architected correctly it can lead to a poor implementation of the new CMS and even loss of business critical content, features and security. Ektron as a CMS has a relatively simple development pattern, however implementations can vary which means any migration from Ektron to Sitecore will not be one size fits all. This article will cover the key concepts to consider with your migration to Sitecore and perhaps provide a starting point for the planning process. 

The first step

Before you begin the process of migrating from Ektron to Sitecore, you need to define a high level goal/objective of the migration, as this will greatly affect the process/steps taken. Some examples of high level objectives could be:
  • Like for like migration - in which case, very detailed requirements will need to be created to ensure nothing is missed.
  • New site (reusing majority of old content) - in this case you would create requirements of the new Sitecore site, see which elements (content, code or design) can be migrated from the old Ektron site and to what level these elements can be migrated.
  • Migration of selected content - this may occur when a greenfields site is being created where some selected content (perhaps product information/history or other smart form data) is required but nothing else (page templates, widgets and unwanted content). 

From the top down

Here are a list of common components that will make up an Ektron implementation and an overview of what they might be implemented as in Sitecore.

Pagebuilder template - In Ektron a pagebuilder template allows you to create multiple page layouts (which contain various drop zones for widgets) which then use the same master page. When migrating these to Sitecore, you would consider creating a Layout which is effectively the master page (containing the header/footer for example) as well as a number of placeholders that make up the layout of the content (whether it be columns or grid based). If you have multiple unique Ektron pagebuilder templates (such as 1, 2 and 3 column designs), each of these could be a sublayout which contains placeholders in the desired columns.

Widgets - A widget in Ektron is simply a module which can be added to a page and runs independently from all other elements. These migrate very cleanly over to the Sublayout (web forms) or Rendering (MVC) in Sitecore. The Parameters on Sitecore sublayouts are much more well defined than Ektron, and a DataSource can be set on the sublayout (and locked down to content of a specific type). Sublayouts in Sitecore can also contain placeholders/other sublayouts, which is a nice way of adding commonly grouped sublayouts (page heading & breadcrumbs for example) to a page as a single item. For any widgets on the smart desktop (logged in admin area), you could create a page only accessible to users with specific permissions.

Smart Forms - a Smart Form in Ektron is the method of storing user-defined objects in XML. In Sitecore you would create templates of the same/similar structure and also make use of template inheritance for any fields that are common across the data objects. If you need to keep using XSLT to render the data, you would need to serialize the item to XML in code. For those who want to forget about XML storage and XSLT display - you can access the code as an object in the code and even make use of tools such as Glass Mapper to use custom cleaner object classes. For Smart Forms which allow multiple objects on the same form, I would suggest a parent template in Sitecore which holds many children templates (of the actual object type).

Menus, Taxonomies & Collections - These three types of content in Ektron can all be migrated to templates in Sitecore. For Menus and other types which may be based on existing content, you could either add fields to those existing content templates or even navigate the Sitecore content tree and build up the data programmatically. 

Library - The library in Ektron is what contains all the media items and it mimics the folder structure of the content tree. These items would quite simply be migrated to the Sitecore Media Library, where you would have much more control about how the content is stored and exposed. The migration process is also a great time to clean up the content and give it a good folder based structure + relevant naming/metadata. 

Programmatic migrations

For the migration of content from Ektron to Sitecore, there are methods available to migrate the content using code, rather than data entry people endlessly moving it item by item. The Ektron Framework API can be used to access the Ektron content (smartform data, menus, taxonomies, collections and media library) which can then be massaged into Sitecore templates. This method may require some manual intervention to organize/clean the data as required, but should take care of much of the manual migration process.

You can also user crawlers/scrappers to download Ektron library items (PDFs, images, etc.) which can then be uploaded in bulk to the Sitecore Media Library. 


Sitecore is the market leading CMS with a lot more available out-of-the-box than Ektron. When planning your migration, it's a good idea to consider what the best way to implement the business requirements in Sitecore would be, and perhaps what else Sitecore may bring to the table that could exceed requirements delivering a stronger solution that ultimately leads to more engaged users.

Monday, July 13, 2015

JavaScript font resizing with multiple font sizes

Web Content Accessibility Guidelines or WCAG are a set of accessibility guidelines for web sites. One of these guidelines is SC 1.4.4 (Resize text) which requires the text can be resized by up to 200%. For simple web site that contain a single paragraph class and title class, resizing of the font is simple. However modern designs with multiple elements (including headers, footers, main body, along with other widgets) can be difficult to resize as each element likely has a different font size.

The following piece of jQuery will go through the multiple classes input and increase each font to 1.2 times it's current value.
$(".textDiv, .titleDiv, .breadcrumbs").each( function(index){
    $(this).css( {
         "font-size": function(index, value) {
  return parseFloat(value) * 1.2;
If you then wanted a decrease function, simply use the example above but set the size to be 0.8 times the current. The plus of 1.2 and minus of 0.8 is not exactly going to scale, but will work closely enough. It is also worth considering saving the current scaled font setting in a cookie, and then applying it on page load.

Sunday, July 12, 2015

Ektron bundling of JavaScript and CSS

An important aspect of web development is optimizing the final product to ensure it loads in a reasonable amount of time. Slower loading web sites are frustrating to users and can lead to higher bounce rates and less time spent on the site.

One of the simplest ways to optimize a web site for faster loading is to look at the number of HTTP requests. That is the number of files needed to be downloaded to render the web page - this includes images, CSS, JavaScript and any custom fonts.

Built into Ektron is the ability to register CSS or JavaScript in the code behind where it gets combined into a single JavaScript file and CSS file (less HTTP requests) and even is able to minimise it (less file size to download).

To bundle JavaScript in Ektron you can use the following code:
JavaScript.Register(this, "/path/file.js");
To bindle CSS in Ektron you can use the following code:
Css.Register(this, "path/style.css"); 
However there is also an Ektron configuration file called "ektron.cms.framework.ui.config" which is located in the web root which needs to be configured to allow bundling and minification.

  • AllowJavaScriptRegistration - Allows JavaScript to be registered in code behind.
  • AllowJavaScriptAggregation - Will the JavaScript be output (bundled) in a single files.
  • AllowJavaScriptMinification - Will the JavaScript be minified - smaller file size but not as readable.
  • AllowCssRegistration - Allows CSS to be registered in code behind.
  • AllowCssAggregation - Will the CSS be output (bundled) in a single files.
  • AllowCssMinification - Will the CSS be minified - smaller file size but not as readable.
It is also possible to have files not aggregate on a single basis. The Register function takes in a third parameter (bool) which controls if it will aggregate or not.
JavaScript.Register(this, "/path/file.js", false);

Wednesday, July 8, 2015

Internet Explorer doesn't render a web site correctly and goes into Quirks mode

I came across an interesting error with Internet Explorer 9 and a modern web site layout (using bootstrap and jQuery). When loading the web site, the style would render completely wrong (and unusable). 

Pressing F12 and looking at the developer console, revealed that the browser mode was IE9, but document mode was set to Quirks. By default web browsers will attempt to display HTML content to the specification of the W3C, quirks mode is a browsers way of attempting to display older web pages (with older standards of HTML).

However when quirks mode is activated for a web site with newer HTML mark-up it will completely butcher the page, due to the presence of new tags and techniques. From my testing I have found the following factors can cause Internet Explorer to enter quirks mode by default:
  1. Any code/comments before the Doctype element in the HTML. The doctype tag "<!doctype html>" should always be the first element on a page.
  2. The following tag should be the first item in your head section, as it basically tells the browser the HTML is up to a given standard.
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>

Sunday, July 5, 2015

Ektron web alerts aren't sending

If you have setup web alerts in your Ektron web site, have updated content with as assigned subscription (that has a user subscribed) and yet to email is generated, it may be due to one/all of these issues.

The main installation for web alerts can be found at: "C:\Program Files (x86)\Ektron\CMS400v91\Utilities\WebAlerts.exe".

  1. On the web alerts tab of the content, ensure that a complete email is being built up. This includes the following elements:
    1. From email address
    2. Subject
    3. Opt out/unsubscribe message
    4. Actual content (message, content link, etc.)
  2. Ensure the Ektron async processor service is running
    1. This can be installed from "C:\Program Files (x86)\Ektron\CMS400v91\EktronAsyncProcessor_Service"
  3. Ensure you have a private queue created named "msmq_web"
  4. The SMTP details for sending of web alerts is not in web.config it is in the config available in "C:\Program Files (x86)\Ektron\CMS400v91\EktronAsyncProcessor_Service"
  5. Disable "Staging Server" on the main site configuration in the workarea.
Ektron 9.1 documentation on web alerts found here.