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" />
Covid 19
COVID-19: Digital Insights For Enterprise Action

Access Perficient’s latest insights into how you can leverage digital technologies to not only respond to the pandemic, but drive your operations forward and deliver experiences your customers need.

Get Informed

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