Taxonomy

Sitecore 8 Marketing Taxonomies

The release of Sitecore 8 has seen a slurry of new features and capabilities added to the new platform, all of which shine for attention. Features like the Federated Experience Manager, new Analytics Suite, Test Everything approach, and test gamification all add to the marketers arsenal of tools.

However with all these new features, some of the more subtle important changes may have been overlooked. This post looks at one of those, namely the addition of new marketing taxonomies and the new ‘Outcomes’ feature.

Taxonomy (from Greek taxis meaning arrangement or division and nomos meaning law) is the science of classification according to a pre-determined system, with the resulting catalog used to provide a conceptual framework for discussion, analysis, or information retrieval

It’s easy for us developers to often think marketers only run one or two campaigns at a time, making them easy to manage. The reality though is that marketers are often running lots of campaigns, all spanning different channels and audiences, each needing to be reported on. Prior to Sitecore 8, marketers could include a ‘type’ whenadding new campaigns, however this was a free text field and wasn’t particularly useful in reality. Campaigns were also attributed a ‘Traffic Type’, which held the method by which a user visited the campaign (direct, via branded keyword etc). Again this was useful, but relatively limited.

Sitecore 8 introduces a slew of new taxonomy methods to help categorise and manage campaigns. These are found under the Marketing Control Panel (formerly Marketing Center).

Overall

Campaign Group

A Campaign Group provides the ability to group campaigns into relevant groups, which provides the ability to report on performance of a group of campaigns under a particular umbrella. For instance, if you are running multiple campaigns around a particular event, such as ‘Digital Trendspot’, then you can attribute all the relevant campaigns into a ‘Digital Trendspot’ Campaign Group.

Campaign Group

Warn

Channel

Channel is a direct replacement for the ‘Traffic Type’ attribute in previous Sitecore versions, however it adds more flexibility over Traffic Types.  Expanding the list of Channels will show you an exhaustive prepopulated list, covering both online, and crucially, offline channels as well.

Channels

As before, new campaigns can be attributed to a channel, which denotes the expected channel that the user will visit the campaign on. Of course, a campaign earmarked for a banner ad or ad network, could feasibly be tweeted and so also drive some traffic from Social networks. To capture this, Sitecore will capture both the intended channel (i.e. the channel attributed  to the campaign), and the actual channel for the user. Using these two fields, marketers can then see how campaigns are communicated through other channels than the originally intended channel.

Assets

A Marketing Asset is typically any marketing content that is used to educate and create interest for a company’s product or services (look out for my forthcoming blog post around terminology differences between marketers and developers). These usually take the form of white paper downloads or pdf’s, could be anything the marketer wishes to use.

Assets

Sitecore 8 now provides the ability to explicitly add marketing assets and attribute them to campaigns. The Asset taxonomy follows the Campaign Groups taxonomy, in that you can create an Asset Group containing many assets. For instance, and Asset Group might be FAQ’s around your products or services, which will then contain the actual FAQ assets.

Campaign, Asset, and Goal Facets

One of my very favourite things about Sitecore is it’s absolute extensibility and flexibility. No one platform can ever provide every feature requirement of a business, and Sitecore recognises this by providing all the mechanisms necessary to easily add your own features and content, all leveraging the underlying capabilities of the platform. Facets extend this idea into the marketing realm, and are essentially there to provide further means to categorise campaigns, Goals, and Assets by ways applicable to your business.

Facets

To use these, you simply rename the applicable facet to whatever you need, and then select it in the applicable field within your Campaign, Goal, or Asset. For instance, you might require Campaign Facets that denotes a Cost Centre. To do this, unprotect one of the ‘Campaing Facet’ items and rename to ‘EMEA’. Then select your campaign and under ‘Campaign Facet 1’ (or applicable number), choose your new Campaign Facet.

Outcomes

Lastly, Sitecore 8 has added a new way to group goals, or provide a hierarchy to user actions, through the ‘Outcomes’ feature. Outcomes are intended to specify a final outcome for the visitor, which may consist of many goals before achieving that outcome. For instance, a user purchase may be an outcome. To purchase a product, a user may trigger several goals along the path.

Outcomes

Using Outcomes will give more ways to analyse traffic (and/or base personalisation on) through tools such as the Path Analyzer and Experience Analytics.

Sitecore DMS: Register a Goal Against Any Page

This is a quick tip for allowing a single service (Web Api Controller, MVC Route etc) to programmatically register goals against any page.

Typically when using the Sitecore DMS to register goals through code, the most common approach is to use the Tracker class to register a goal on the current page, as such;

        //Create the record that needs to be stored (the goal)
        VisitorDataSet.PageEventsRow pageEventsRow = Tracker.CurrentPage.Register(goal);

        //Add any data you like, which will be stored with the PageEvent
        pageEventsRow.Data = eventMessage;
        pageEventsRow.ItemId = goalItem.ID.ToGuid();

        //Submit the goal
        Tracker.Submit();

The issue with this is that it registers a goal against the current page only.

In some scenarios you may wish to register goals against other pages. For instance if you would like to set up a generic MVC/Web API route to register a goal from client side, accepting any page.

To do this, you can use the PagesRow class (the class type for the Tracker.CurrentPage object) from the VisitorDataSet to register the goal.

       //Getting the current page into PagesRow 
        VisitorDataSet.PagesRow page = Tracker.Visitor.CurrentVisit.CurrentPage;

        //Override items as required
        page.ItemId = tmpItemId.ToGuid();
        page.PageId = tmpItemId.ToGuid();
        page.Url = "/Articles/Custom-Field-for-Task-Schedule";

        var pageEventData = new PageEventData(goalName)
        {

               ItemId = tmpItemId.ToGuid(),
               DataKey = goalName,
               Data = "/Articles/Custom-Field-for-Task-Schedule",
               Text = targetItem.Name
        };

        //Register via page
        page.Register(pageEventData);

This example uses the CurrentPage object to instantiate a PagesRow object, which is then overridden with the required values. I then create a standard MVC route to this method. My example looks like this;

     routes.MapRoute(
            "RecordGoal", // Route name
            "rest/goal/{goalName}/{itemId}", // URL with parameters
            new
            {
                action = "RecordGoal",
                controller = "MarkettingService",
            });

I can now call this route from any page client side, and simply pass the goal name and the page I wish to register it against. Now in the Latest Visits report, I can see my goal recorded against the correct page:

Analytics Report

Sitecore: Grouping Publishing Targets

This post is to provide a simple tool to cover an admittedly rare scenario, or at least currently rare. This scenario came about after working with a global Sitecore customer to design an architecture that covered the customers global footprint. The architecture allowed for multiple Content Delivery (CD) servers within each region for availability/redundancy purposes.

World Architecture

When designing this architecture, it became evident that there would be lots of different publishing targets created, which would become an annoyance to Content Editors, and also bring about the possibility of publishing targets being left unchecked. Editors in Asia however still needed to be able to publish to the Asian CD’s and not necessarily to other CD servers. With the above, the publishing dialog looked something like this;

Publish Dialog Before

The simple solution to this is to allow grouping of the publishing targets into logical groups, such as Asia; Europe; US etc. To achieve this is easy, and involved the following steps;

  1. Create a new template type to represent Publishing Groups. This contains a single multi-list for selecting publishing targets that it will represent.
  2. Create a folder to contain your publishing groups.
  3. Create the groups that you want to use, and add the relevant publishing targets into each.
  4. Override the ‘Publish.xml’ dialog to add in a new frame for publish groups
  5. Create your own class to sit behind the dialog form;
  6. Where publishing groups exist, then use those in place of publishing targets, else use Publishing Targets in the normal way

In the infamous words of Blue Peter, here is one I have made earlier: https://marketplace.sitecore.net/Modules/Sitecore_Publishing_Target_Groups.aspx

You can also find the source here: https://github.com/brooksyd2/sitecorepublishgroups

Once installed, this module will allow you to set up publishing groups to represent many publishing targets;

Add Group

This will then feed into the publishing dialog as below;

Dialog

This can be further refined through default publishing groups, settable in the same way as default publishing targets.

As stated in the beginning, a simple solution to a rare problem, but one I hope will help someone else in future.

Related Module: https://marketplace.sitecore.net/Modules/Sitecore_Publishing_Target_Groups.aspx

Related Source: https://github.com/brooksyd2/sitecorepublishgroups

Sitecore DMS: Recognising Users Across Devices

This post looks at how DMS stores visitor records, and this can be manipulated so that returning visitors across devices can reuse the same Visitor records.

When a user visits your site for the first time, the Sitecore DMS will create a brand new Visitor record in the analytics database, and link this to a new Visit record. This visit record will be updated for the duration of that session with relevant information, such as pages visited, profiles triggered etc. Sitecore will also place two cookies onto the clients computer, one for the session, and a global cookie that will help Sitecore identify the visitor between sessions. These cookies are called

SC_ANALYTICS_SESSION_COOKIE, and SC_ANALYTICS_GLOBAL_COOKIE respectively.

Once the first visit has been registered, your Visits Table will look like this (obviously ignoring any previous visits):

VisitFirst

The VisitorId matches the new Visitor record created in the Visitors table, which will look something like this:

VisitorFirst

Once that session ends, then the visit will be closed (this is all handled via the VisitEnd pipeline, which is invoked by the SessionEnd pipeline). If the user then returns to the site, Sitecore will check for the SC_ANALYTICS_GLOBAL_COOKIE  cookie, and if found, will use the existing Visitor record to attribute to a new Visit Record.  So to simulate this, delete the existingSC_ANALYTICS_SESSION_COOKIE (shown through Chrome below);

Remove Cookie

Now when you refresh the site, Sitecore will not find a session cookie, and so will create a new visit. However, as it can find a Global cookie, it can detect who you are, and so the same VisitorId will be used as the previous visit.

SecondVisit

So this is great, Sitecore can now continue attributing visits to the same user so long as it can find the Global cookie. The Global cookie is set to expire 10 years in the future, so as long as the user does not delete that cookie, and continues to browse from the same device, then Sitecore will continue to recognise them.

However, if the user browses to the site from another device (mobile, different browser etc), then obviously the cookie won’t be there and Sitecore will create a new Visitor record. Assuming that the user hasn’t authenticated against the site (and so no Sitecore User exists for them) then there is unfortunately no way to detect that user on another device. What about when the user does log in or becomes known in some other way? Unfortunately Sitecore still does not recognise this as the same visitor, and so the new Visitor record will endure.

If you do want to use the same Visitor record however, then this is possible, so long as the user has registered (or in some way has a corresponding Sitecore User profile). When the user registers with the site a Sitecore User profile is created. Of course at this point you should also be using the ‘ExternalUser’ field to set the user name (or other identifiable attributes), which would allow you to query for the user across different visitor records as well.

Tracker.Visitor.ExternalUser = Sitecore.Context.GetUserName();

So once the user registers, the Visitor record will be updated as such:

Register

To allow Sitecore to recognise a returning authenticated user, and set the Visitor record appropriately, you simply need to recognise the visitor first, and then replace the automatically generated Session cookie with a new Session cookie containing the previous visitor details. To do this, within the Log In method for example, you can see if the user has an existing profile (using the user name), and if so set the cookie;

var visitor = VisitorManager.GetVisitorByExternalUser(domainUser);

if (visitor == null)

{

    Log.Info("First visit of " + domainUser, this);

}

else

{

    Log.Info("Returning visit of " + domainUser, this);

    if(visitor.VisitorId != Guid.Empty)

    {

        new VisitorKeyCookie().Create(visitor.VisitorId);

        new VisitCookie().Invalidate();

    }

}

With this method in place, when the user firsts visits your site from a different device, a new visitor record will be created to match their anonymous status (as they are not known at this point).

ReturnAnon

Once they log in however, a new Visit record will be created with the previous Visitor details set. This does mean that everything for the user post log in will be treated as a new visit, but using the previous VistorId.

Recognise