Monthly Archives: May 2009

Server-Side Dynamic Section Variations

Editor’s Note: The original URL is: http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html. This is an archived/re-post retrieved from the Wayback Machine: Internet Archive of an original blog post written by Eric Vasilik, but re-posted since the site is no longer available & the content has been deemed save-worthy.


This technique is one of my favorites because it involves some pretty “clever” (euphemism for twisted) JavaScript. But don’t let this scare you, the script works on all the browsers and is as fail-safe as the scripting that Website Optimizer requests you place on your sites by default.

Multi-Variate Experiments “Out of the Box”

First, let’s revisit certain aspects of GWO pertinent to this technique. By default, GWO handles multi-variate experiments in the following way:

gwotricks_1

Your test page and the default content for your experiment sections are served directly from your web server. If alternative content has been chosen to be displayed to a visitor, that alternative content is served from a Google server.

Now, this poses a particular limitation: the alternative content must be static in nature. The reason behind this is in the fact that, in the default setup process of a multi-variate experiment, you are requested to input the alternative content into GWO’s user interface, and that content is simply served back to your test page on demand where it replaces the default content in the page for visitors selected to see the alternative content.

This means that if you wanted to customize that alternative content differently for each visitor, you don’t get a chance to do so. For example, you might want to include the customer’s name in the alternative content. Or, you might want to serve a promotion customized for the given customer.

Alternative Content Served from Your Webserver

The technique I am about to discuss allows you to serve all content, default and alternative, directly from your web server:

gwotricks_2

Here, the Google server does not serve any alternative content. It only serves back an indicator (an integer) of which content should be show to a given visitor. All the possible variations for the sections are rendered into the web page by your web server where you have complete dynamic control over the content of those variations. In the following, I will show you the scripts you need to generate along with that content in order to show one of either your default content or variations.

Size of Alternatives

That said, one should be careful when using this technique because it requires you to render all possible section variations into the page. Because even though your web server knows what the content of the alternatives are, it does not know which alternative will be chosen for a visitor to your test page. Contact with the Google server is required for that, and the logic about which content to show to the visitor must be executed in the browser client.

So, if the number and size of all the alternative section variations is not too large, you can use this technique. Many times, this is the case. Even if you define your entire page to be a single section, this technique may work for you because only the HTML of the alternative need be present in your page. Any other resources, like images, scripts or style sheets, which are specific to an alternative variation will be loaded if that alternative variation is chosen for a visitor. Content which was not chosen for the visitor will not even be parsed by the browser, it will essentially be thrown away.

Creating the Experiment

To use this technique, you begin by creating a regular multi-variate experiment. Give the experiment a name, test page and goal page. When asked to add the GWO scripts to the page, add the control script in the normal way. And, add the tracking scripts in the normal way.

However, do not follow the default instructions for adding section scripts. I have prepared an example test page you can look at which illustrates the alternative to the default section scripts which allows you to serve alternative section variations from your web server:

Server Side Sections Example:

<h2>Server-side Dynamic Content - Test Page</h2>

<p>Content Before Section1
<p>

<!-- Section1 - Default content -->
<script>
var GWO_Section1 = utmx("variation_number", "Section1");
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write('<no' + 'script>');
</script>
Default content - shown by default<br>
</noscript>

<!-- Section1 - Variation 1 -->
<script>
if (GWO_Section1 == 1) document.write('</noscript a="');
</script><!--">
Alternative content 1<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->

<!-- Section1 - Variation 2 -->
<script>
if (GWO_Section1 == 2) document.write('</noscript a="');
</script><!--">
Alternative content 2<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->

<p>Content After Section1<br>

<script type="text/javascript">
if(typeof(_gat)!='object')document.write('<sc'+'ript src="http'+
(document.location.protocol=='https:'?'s://ssl':'://www')+
'.google-analytics.com/ga.js"></sc'+'ript>')</script>
<script type="text/javascript">
try {
var pageTracker=_gat._getTracker("UA-7250447-1");
pageTracker._trackPageview("/3386445238/test");
}catch(err){}</script>

First, you will want to declare the number and names of the server-side dynamic experiment sections you plan to test. Sections are normally declared as a result of surrounding the default content of a section with the standard GWO sections scripts. But, because we are not using those, you need to use an alternative. So, to declare a single section with the name “Section1”, place the following immediately after the Control Script:

<!-- utmx section name="Section1" -->;

You can repeat this kind of comment to declare up to 8 sections. For example:

<!-- utmx section name="Section1" -->
<!-- utmx section name="Section2" -->
<!-- utmx section name="Section3" -->

Note that you can mix regular GWO multi-variate section with server-side dynamic sections. Simply include the standard GWO style sections as described in the default install instructions.

Instrumenting the Sections

The following script is the entire definition of the section from my example page. I show you in its entirety here, and will dissect it later. Note that the dynamic content for each variation is highlighted. These are the parts of the page you get to dynamically generate. Only one of them will be show to a given visitor, the others will be stripped away.

<script>
var GWO_Section1 = utmx("variation_number", "Section1");
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write('<no' + 'script>');
</script>
Original content - shown by default<br>
</noscript>

<script>
if (GWO_Section1 == 1) document.write('</noscript a="');
</script><!--">
Alternative content 1<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->


<script>
if (GWO_Section1 == 2) document.write('</noscript a="');
</script><!--">
Alternative content 2<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->

The basic idea with this technique is that each of these script blocks controls a piece of content. The first controls the original content. By default, the original content is show to the visitor. The other script blocks control the alternative pieces of content, one of which, is meant to replace the original content. By default the alternatives are hidden from the visitor. If an alternative is chosen to be shown to the visitor, then the script blocks will work together to hide the original and show only one of the alternatives to the visitor.

The content contained in each of these script blocks is totally under your control in your web server. Which one of them is shown to the visitor is under the control of Website Optimizer.

The Default Content

Like any GWO experiment, the default content is encoded in your test pages, and if JavaScript is not present or disabled, or there is any malfunction anywhere, the default content will be presented to your visitors. With this technique, the default content is handled with this script:

<script>
var GWO_Section1 = utmx("variation_number", "Section1");
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write('<no' + 'script>');
</script>
Original content - shown by default<br>
</noscript>

Here, the script code firsts obtains the number of the variation for the section named “Section1” chosen for the current visitor:

var GWO_Section1 = utmx("variation_number", "Section1");

This call to the utmx function will return a 0 (zero) or undefined if the visitor should see the default content. This value is saved in a global variable for use in subsequent alternative content scripts. Note that the utmx function is defined by the Control Script which needs to have been executed before the call to the utmx function in this script.

Then, if alternative content has been chosen for this visitor, the default content is hidden from the visitor with the second line of code:

if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write('<no' + 'script>');

By document.writing a beginning <noscript> tag, the content after the script and up to the first </noscript> tag will be consumed and ignored by the parser. This requires that your default content not contain any noscript tags (beginning or ending). This is exactly the same technique used by GWO for standard installations of multi-variate experiments. The only difference is that here we are just removing the default content, but the standard GWO multi-variate technique document.writes the alternative content to replace the default content before writing the <noscript> tag to eliminate the default content.

The Alternative Content

Now, for each variation of alternative content for a given section, you will need a script like this:

<script>
if (GWO_Section1 == 1) document.write('</noscript a="');
</script><!--">
Alternative content 1<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->

Note that the 1 indicates that this script is customized for the first alternative. The second alternative will have the number 2, the third 3, etc. The larger highlighted part is your dynamically generated alternative content for the first alternative. Simply have your web server surround the alternative content with the other text.

The first line of the script determines if this alternative was chosen to be viewed by the visitor and document.writes some content designed to cause the variation to be shown to the visitor:

if (GWO_Section1 == 1) document.write('</noscript a="');

To understand this better, consider what this content would look like if scripting is disabled, or the value of GWO_Section1 does not have the value 1. That is, there is no script:

<!--">
Alternative content 1

<script>document.write('<'+'!'+'-'+'-')</script>-->

This entire block of HTML is nothing more than one large comment. In fact, the alternative content is hidden by default by the fact that it is embedded inside a comment. This means that the alternative content must not have any comments in it. Note that even the script at the end of the HTML is also inside the comment.

Now, look carefully at what is written if this section variation has been chosen to be displayed to the visitor:

</noscript a="

This is the beginning of an ending noscript tag. Note that there is no > terminating the tag. Also, in this tag there is the beginning of an attribute. Notice, also, that the value of the attribute is not present and that the ending double quote is not present. That is not two single quotes. It is a single double quote.

Recall that the way that document.write works is that the written text is, essentially, inserted after the end of the script where the browser parser will resume its parsing after the script has executed. Again, by stripping away the first script tag, let’s look at what the parser will encounter:

</noscript a="<!--">
Alternative content 1<br>
<script>document.write('<'+'!'+'-'+'-')</script>-->

Here the parser sees an ending noscript tag with an attribute whose value are the characters which begin a comment. The thing to know here is that HTML parsers allow beginning comment sequences inside attribute values. This is the clever (twisted) part I eluded to earlier.

Now, it should be apparent why there was the “> characters immediately after the beginning comment character sequence: <!–. It is there to terminate the dynamically written ending noscript tag. This tag “eats” the beginning comment token. Yummy.

This allows the parser to parse and display the alternative content. Now, all we need to do is deal with the remaining ending comment token! This is done by the last part of the script:

<script>document.write('<'+'!'+'-'+'-')</script>

Which injects a beginning comment token which is terminated by the remaining ending comment token, statically present in the page. Without this document.write, the “–>” would appear in the page when this alternative content was chosen for the visitor.

This is how each alternative variation is handled. Simply do the above for each alternative section. Each one will have the server generated content of the variation. Each script will have the number of the variation encoded in it. 1 for the first alternative, 2 for the second, etc.

You can repeat this sequence of scripts for a section as many times on your page(s) as you want to hide/show the default/alternative content for that section.

Setting Up the Variations in GWO

Even though this technique requires you generate all your alternative content into the page, you will still need to create section variations in Step 3 of the GWO user interface for each section in your test. The only difference is that you do not supply any content for these variations. The reason for this is that GWO still needs to know how many variations each server-side dynamic section has for the purposes of choosing which variation visitors will see and reporting results. For example:

gwotricks_3

Shows the section named “Section1” with two (2) variations created for it. I give each variation a name for reporting purposes, but I do not need to give it any content.

After Doing this, all that is left to do is preview the experiment to make sure the scripts are working and launch the experiment!

Advertisements