Architecture

MVT in MVC – A History Lesson

History Books@1x.jpg

Multi-Variate Test has been a part of Sitecore DMS for quite some time. It basically allows marketers to vary a component’s datasource or a rendering itself and see which variation does better as measured in the overall engagement value. Testing is a big deal these days and Sitecore 8 attempts to disrupt the status-quo with the new Content Testing feature (aka Page Tests) that I will look into in the next installment of my Sitecore 8 Developer’s Notes (here’s part 1). Before I do so:

[su_note note_color=”#fafafa”]Let’s take a look at how MVT evolved and how parts of page’s layout details were not exactly shared even before Sitecore 8[/su_note]

7.0 / 7.1

A test variation is recorded in the presentation details as an attribute of the rendering node:

<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}"
ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}"
id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}"
mvt="{2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}"
ph="Main" />

The mvt attribute points to the test definition item under /sitecore/system/Marketing Center/Test Lab. It will be parsed out in Sitecore.Layouts.RenderingReference (simplified):

private void ParseDefinition(RenderingDefinition definition)
{
// ...
this.settings.MultiVariateTest = RenderingReference.ParseMultiVariateTest(definition, this.renderingItem);
// ..
}

...

private static string ParseMultiVariateTest(RenderingDefinition renderingDefinition, RenderingItem renderingItem)
{
// ...
string multiVariateTest = renderingDefinition.MultiVariateTest;
// ...
return multiVariateTest ?? string.Empty;
}

...

[XmlAttribute("mvt")]
public string MultiVariateTest { get; set; }

And then when the time comes for mvc.customizeRendering pipeline to apply MVT it will:

Item variableItem = args.PageContext.Database.GetItem(renderingReference.Settings.MultiVariateTest);

It works and the MVT definition is shared just like the entire layout details are.

7.2

Things changed in 7.2. I am not sure how well it’s known (let alone documented) but MVT in 7.2 is language-specific. That same test variation will be recorded differently in 7.2:

<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}"
ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}"
id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}"
mvt="en={2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}"
ph="Main" />

If you go ahead and create another language version for that page item and open it in Page Editor you won’t see the active test. You can now create a different test for the same component and it will be recorded like this:

<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}"
ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}"
id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}"
mvt="en={2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}&ru-RU={38B34DBC-6D3C-439F-92AF-D0C2EBCB3AB3}"
ph="Main" />

It is indeed language-specific. The problem is – the MVC code that’s using it was not invited to the party. 7.2 has a known defect and MVT doesn’t work in MVC. The mvt attribute is still directly translated into the MultiVariateTest attribute and no database can find an item for en={GUID}. The fix suggested by Ben is a little intrusive and SCORE provides support for using MVT with Sitecore MVC in 7.2 a little differently (feel free to contact me if you’re interested in details).

7.5

MVT is still language-specific in the otherwise shared layout details but the MVC code finally caught up. Here’s a one line change that makes all the difference:

private void ParseDefinition(RenderingDefinition definition)
{
// ...
this.settings.MultiVariateTest = RenderingReference.ParseMultiVariateTest(definition, this.renderingItem);
// ..
}

...

private static string ParseMultiVariateTest(RenderingDefinition renderingDefinition, RenderingItem renderingItem)
{
// ...
string variateTestForLanguage =
MultiVariateTestingExtensions.GetMultiVariateTestForLanguage(renderingDefinition, language);
// ...
return multiVariateTest ?? string.Empty;
}

...

[XmlAttribute("mvt")]
public string MultiVariateTest { get; set; }

That new helper method is actually available in 7.2. It’s just the MVC didn’t get the memo. And all it does is:

return WebUtil.ParseQueryString(multiVariateTest)[language.Name]

The MVT is working again in MVC.

8.0

8.0 makes a big move. A whole new ball game with the __Final Renderings field (aka versioned layouts). And not only that, there’s a big move towards testing page variations and suggesting what tests to run automatically. I will sure write about it like I promised already but what about good old MVT? Still there. Downgraded back to its original semantic. That same test variation we looked at will be recored as:

<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}"
ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}"
id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}"
mvt="{2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}"
ph="Main" />

It’s not written to the shared __Renderings though. It’s now part of the __Final Renderings so no need to version it individually. The MVC team didn’t need a memo this time. The rendering reference / definition parsing code has also been reverted back to:

// ...
string multiVariateTest = renderingDefinition.MultiVariateTest;
// ...

We have arrived. I hope you enjoyed the journey!

[su_divider][/su_divider]

p.s. There’s something else I noticed in 8. Something I haven’t seen before – Personalization Test:

[XmlAttribute("pt")]
public string PersonalizationTest { get; set; }

… Next Time!

About the Author

As a Sitecore MVP, Brian spends most of his time consulting and architecting software solutions for enterprise-level Sitecore projects.

More from this Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up