1

I am trying to build a basic tag management solution in SiteCore.

I have created a folder called Tag Management under Templates. Under the Tag Management folder I created a template called Google Analytics. This tag has a few attributes that are used as parameters for the tag.

If I create a content item that inherits this template, I see the attribute fields.

What I need to know, is where -- as best practice -- would I would write my code that generates the script tag. I looked in the SiteCore source project, and do not see any folders for Template code.


UPDATE: Based on the Feedback and this Url: http://andyuzick.arke.com/2013/02/as-web-marketers-great-deal-of-our.html , I have implemented a new class library with the following:

Settings.cs

namespace TagManagement
{
    public class Settings
    {
        public const string DEFAULT_GLOBAL_TAG_FOLDER = "/sitecore/content/Global/TagManagement";
        public static string GlobalTagFolder
        {
            get
            {
                return Sitecore.Configuration.Settings.GetSetting("TagManagement.GlobalTagFolder", DEFAULT_GLOBAL_TAG_FOLDER);
            }
        }
    }
}

WebControl.cs

using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using System;
using System.Text;
using System.Web.UI;

namespace TagManagement
{
    public class TagManagmentControl: Sitecore.Web.UI.WebControl
    {
        System.Web.UI.WebControls.Literal container;

        public string TagItem { get; set; }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            container = new System.Web.UI.WebControls.Literal();
        }

        protected override void CreateChildControls()
        {
            Assert.IsNotNullOrEmpty(TagItem, "tag item");
            Item item = Sitecore.Context.Database.GetItem(TagItem);
            StringBuilder tagToOutput = new StringBuilder();
            string templateName = item.TemplateName;
            switch (templateName)
            {
                case "Google Analytics":
                    tagToOutput.AppendLine("<script>");
                    tagToOutput.AppendLine("    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){");
                    tagToOutput.AppendLine("    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),");
                    tagToOutput.AppendLine("    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)");
                    tagToOutput.AppendLine("    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');");
                    tagToOutput.AppendLine("    ga('create', '" + item.Fields["Tracking ID"].Value + "', '" + item.Fields["Domain"].Value + "');");
                    if (item.Fields["Enable Demographics and Interest Reports"].Value == "1") 
                    {
                        tagToOutput.AppendLine("    ga('require', 'displayfeatures');");
                    }
                    tagToOutput.AppendLine("    ga('send', 'pageview');");
                    tagToOutput.AppendLine("</script>");
                    tagToOutput.AppendLine();
                    break;
                case "HTML Tracking Tag":
                    tagToOutput.AppendLine(item.Fields["Markup"].Value);
                    break;
            }
            container.Text = tagToOutput.ToString();
        }

        protected override void DoRender(HtmlTextWriter output)
        {
            EnsureChildControls();
            container.RenderControl(output);
        }

        protected override string GetCachingID()
        {
            return this.GetType().FullName;
        }
    }

}

PipelineProcessor.cs

using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Layouts;
using Sitecore.Pipelines.InsertRenderings;

namespace TagManagement
{
    public class InsertTags
    {
        public void Process(InsertRenderingsArgs args)
        {
            Assert.ArgumentNotNull(args, "args");

            if (Sitecore.Context.Site.Name == "shell")
            {
                return;
            }

            Item globalTagFolder = Sitecore.Context.Database.GetItem(Settings.GlobalTagFolder);
            Profiler.StartOperation("Tag Management: Adding Tags...");

            foreach (Item globalTagItem in globalTagFolder.Children)
            {
                TagManagement.TagManagmentControl control = new TagManagement.TagManagmentControl();
                if (control != null)
                {
                    control.TagItem = globalTagItem.ID.ToGuid().ToString();
                    control.Cacheable = true;
                    control.VaryByData = true;
                    RenderingReference reference = new RenderingReference(control);
                    reference.AddToFormIfUnused = true;
                    args.Renderings.Add(reference);
                    Tracer.Info(string.Concat("Tag Management: Added: '", globalTagItem.Name, "'"));
                }
            }

            Profiler.EndOperation();
        }
    }
}

I would appreciate any constructive feedback from the SiteCore experts in the room!

1 Answer 1

2

I believe you're pretty much in the right direction.

I can think in three ways to render those tags contents.

1) Add it in your main layout code behind (it is the easiest but I really dont like that option, your code will be dependent on the mainlayout)

2) Build a sublayout and add it in a specific placeholder in your head tag, give to the sublayout code the responsability to render the tags (also don`t like it too much)

3) Create a Process in the "renderLayout" pipeline that does the job for you (the best option, it is decoupled and can be easily turned on and off via config files) *The Caveat, your tag needs to be runat server.

This is how would look like your process:

namespace YourNamespace
{
    public class PrintTags
    {
        public void Process(RenderLayoutArgs args)
        {
            //put here validation you may require

            var head = WebUtil.FindControlOfType(Sitecore.Context.Page.Page, typeof(System.Web.UI.HtmlControls.HtmlHead));

            if (head != null)
            {
                //add any content in the head
                head.Controls.Add(new Literal(" CONTENT "));
            }
            else
            {
                //make sure to not break the app instead just log the error.
                Sitecore.Diagnostics.Log.Error("Error - The HEAD element must be runat=server", this);
            }
        }
    }
}

.Config:

<configuration>
  <sitecore>
    <pipelines>
      <renderLayout>
        <processor type="YourNamespace.PrintTags, YourAssembly" />
      </renderLayout>
    </pipelines>
  </sitecore>
</configuration>

Hope it helps..

cheers

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.