The custom container tag is one of the most useful tags available in the tag ecosystem and this tutorial quickly demonstrates how to get the most out of it with a Microsoft/Yahoo tag

Foreword

When you have a tag that isn't available in the tag eco-system the best way to get your tag running is:

(i) Send Tealium Support the implementation guidelines/code block and a contact at the vendor. The better the guidelines/more you provide the quicker we'll be able to add it!

(ii) Use a Custom Container to fire your tag whilst you're waiting for the new tag. This tutorial will help with this.

Note : Bear in mind this is an advanced task so if you're not comfortable please feel free to reach out to support to help you

Problem

A vendor has given you a code snippet to run on your site and you're unsure how to execute it. You also want to map some Variables to it for use. In this example we will use a Microsoft/Yahoo tag.

Microsoft/Yahoo code snippet (you may need to refer back up to here in this post)

<script type="text/javascript"> 
if (!window.mstag) mstag = {loadTag : function(){},time : (new Date()).getTime()};
</script> 

<script id="mstag_tops" type="text/javascript" src="//flex.msn.com/mstag/site/b7381bb8-71e7-408c-91d0-3adb90b5c736/mstag.js">
</script> 

<script type="text/javascript"> mstag.loadTag("analytics", {dedup:"1",domainId:"1516122",type:"1",revenue:"",actionid:"264766"})
</script> 

<noscript> <iframe src="//flex.msn.com/mstag/tag/b7381bb8-71e7-408c-91d0-3adb90b5c736/analytics.html?dedup=1&domainId=1516122&type=1&revenue=&actionid=264766" frameborder="0" scrolling="no" width="1" height="1" style="visibility:hidden;display:none"> </iframe> </noscript>

Solution

1. Examine your code:

Screen_Shot_2014-09-26_at_14.56.31.png

This is a pretty thorough example and we can see four parts to the code:

A.  Some code to run first: This is some code that needs to be run first. We can't see anything specific we need to pass in from Tealium so we're going to make a mental note to run this first.

B.  A script to call : Now we're being asked to call a script. Note some of it looks client specific (i.e. the b738...736) so we're probably going to map this. Also, note that the script needs an ID of 'mstag_tops'. We're going to need to do that too

C. Some code to run after the script : The script in (B) is synchronous, which means your browser will run through all of that code before moving on to next piece of code (i.e. 'C'). This means we're going to have to do something to ensure (C) runs after (B). Also, note that some values look dynamic (e.g. 'actionid' and 'domainId') - we'll have to map those

D. Noscript : This is common when receiving tags. It's a fall back option for browsers which don't support or have javascript disabled. Tealium requires javascript so we can completely ignore this as it is redundant (if the browser doesn't allow javascript then it can't run Tealium at all)

2. Add the Tealium Custom Container from the tag library and save it

click 'add tag'...

add tag button.png

click 'add'...

Screen_Shot_2014-09-26_at_14.50.43.png

save it (you don't need to publish yet)...

Screen_Shot_2014-09-26_at_14.52.17.png

3. Edit the template

Now you've saved you can edit the template (if you have edit template permissions) by going into the tag configuration then advanced and clicking edit template:

Screen_Shot_2014-09-26_at_14.54.40.png

4. Add 'Tag Sending Code' (A - in example)

First, we're going to copy the code from  A in our example and drop it in line 76 in the 'Tag Sending Code':

Screen_Shot_2014-09-26_at_14.57.55.png

This part of the template will allow you to run your code first. Here is what the code will look like now:

        /* Start Tag Sending Code */
          if (!window.mstag) window.mstag = {loadTag : function(){},time : (new Date()).getTime()};
        /* End Tag Sending Code */

5. Use Loader Function Call (B - in example)

We need to uncomment line 99 and lines 101-104 (the other lines are used for making image requests or generating iframes - we only want to call a script):

Screen_Shot_2014-09-26_at_15.06.37.png

Now, we want to tweak line 101 to call the script at '//flex.msn.com/mstag/site/b7381bb8-71e7-408c-91d0-3adb90b5c736/mstag.js'. To do this, I've updated the 'src' attribute as follows:

Screen_Shot_2014-09-26_at_15.08.29.png

Instead of using u.data.base_url - I'm forcing the string to start with  "//flex.msn.com/mstag/site/" and end with "/mstag.js" with a Variable called u.data.script_id sandwiched in between. This u.data.script_id is going to be  a dynamic Variable that we can set by mapping a Variable to 'script_id' in the tag mapping toolbox (which I'll go into later - we have more to do and we can do them all at once).

Finally, we want to change the "id" attribute from "utag_##UTID##" to the ID from the code - "mstag_tops":

Screen_Shot_2014-09-26_at_15.12.43.png

This part of the code now looks like this:

/* Start Loader Function Call */
        /* Un-comment the single-line JavaScript comments ("//") to use Loader. */

          if (!u.initialized) {
            //u.loader({"type" : "iframe", "src" : u.data.base_url + c.join(u.data.qsp_delim), "cb" : u.loader_cb, "loc" : "body", "id" : 'utag_##UTID##' });
            u.loader({"type" : "script", "src" : "//flex.msn.com/mstag/site/" + u.data.script_id + "/mstag.js", "cb" : u.loader_cb, "loc" : "script", "id" : "mstag_tops" });
          } else {
           u.loader_cb();
          }

//          u.loader({"type" : "img", "src" : u.data.base_url + c.join(u.data.qsp_delim) });

        /* End Loader Function Call */

6. Set Callback Tag Sending Code (C - in example):

Now that we've set our code to run first (A) and we've told the template what script to call (B) we need to tell it what code to run after the script has loaded (C). To ensure the script has loaded before (C) is called we need to use the Loader Callback Function which is specified on lines  81-93. We need to uncomment it as usual on lines 84, 85 and 91:

Screen_Shot_2014-09-26_at_15.17.43.png

Now that we've uncommented our code we can insert the code from (B) onto line 88 with some amends:

Screen_Shot_2014-09-26_at_15.19.28.png

You'll see that I've overridden the values for domainID and actionid with u.data.~ values. This is so we can set these using Variables in the UI and mapping them.

7. Verify your template

We're now finished with the template so you should end up with a template like this:

//~~tv:20010.20140827
//~~tc: Tealium Custom Container

/*
  Tealium Custom Container Notes:
  - Add sending code between "Start Tag Sending Code" and "End Tag Sending Code".
  - Add JavaScript tag library code between "Start Tag Library Code" and "End Tag Library Code".
  - Add JavaScript code only, do not add HTML code in this file.
  - Remove any <script> and </script> tags from the code you place in this file.

  Loading external JavaScript files (Loader):
  - If you need to load an additional external JavaScript file, un-comment the singe-line JavaScript comments ("//") within the following Loader sections near the bottom of this file:
      - "Start Loader Function Call"
      - "End Loader Function Call"
      - "Start Loader Callback Function"
      - "End Loader Callback Function"
  - After un-commenting, insert the path to the external JavaScript file you want to load.
  - Finally, within the Loader callback function, insert the JavaScript code that should run after the external JavaScript file has loaded.
*/

/* Start Tag Library Code */
/* End Tag Library Code */

//tealium universal tag - utag.sender.custom_container ut4.0.##UTVERSION##, Copyright ##UTYEAR## Tealium.com Inc. All Rights Reserved.
try {
  (function (id, loader) {
    var u = {};
    utag.o[loader].sender[id] = u;

    // Start Tealium loader 4.32
    // Please do not modify
    if (utag === undefined) { utag = {}; } if (utag.ut === undefined) { utag.ut = {}; } if (utag.ut.loader === undefined) { u.loader = function (o) { var a, b, c, l; a = document; if (o.type === "iframe") { b = a.createElement("iframe"); b.setAttribute("height", "1"); b.setAttribute("width", "1"); b.setAttribute("style", "display:none"); b.setAttribute("src", o.src); } else if (o.type === "img") { utag.DB("Attach img: " + o.src); b = new Image(); b.src=o.src; return; } else { b = a.createElement("script"); b.language = "javascript"; b.type = "text/javascript"; b.async = 1; b.charset = "utf-8"; b.src=o.src; } if (o.id) { b.id = o.id; } if (typeof o.cb === "function") { if (b.addEventListener) { b.addEventListener("load", function () { o.cb(); }, false); } else { b.onreadystatechange = function () { if (this.readyState === "complete" || this.readyState === "loaded") { this.onreadystatechange = null; o.cb(); } }; } } l = o.loc || "head"; c = a.getElementsByTagName(l)[0]; if (c) { utag.DB("Attach to " + l + ": " + o.src); if (l === "script") { c.parentNode.insertBefore(b, c); } else { c.appendChild(b); } } }; } else { u.loader = utag.ut.loader; }
    // End Tealium loader

    u.ev = {'view' : 1};

    u.initialized = false;

    ##UTGEN##

    u.send = function(a, b) {
      if (u.ev[a] || u.ev.all !== undefined) {
        //##UTENABLEDEBUG##utag.DB("send:##UTID##");

        var c, d, e, f, i;

        u.data = {
          /* Initialize default tag parameter values here */
          /* Examples: */
          /* "account_id" : "1234567" */
          /* "base_url" : "//insert.your.javascript.library.url.here.js" */
          /* A value mapped to "account_id" or "base_url" in TiQ will replace these default values. */
        };

        /* Start Tag-Scoped Extensions Code */
        /* Please Do Not Edit This Section */
        ##UTEXTEND##
        /* End Tag-Scoped Extensions Code */

        /* Start Mapping Code */
        for (d in utag.loader.GV(u.map)) {
          if (b[d] !== undefined && b[d] !== "") {
            e = u.map[d].split(",");
            for (f = 0; f < e.length; f++) {
              u.data[e[f]] = b[d];
            }
          }
        }
        /* End Mapping Code */

        /* Start Tag Sending Code */

          if (!window.mstag) window.mstag = {loadTag : function(){},time : (new Date()).getTime()};

        /* End Tag Sending Code */

        /* Start Loader Callback Function */
        /* Un-comment the single-line JavaScript comments ("//") to use this Loader callback function. */

        u.loader_cb = function () {
          u.initialized = true;
          /* Start Loader Callback Tag Sending Code */

            mstag.loadTag("analytics", {dedup:"1",domainId:u.data.domain_id,type:"1",revenue:"",actionid:u.data.action_id});

          /* End Loader Callback Tag Sending Code */
        };

        /* End Loader Callback Function */

        /* Start Loader Function Call */
        /* Un-comment the single-line JavaScript comments ("//") to use Loader. */

          if (!u.initialized) {
            //u.loader({"type" : "iframe", "src" : u.data.base_url + c.join(u.data.qsp_delim), "cb" : u.loader_cb, "loc" : "body", "id" : 'utag_##UTID##' });
            u.loader({"type" : "script", "src" : "//flex.msn.com/mstag/site/" + u.data.script_id + "/mstag.js", "cb" : u.loader_cb, "loc" : "script", "id" : "mstag_tops" });
          } else {
           u.loader_cb();
          }

//          u.loader({"type" : "img", "src" : u.data.base_url + c.join(u.data.qsp_delim) });

        /* End Loader Function Call */

        //##UTENABLEDEBUG##utag.DB("send:##UTID##:COMPLETE");
      }
    };
    utag.o[loader].loader.LOAD(id);
  })("##UTID##", "##UTLOADERID##");
} catch (error) {
  utag.DB(error);
}
//end tealium universal tag

8. Create your Variables and map them

Create your Variables via  the 'Data Layer' tab and then map them to the following values in the mapping toolbox:

Screen_Shot_2014-09-26_at_15.23.27.png

9. Set your relevant Variables via an extension

You can now set your Variables to the values in your original tag via an extension:

Screen_Shot_2014-09-26_at_15.24.44.png

10. Save and publish!

Thats it - you're done! Once you've saved and published your tag will work as desired with the added bonus that you can set the Variables in the tag via extensions (instead of having to amend your template each time you want to use a different value).