Friday, November 29, 2013

Sitecore Profiling and Tracing

It's been a while since I've posted. I have a couple of bigger subjects on the spike, but for now here's a quick word about Sitecore profiling and tracing.

Have you ever had to debug a problem with a Sitecore page and you wind up slogging through the log, trying to find the related error? Or have you ever wondered which of your renderings or sublayouts might be causing performance issues? Or maybe you have custom logic in a pipeline processor, and you wish there was an easy way to emit debugging or performance information?

There are a couple of underutilized features in Sitecore that can be a real time saver in situations like this: Sitecore.Diagnostics.Tracer and Sitecore.Diagnostics.Profiler. These classes are sitting right next to the much-used Sitecore.Diagnostics.Log class, but are often overlooked. Both of these classes allow you to emit information directly to the page when in debug mode. This is a far more convenient and useful way to do debugging than writing to the Sitecore log.

The Profiler class is useful for tracking the progress of the page rendering cycle, and for gathering performance data about the components and code being executed. It has the usual Info, Warning and Error static methods you are probably familiar with from the Log class, but the real gems here are the StartOperation and EndOperation methods. With them, you can gather valuable performance data about parts of the rendering process, including both large chunks of a process and nested inner pieces of the process. For example, the Arke MetaTag Manager  module emits quite a bit of information about it's internal workings to the debugger.


The information provided not only helps us understand the performance impact of this process, but also helps us troubleshoot when we suspect that a tag is not being gathered properly.

To output this information, it's a simple matter of adding a two lines of code. For example, this is the Process method used for the CustomTag pipeline processor:


public void Process(InjectMetaTagsPipelineArgs args)
{

  Sitecore.Diagnostics.Profiler.StartOperation(
    "Adding custom tag '" + GetSignatureName() + "'"
    );

  try
  {
    Assert.ArgumentNotNullOrEmpty(
      TypeSignature, 
      "Class not supplied"
      );
    args.MetaTags.Add(ReflectionUtil.GetCustomTag(TypeSignature));
  }
  catch (Exception ex)
  {
    Sitecore.Diagnostics.Tracer.Error(
      "CustomTag failed.", 
      ex
      );
    Sitecore.Diagnostics.Log.Error(
      "CustomTag failed.", 
      ex, 
      "CustomTag"
      );
  }
  finally
  {
    Sitecore.Diagnostics.Profiler.EndOperation();
  }
}


Sitecore will nest sets of profiling blocks, which makes it easy to trace through a process to see where a problem or performance hit may be.

The other handy class for "in-page" debugging is the Tracer class. Again , this class has the familiar InfoWarning and Error static methods, but the output from these methods is written to the "Trace" section of the page debugger. I use these methods for writing out error or info strings much the way I would to the Sitecore Log, but they're written to the page itself, where troubleshooting is much easier. It's always nice to just be able to turn on the debugger to see this info instead of having to search through the log file.

Again, looking at the sample code above, note that the "catch" statements include a line of code to write the error to the tracer, which would yield this:

That beats searching for the error on the log file ... or worse, throwing a "yellow screen".

Happy tracing!


Wednesday, July 3, 2013

Hiding fields in the Content Editor



The source code, package and documentation for this module are available from the Sitecore Marketplace.
Anyone who has worked much with the Sitecore Content Editor knows that there are a bunch of "standard" fields that Sitecore usually keeps hidden. These fields are either system-managed, or are rarely used and typically only changed by developers or administrators. With proper permissions, you can see these fields (View > Standard Fields), but they are usually turned off to reduce clutter.

Sometimes I want to hide some of the fields that are created as part of my solutions. This may include:
  • Fields that are intended only for administration. To avoid clutter, these fields should be hidden unless the content editor is showing standard (system) fields.
  • Fields that are populated by handlers. This could include fields that are populated by a save handler and should not be edited.
  • Fields that are populated by a publishing processor, to aggregate information or provide hints or shortcuts to the CD, to improve performance or to pass along other data.
  • Fields that are populated or reconciled by a data importer, which should not be edited.

I've created a module (available from the Sitecore Marketplace) to do just that.

This module extends Sitecore to allow developers to designate when a field should be hidden from the content editor. The options are to (1) always show the field, (2) always hide the field, or (3) only show the field when the content editor is showing standard (system) fields.

The module extends the “GetContentEditorFields” pipeline and also extends the Template field template that Sitecore uses for managing template fields in the content editor. A description of the techniques underlying this are included a bit farther down.

Installing the module

There are three key pieces required for this module: the assembly, the config file and Sitecore content items. These are all included in the package Arke.Templates.zip. To install this module, simply upload this package to Sitecore and install it normally.

If security prevents the package installer from deploying the assembly (.dll) file or the Arke.Templates.config file, these can be extracted from the zip file and deployed manually.


Using the module

Once the module is installed, you can manage the visibility of any field by changing the “Show In Content Editor” setting on any field item. The options are…
  • Always: Always show this field.
  • Never: Never show this field.
  • When showing standard fields: Show this field when Standard Fields is turned on in the ribbon (under View).


Configuration options

The Arke.Templates.Config file allows the system administrator to set how the module behaves. “HideEmptySections” governs how to handle content editor sections when all of the fields within that section have been hidden:

<!-- Hide empty sections
Should the template section be hidden entirely if all of the fields
within it are hidden
-->
<setting name="Arke.Templates.HideEmptySections" value="true" />


How the module works

The module works by extending the GetContentEditorFields pipeline.

Like many other Sitecore pipelines, GetContentEditorFields maintains a collection in its PipelineArgs class that is populated by a series of processor items. When Sitecore is rendering the content panel, it uses this pipeline to gather all of the fields and sections that it needs to display. As each processor runs, it adds fields and sections to a collection, which Sitecore uses at the end of the pipeline to form the editing panel.

When developing a pipeline processor in a situation like this, it is tempting to replace Sitecore’s processor with your own, in order to control what data is being added to the args object. However, this often requires extensive duplication of Sitecore’s code, as many of the classes in the Sitecore namespace are not public or not static, and so must be replicated in the custom processor. It also means the custom processor is less “future-proof”. If a future Sitecore release changes the processor you replaced, you will have to re-create your custom processor to reflect Sitecore’s changes.

The architecture of this module leaves Sitecore’s GetContentEditorFields pipeline processors intact, and adds a new custom processor to the end of the pipeline (the namespaces below have been truncated for readability):

<pipelines>
  <getContentEditorFields>
    <processor
      type="Arke…TrimHiddenFields, Arke.SharedSource.Templates"
      patch:after="processor[@type='Sitecore...GetExplicitFields, Sitecore.Client']
    />
  </getContentEditorFields>
</pipelines>

When the default processors have completed, the args class contains all of the fields and sections gathered by the standard processors. The TrimHiddenFields processor then iterates over all of the content sections, examining all the fields to see if their “hide” box is checked, and removing them as appropriate. It them removes the section if it no longer has visible fields.

public void Process(GetContentEditorFieldsArgs args)
{
  Assert.ArgumentNotNull(args, "args");
  if (args.Sections == null || args.Sections.Count == 0)
  {
    return;
  }
  if (Settings.HidingCheckedFields == HideCheckedField.Never)
  {
    return;
  }
  this.args = args;
  for (int sectionIndex = 0; sectionIndex < args.Sections.Count; sectionIndex++)
  {
    Editor.Section section = args.Sections[sectionIndex];
    TrimFields(section);      
    if (Settings.HidingEmptySections && section.Fields.Count == 0)
    {
      args.Sections.RemoveAt(sectionIndex);
      sectionIndex--;
    }
  }
}


private void TrimFields(Editor.Section section)
{
  for (int fieldIndex = 0; fieldIndex < section.Fields.Count; fieldIndex++)
  {
    if (FieldIsHidden(section.Fields[fieldIndex]))
    {
      section.Fields.RemoveAt(fieldIndex);
      fieldIndex--;
    }
  }
}


private bool FieldIsHidden(Editor.Field field)
{
  try
  {
    Item templateFieldItem = GetTemplateFieldItem(field, args.Item.Database);
    if (templateFieldItem == null)
    {
      return false;
    }
    bool isHiddenChecked = false;
    try
    {
      CheckboxField fld =
        (CheckboxField)templateFieldItem.Fields[Settings.HideCheckboxFieldName];
      isHiddenChecked = fld.Checked;
    }
    catch { }
    switch (Settings.HidingCheckedFields)
    {
      case HideCheckedField.Never:
        return false;
        break;
      case HideCheckedField.Always:
        return isHiddenChecked;
        break;
      case HideCheckedField.WhenHidingStandardFields:
        return isHiddenChecked && (!UserOptions.ContentEditor.ShowSystemFields);
        break;
    }
  }
  catch { }
  return false;
}
 
private Item GetTemplateFieldItem(Editor.Field field, Database database)
{
  try
  {
    return database.GetItem(field.TemplateField.ID);
  }
  catch { }
  return null;
}


It may seem wasteful to “undo” some of the work down by previous processors. However, the CPU overhead for this is pretty light, and any item data the custom processor needs (like field definition items) will have already been read (and presumably cached) by previous steps. This slight extra overhead is a small price to pay to keep this additional functionality self-contained, and to avoid replacing any of Sitecore’s default processors. Also bear in mind that this activity only happens in the content management server, where I regard performance as somewhat less critical than the content delivery instance.

More resources...




Tuesday, March 12, 2013

The Heart of the Meta

This article describes Arke System's Meta Tag Manager shared source module, available for free download from the Sitecore Marketplace.




Update 27-March-2013: Several changes have been made to this module, including adding new tag types (properties), adding support for all tag types in the pipeline, and creating "Custom Tags" to replace the less intuitive "Dynamic Processors"). See the documentation file in the Sitecore Marketplace for details.
It's almost inevitable that at some point in a solution's lifespan, there comes a need to add various types of meta tags to the head of your pages. Sometimes it's site-wide tags like turning off the silly IE image toolbar (thankfully a legacy issue now). Sometimes it's something you may need at the page level, like instructing robots not to crawl the page. Sometimes the tag values are static, like a robot directive  Sometimes they're dynamic, like page type (template), GUID or other info needed by crawlers or page script. Sometimes the need is simple, sometimes there are very complex tagging requirements for analytics or search crawling.

I've found that over time, solutions wind up with meta tags being handled in dozens of ways ... sometimes in markup, sometimes in code-behind, sometimes in base layouts, sometimes in renderings, sometimes in handlers. Discovering the providence of a tag you find in the final HTML can be challenging.

Recently, a client was concerned about the S.E.O. ramifications of having identical pages at more than one URL on their Sitecore site (for example, with and without "/en" in the path). Having pages like this (or worse, internal links formed differently) can decrease search ranking. If the same page is at two URLs, and there are links to both, the "link juice" is diluted across those pages.

One way to overcome this is to issue a "canonical URL" meta tag. If you emit a meta tag with the same canonical URL on both pages, it informs the search engine which URL is "authoritative" for that page. The search engine will (theoretically) award all of the link juice to the canonical URL.

If you are using a common base layout class, the simplest thing to do would be to have the code-behind of that class hang the canonical meta tag in the page header. But in this case, the client did not have a common base layout.

This kind of thing has come up often enough that I was motivated to create a MetaTag management module. Different chunks of code need to create meta tags, and it’s not always convenient or even possible to limit the timing of meta tag generation to the layout.

This article only covers some highlight from the module. For more detail, see the full documentation at the Sitecore Marketplace.

Overview



Tags can be added four ways:

  1. By adding processors to the InjectMetaTags pipeline.
  2. In the content editor, by adding tag definitions to a GlobalTags folder (these tags appear site-wide).
  3. In the content editor, by selecting pre-defined tags in a field that can be added to any template (these tags appear on individual pages)
  4. In code, at any point in the page lifecycle. This allows code in layouts, sublayouts and renderings to add meta tags “ad hoc”.



Several tag "types" are support to simplify creation of tags in code or configuration:


  1. Static tags: Tags where both the name and value are static, such a “robots noindex”.
  2. Custom tags: Tags where either the name, value or both are generated by custom logic.
  3. Method tags: Tags where the name is static, and the value is derived from an existing static method.
  4. Property tags: Tags where the name is static, and the value is derived from an existing static property.

Method and Property tags allow creation of dynamic tags entirely in configuration, with no coding. These tags derive their values at runttime from existing methods or properties.


There seems to be two subspecies of meta tag markup, those that use a “property” attribute and those that use “name”. Both are still effectively name/value pairs. The “name” style tag seems to be more common, but notable sets of commonly-used tags (like OpenGraph tags) use the “property” structure. This module allows both styles.

Architecture


The module uses a collection of tag description objects (not markup) that persist through the page lifecycle. Tags are added to this collection in various ways, and are flushed to the head section of the page after pre-render. To flush the tags to the page, each is formed into a custom MetaTag control. 

No modifications to the solution’s code or markup are required; all of the artifacts and event hooks are created using pipeline processors added to the httpRequestBegin and insertRenderings pipelines.

Adding Tags From Code


Coders can add tags to the page in any point in the page lifecycle, using provided convenience methods.

    PageTags.AddTag(MetaTagType.name, "MyTag""This is my tag.");

Managing Tags in the Content Editor


Site administrators can create site-wide tags by adding "StaticMetaTag" and "DynamicMetaTag" items to the appropriate folder in the Modules section of the content tree. Items added to the "GlobalTags" folder are emitted on every page; items added to the "OptionalTags" folder are available for content authors to use selectively in their pages (see below).


The definition of a StaticMeta tag is simple; just specify the tag type ("name" or "property"), and the key and value.


To define a dynamic tag, you must first create a simple "Dynamic Processor" class that exposes properties for TagType, Key and Value. Sample Dynamic Processors are provided that emit tags for the Item ID, Template Key and Machine Name. Once this class is defined, you can add it by creating a DynamicMetaTag item and supplying the class signature for the dynamic processor.


namespace Arke.SharedSource.MetaTags.DynamicProcessors
{
  public class ItemID : IDynamicProcessor
  {
    public MetaTagType TagType { getset; }
    public string Key { getset; }
    public string Value { getset; }
 
    public ItemID()
    {
      TagType = MetaTagType.name;
      Key = "ItemID";
      Value = Sitecore.Context.Item.ID.ToString();
    }
  }
}


A base template is provided, which can be added to the base templates of any site template. This gives the content author an opportunity to include the pre-defined tags (those defined n the OptionalTags folder) in any given page.



Managing Tags in the InjectMetaTags Pipeline


The process for gathering, forming and injecting tags is itself managed with a custom pipeline. Developers can add custom tags by inserting processors into this pipeline. They can also change the behavior of the process by replacing existing processors.
For more information on how to manage processes in your solutions by creating custom pipelines, see "Put That in Your Pipe and Process It"

In addition to the processors that gather the meta tags defined in content (global and page-scoped), there are  other "demonstrator" processor included in the module. One shows how to implement a fully custom meta tag processor, using the "canonical" meta tag as an example.

There are also processors that allow you to leverage your "Dynamic Processors" or any static method (including any Sitecore static method) to add a global meta, entirely in configuration, without writing a single line of code. This is accomplished by adding processor nodes that have child nodes the define class signatures and names of the processor or static method to be used. 

Here's and example of a meta tag pipeline in config (I've shortened the type names for readability):

<Arke.MetaTags.InjectMetaTags>
  <processor type="Arke...CheckContextItem, Arke.SharedSource.MetaTags" />
  <processor type="Arke...CheckHeader, Arke.SharedSource.MetaTags" />
  <processor type="Arke...CanonialUrl, Arke.SharedSource.MetaTags" />
  <processor type="Arke...MethodTag, Arke.SharedSource.MetaTags">
    <TypeSignature>Sitecore.Context, Sitecore.Kernel</TypeSignature>
    <MethodName>GetSiteName</MethodName>
    <TagName>sc_site</TagName>
    <TagType>name</TagType>
  </processor>
  <processor type="Arke...GlobalTags, Arke.SharedSource.MetaTags" />
  <processor type="Arke...ItemTags, Arke.SharedSource.MetaTags" />
  <processor type="Arke...FlushMetaTags, Arke.SharedSource.MetaTags" />
</Arke.MetaTags.InjectMetaTags>






The source code for this module is available at the Sitecore Marketplace. You can also download the documentation file.

Saturday, March 9, 2013

Put That in Your Pipe and Process It

A teacher once told me "When faced with a problem you don't understand, solve any part of it that you do understand, and then step back and look at the problem again." It was supposed to be advice about math, but it is a good advice for troubleshooting any problem. It also taught me that complex problems and processes are best handled in small, discreet pieces.

If you read my blog about renderings, you've heard me lecture on the importance of granularity. When coding our solutions, we often implement complex processes, sequential processes. Sitecore gives us a great tool for making these processes granular and extensible with pipelines.

A pipeline is a framework for defining a process in a series of steps that are handled by individual processors. Developers implement the steps in code following a specified pattern, and define the ordering of these steps in a config file. The pipeline execution engine manages this functionality and exposes a number of supporting methods and properties.

Sitecore exposes many of its internal processes via pipelines, allowing us to do all kinds of magic by adding and modifying processors. Lots of cool enhancements to Sitecore have been shared around the community that leverage these open pipelines.Why don't we open our solutions up to future developers (and our future selves) by using this same technique?

Just like Sitecore has done with many of  its processes, we can take our solution's processes, break them down into a series of steps, and implement them with a pipeline. This will allow us to extend or modify the process later (perhaps even using classes in a different assembly) through configuration. This makes our solutions more transparent and more flexible. It leaves an open architecture that allows future developers to change the behavior of the process without changing the original code.

The example code in this article is taken from the MetaTag Manager Module available from the Sitecore Marketplace
The solution I'll use as an example is designed to manage Meta Tag Manager open source module. There are a number of "common" circumstances that influence the insertion of meta tags in that module: managed content items, logic for specialty tags, and a context object that code can use to insert meta tags. These each require their own set of code to manage. Knowing this, and knowing that in the future I might want to implement additional meta tag logic in the future, I used a pipeline to manage this task.

 

When to Use a Pipeline


Pipelines are a useful tools when you are creating sequential processes that represent significant functionality in your application. This might be something like a data consumer that periodically imports data (via a scheduled task) from an external system, or a process for generating markup as part of your page construction (as in the example pipeline in this article), or a process associated with application start-up,  publishing, or any other part of your solution.

Sitecore uses pipelines for most of the processes needed to render every page; this tells me that they should be reasonably efficient. Custom pipelines are most useful for complex processes that may need to be extended or modified later, with the convenience if not having to modify the original code.

 

Anatomy of a Pipeline


The Sitecore pipeline architecture exists to allow you to define a series of steps in a config file that, when executed in order, implement a process within the solution. The pipeline can be invoked from anywhere in your code where you might otherwise call one or more methods to achieve the same purpose.

The pieces of a pipeline are...

  • The pipeline definition. This is declared in a config file.
  • One or more pipeline processors. These represent the steps that could be used in the pipeline, and are implemented in code.
  • (Optional) A PipelineArgs class, which is implemented in code and is used to allow the steps in the pipeline pass data down the line.
  • The Sitecore.Pipelines.CorePipeline namespace, which contains all of the API needed to develop and invoke pipelines and pipeline processors.


In a pipeline, each step is defined using a class signature in the config file. The when the pipeline is run, Sitecore uses reflection to instantiate n instance of each processor class, and calls the Process method of that class.

 

Pipeline Args


It is usually helpful to be able to maintain some context during the execution of the pipeline, so that processors can pass data to each other. Sitecore instantiates a PipelineArgs class (or a custom class that inherits from PipelineArgs) when a pipeline is run. This instance is passed to each processor's Process method, allowing each step access to the PipelineArgs.

This PipelineArgs class exposes some useful methods to each processor. One important one is the AbortPipeline method. If a processor step detects that the pipeline should be terminated without calling the subsequent steps, it can call this method.

The PipelineArgs class also contains a SafeDictionary property called CustomData. Pipeline processors can add objects to this dictionary in order to pass information down the line as subsequent processors are invoked.

Rather than use the CustomData dictionary, I prefer to create a custom "args" class that inherits from Sitecore's PipelineArgs. I can then define properties that do not require casting to be used by pipeline steps. This is also a convenient place to put convenience or utility methods for the processor steps.


namespace Arke.SharedSource.MetaTags
{
 public class InjectMetaTagsPipelineArgs : PipelineArgs
 {
  public List<MetaTagItem> MetaTags;
 
  public InjectMetaTagsPipelineArgs()
  {
   this.MetaTags = new List<MetaTagItem>();
  }
 }
}


When using a custom PipelineArgs class, it is a good idea to create an Interface that our pipeline processors will implement. This ensures that each step is casting the args class properly.

namespace Arke.SharedSource.MetaTags.Pipelines
{
  public interface IInjectMetaTagsPipelineProcessor
  {
    void Process(InjectMetaTagsPipelineArgs args);
  }
}

 

Pipeline Processors


The steps in your pipeline are implemented with pipeline processors, representing the steps in the process that the pipeline implements. Each is implemented with a class that implements a Process method, which accepts a PipelineArgs argument. The pipeline runner instantiates these classes in turn, and calls the Process method, passing in the PipelineArgs object.

This is where you implement the logic for that step of the process. The processor may read from and.or write to the PipelineArgs object. It can abort the remainder of the pipeline with the AbortPipeline method.

For example, this processor runs early in the pipeline to make sure there is a context item, and aborts the pipeline if necessary:

namespace Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags
{
  public class CheckContextItem : IInjectMetaTagsPipelineProcessor
  {
    public void Process(InjectMetaTagsPipelineArgs args)
    {
      if (Sitecore.Context.Item == null)
      {
        Tracer.Warning(string.Concat("Not injecting meta tags; no context item"));
        args.AbortPipeline();
      }
    }
  }
}

This processor adds a "canonical" meta tag:

namespace Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags
{
  public class CanonialUrl : IInjectMetaTagsPipelineProcessor
  {
    public void Process(InjectMetaTagsPipelineArgs args)
    {
      Tracer.Info(string.Concat("Adding Canonical URL"));
      args.MetaTags.Add(new MetaTagItem(MetaTagType.name, "canonical"Settings.GetAuthorativeUrl()));
    }
  }
}

 

Architecting the Steps in a Pipeline


What pipeline steps you create, and what they do, is up to you. Remember that pipelines typically define a process in your solution. Sitecore has pipelines that define the processes for things like insertRenderings and publishItem. These steps in these pipelines do thing like detecting if the process is appropriate for the current item or context, building up or transforming data, moving data from one place to another, generating markup, cleaning up, logging messages and saving performance data.

When I'm building a process to be handled by a pipeline, I tend to think about Stephen Covey's advice about analysis and synthesis. To analyze means to break apart, to synthesize means to put together. A pipeline process often begins by analyzing (checking and transforming the input data, context and environment), and then ends with synthesizing the desired output.

What steps your pipeline should take depends on the nature of the task at hand. It is common to have the initial steps determine if the process should execute depending on the context or availability of data or objects, and to instantiate objects and data that will be needed by subsequent steps. The next steps actually perform the process in discreet steps, and the last steps clean up or do some logging.

Try to break the pipeline into very discreet steps. If you find that one of your steps is becoming "spaghetti," break it into multiple steps. Take logic that makes decisions and move them to separate steps. If there is data to be gathered that is used by subsequent steps, put the data gatherers into separate steps. This allows future developers to modify or extend the data-gathering, decision-making and output-producing steps, or to insert their own steps in between.

The pipeline in the example solution starts by checking if meta tags can be injected into the page (by validating the existence of a context item and a head section in the page). It then has a step for every group of tags that might be injected (depending on the nature of the tags), adding them to a collection stored in the PipelineArgs. Finally, it flushes the tags to the page.

By separating the sets of tags to be included, the application administrator can decide to exclude steps, say for example, the canonical URL tag, by removing them from the config. A developer can add logic to include a different set of tags by adding a step to this pipeline, which might call a class in an entirely separate assembly.

 

The Config File


The pipeline steps are defined in .config. This might be directly in web.config, or in an external config file. I'd recommend an external config file ... see this blog post.

Each step in the pipeline is defined with a processor node, which simply declares the type signature for that step of the pipeline.

A pipeline processor node can also have child nodes. The tag name in these nodes must map to property names on the class for that processor. Sitecore will inject the value (the text) of each node into the corresponding property in the class. This allows you to create more "general purpose" processor steps and hand properties to them at runtime.

<MetaTags.InjectMetaTags>
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.CheckContextItem, Arke.SharedSource.MetaTags" />
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.CheckHeader, Arke.SharedSource.MetaTags" />
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.CanonialUrl, Arke.SharedSource.MetaTags" />
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.MethodTag, Arke.SharedSource.MetaTags">
    <TypeSignature>Sitecore.Context, Sitecore.Kernel</TypeSignature>
    <MethodName>GetSiteName</MethodName>
    <TagName>sc_site</TagName>
    <TagType>name</TagType>
  </processor>
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.GlobalTags, Arke.SharedSource.MetaTags" />
  <processor type="Arke.SharedSource.MetaTags.Pipelines.InjectMetaTags.FlushMetaTags, Arke.SharedSource.MetaTags" />

 

Invoking the Pipeline


It's really very simple to invoke a pipeline. You simply call Sitecore.Pipelines.CorePipeline.Run("MyPipelineName", args), where MyPipelineName is the name of the pipeline in the config file, and args is an instance of PipelineArgs (or a custom class derived from it).

  InjectMetaTagsPipelineArgs args = new InjectMetaTagsPipelineArgs();
  Sitecore.Pipelines.CorePipeline.Run(Settings.PIPELINE_NAME, args);

Where to invoke the pipeline depends on what the pipeline does. Sometimes it needs to be invoked from a timed task, sometimes from another pipeline, sometimes from other places. If I have a situation where I need to extend an existing Sitecore pipeline with a complex task, I'll create my own pipeline and invoke it from Sitecore's pipeline. That makes maintenance much easier, because I can define it all in another config file and don't need to patch Sitecore's pipeline more than once.

First, we wire up the the appropriate existing pipeline:

  <pipelines>
      <insertRenderings>
        <processor
          type="Arke.SharedSource.MetaTags.Pipelines.InsertRenderings.InjectMetaTags, Arke.SharedSource.MetaTags"
          patch:after="processor[@type='Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings, Sitecore.Kernel']"
        />
      </insertRenderings>
  </pipelines>

The method we're wiring exists only to fire our custom pipeline:


  public void Process(InsertRenderingsArgs args)
  {
    Assert.ArgumentNotNull(args, "args");
 
    // Don't wire this up when in the sitecore shell
    if (Sitecore.Context.Site.Name.Equals("shell"StringComparison.InvariantCultureIgnoreCase))
    {
      Tracer.Warning("Meta tags not emitted in the shell site.");
      return;
    }
 
    // We'll wire up a handler for after prerender is complete, so any meta tags added
    // by controls (via Arke.SharedSource.MetaTags.PageTags) will be available.
    Sitecore.Context.Page.Page.PreRenderComplete += new EventHandler(RunPipeline);
 
  }

  void RunPipeline(object sender, EventArgs e)
  {
    Profiler.StartOperation("Adding Global MetaTags.");
    try
    {
      InjectMetaTagsPipelineArgs args = new InjectMetaTagsPipelineArgs();
      Sitecore.Pipelines.CorePipeline.Run(Settings.PIPELINE_NAME, args);
    }
    catch (Exception ex)
    {
      Sitecore.Diagnostics.Log.Error("InjectMetaTags failed", ex, "InjectMetaTags");
    }
    Profiler.EndOperation();
  }

Our pipeline in turn declares the steps that would otherwise have to be patched into Sitecore's pipeline, as shown in the config example shown before.



Next time you're building a process for your solution, consider using Sitecore's built-in tools for pipeline management. It may take a little more time now, but it'll make life easier later, when new requirements come down the pipe.



References:

Tuesday, February 12, 2013

Tag, You're it: Tracking Tag Management in Sitecore

As web marketers, a great deal of our strategy relies on hunting (we'll leave farming tactics, like social media, nurturing and personalization, for another day). Most of our hunting activities rely heavily on tracking. The wiki definition of tracking (in the hunting context) fits this quite well:
Tracking in hunting and ecology is the science and art of observing animal tracks and other signs, with the goal of gaining understanding of the landscape and the animal being tracked (quarry).
For web marketers, hunting requires an understanding of the web ecosystem and the behavior of our "quarry" within it, so tracking is very important to us. There has been an explosion in tracking technologies of late, most of which are based on injecting tracking tags into our pages. Our pages have more tags hanging off them than the discount rack at Macy's --- so much so that tracking tag management has become a hot service offering. Just Google tracking tag management and you'll find more tools than you can count.

These tools can be appealing. After all, we have so much tag content that we need to manage on our site.

Wait a minute ... "content" ... "manage" ... hmmm --- aren't we already working in a content management environment?

There's no doubt that we could build a superb tracking tag management system into Sitecore. When we do a deep dive into these tagging technologies, we find that the formation and injection of tags into our pages can become quite complicated, but Sitecore is the best system around for building complex content management architectures.


Simple tracking tag management in Sitecore


But let's start off simple. When you first get into tagging, you find that at its simplest, all you have to do is copy a tag snippet (typically some javascript) into your pages. You find  new tracking service you want to use, you paste their snippet into your pages, and you're off.

Simple as that sounds, our marketers can't just do that themselves. They need the developers to deploy the tags to the production servers, typically within layouts. But marketeers want things done now ... so why don't we simplify this process by creating support for simple tag injection?

The solution I'll describe here is pretty rudimentary. It assumes that you are tagging every page on your site with every tag you have. That's fine for a start; over time, we'll examine ways to create dynamic tags and associate tags with content more robustly.

We'll create templates to allow the tag markup to be managed as Sitecore content. Since we want the tags on every page, we'll use a pipeline processor to inject them into every page (rather than relying on layouts).

You can download the source and package for this solution from the Sitecore Marketplace.


The templates


First, a couple of templates. We will create other tag types over time, but for now we'll just create a template for "Html Tracking Tag" that just holds some static tag markup. We'll also create a folder template to hold all of our tag items. This just a template with no fields, but with Standard Values set with insert options for our tag template.


The HtmlTrackingTag template is simple; it just contains a memo field to hold the tag markup.


We'll create a TrackingTagFolder in our content, wherever we manage "globals".


I've added a couple of tag items, which contain simple tag markup copied from that service's site.



The code


First, we'll need a configuration file to register up our pipeline and manage our settings:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <settings>
            <setting name="TrackingTags.GlobalTagFolder" value="/sitecore/content/Global/TrackingTags" />
        </settings>
        <pipelines>
            <insertRenderings>
                <processor
                    type="Arke.SharedSource.TrackingTags.Pipelines.InsertRenderings.InsertTrackingTags, Arke.SharedSource.TrackingTags"
                    patch:after="processor[@type='Sitecore.Pipelines.InsertRenderings.Processors.AddRenderings, Sitecore.Kernel']"
                    />
            </insertRenderings>
        </pipelines>
    </sitecore>
</configuration>

And we'll create an associated settings class to make it simpler to access our settings (we only have one for now, but it's good practice).

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



To render the tags to the page, we'll create a simple web control that grabs the markup from the tag definition item and spits it to the page.

namespace Arke.SharedSource.TrackingTags
{
 public class HtmlTrackingTag : Sitecore.Web.UI.WebControl
 {
  System.Web.UI.WebControls.Literal container;
 
  public string TagItem { getset; }
 
  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);
   Assert.IsNotNull(item.Fields["Markup"], "Markup");
   string markup = item.Fields["Markup"].Value;
   container.Text = markup;
  }
 
  protected override void DoRender(HtmlTextWriter output)
  {
   EnsureChildControls();
   container.RenderControl(output);
  }
 
  protected override string GetCachingID() 
  { 
   return this.GetType().FullName; 
  }
 }
}

Finally, we'll use a pipeline processor to iterate over the global tags and inject a HtmlTrackingTag control into the page for each.

namespace Arke.SharedSource.TrackingTags.Pipelines.InsertRenderings
{
 public class InsertTrackingTags
 {
  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("Adding Tracking Tags.");
 
   foreach (Item globalTagItem in globalTagFolder.Children)
   {
    Arke.SharedSource.TrackingTags.HtmlTrackingTag control = 
     new Arke.SharedSource.TrackingTags.HtmlTrackingTag();
    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("Added tracking tag '", globalTagItem.Name, "'"));
    }
   }
 
   Profiler.EndOperation();
  }
 }
}

Note from the config file that we're putting our processor before Sitecore's AddRenderings processor.This puts our renderings at the top of the body part of the page.

If you look at the page in debug mode, you can see the script tag renderings.




Shortcomings of this solution

Of course, this is a bit of a dangerous solution. We've enabled content managers to manually inject script into the page. Either by accident or intent, a content owner could wreak havoc on the site. The tag definitions in globals should have good security to limit access only to trusted power users.

As I said before, this is a pretty simple solution. The obvious next step is to create a place to store "ad hoc" tags, and a rendering parameter template for the HtmlTrackingTag control. This would allow content manager to insert specific tag into specific pages.

Beyond this, a much more robust solution would include templates for the well-known tags so they could be managed more easily (by pasting in specific parameters into specific fields, rather than the entire tag). Dynamic tags that modify their behavior depending on context, template or rendering parameters could be built as well.

This solution allows the easy things to be easy, and the hard things will just have to wait till later. At least now, when we identify a new tracking service we want to implement, its as simple as "tag, you're it".





The source code and package for this solution are available at the Sitecore Marketplace.


Friday, January 25, 2013

Render Unto c#


When it comes to CMS development (among other things in life) I’m a big fan of granularity and reusability. I believe that in a good solution architecture, both content and code are managed in discreet, granular pieces, which promotes both consistency and reusability.

That’s why it bothers me that so many Sitecore professionals react to the word “rendering” the same way a horse would. To my mind, a good solution has a geometric ratio of layouts to sublayouts, and sublayouts to renderings. Yet I see projects that are extremely sublayout-centric, with content IA and logic governing page layout.

Sitecore’s arsenal of presentation management tools, such as layout details, placeholder settings and rendering parameters, allows us as developers to truly empower our content owners. When implemented well, these features give the content authors what I like to call “controlled control” over their pages.

Unfortunately, we often see solutions where sublayouts are the dominant presentation component. Sublayouts are far less efficient than renderings, both in terms of performance and management. With sublayouts, there are all the ascx files to manage and deploy. And using sublayouts to present content seems to promote having a single component (sublayout) present multiple fields. This can dramatically reduce the solution’s flexibility – or worse, lead to having multiple components that are slight variations on each other, or have cumbersome logic (often wired to “control” fields in the content) to suppress content or change the presentation behavior.

Worse, some solutions rely almost entirely on the content tree to govern layout, such as by having fields in page templates that change the behavior of the layout, and/or by having sets of child items that code “bubbles up” into the page when they are present.

So why are renderings so often left out of solution architecture? I suspect that the problem lies in Sitecore training. Although Sitecore trainers do point out the different ways that renderings can be created, they tend to use XSL as the example technology in class (probably because it’s quicker to demonstrate --the trainer can show changes to an XSL rendering immediately, without compiling). Regrettably, this leaves many with a linkage in their minds between renderings as a Sitecore artifact and XSL as a technology. The oft-maligned rendering can be implemented using multiple technologies, yet many, many developers believe that renderings can only be developed using XSL.

I’m not going to wade into the great XSL debate here. I personally like XSL, but I rarely use it in Sitecore projects, for a number of reasons that I’ll get into that in a separate post. Suffice it to say that many developers, even if they know XSL, want to avoid it if for no other reason than to make their projects sustainable. XSL is a far more rare skill than c#, so it makes sense to ensure that future developers will be able to extend and maintain the project. And since there’s this misconception that “renderings = XSL”, the “baby” of a rendering-based architecture gets thrown out with the “bathwater” of XSL. And that’s a shame.

So let’s set the record straight. Renderings can and should be developed in c#. Actually, John West points out in his book “Professional Sitecore Development,” there are four types of renderings:
  1. XSL renderings
  2. Method renderings
  3. URL renderings
  4. Web Controls
Of these, Web Control renderings – controls that are implemented entirely in code and deployed in assemblies – are the least used yet most useful presentation component available. (In my next post, I’ll delve into the anatomy of a web control rendering.)

As a simple example, consider a page with a “core content” (“body”) area consisting of a title, a main image, and some body text. These three fields are defined in the page’s template. One way of handling this is to create a sublayout that renders these fields to the output (hopefully, at least, using field renderers). But what happens when the author does not want a title on a particular page (this is a simple example, so let’s not quibble over usability or SEO). Sure, the sublayout’s code-behind could suppress the <h1> when the field is empty or null. Or we could have a checkbox in the template to suppress the title.

What if the content author wants something other than a main image, like a flash or a video? What if they need to insert something between the image and the body? And after the body, they might need set of “spots” to point to other content?

So we might resort to having different sublayouts with variations on the content. This can lead to an unmanageable mess, creating confusion as to which sublayout does what. It also leads to redundant code, which makes ongoing maintenance and modification to the site much more challenging.

Another solution would be to put fields in the template to suppress content, or add content, or modify the presentation of content. Or we might create templates for child items that, when present, are bubbled up into the page. This puts management of presentation into the data. Sitecore is so well architected to give us excellent separation of content and presentation, so why fight that and force content to manage presentation?

I much prefer solutions that have very “light” layouts and sublayouts, with lots of renderings bound to placeholders. For the simple example, I would have a separate rendering each for title, main image, and body text, which I would bind to a placeholder in the sublayout for the core content area. Standard values in the item’s template would bind them by default, but the content owner would have the freedom to change the presentation as required. We can use features like thumbnails, rendering parameters, placeholder settings and compatible renderings both to assist them in the layout process, and to enforce brand or visual design requirements.

Most of my layouts and sublayouts are little more than div’s and placeholders. They exist to manage the geometry of the page or of regions of the page, not to present the actual content. Renderings bound to placeholders actually emit the content. Rendering parameter templates allow the editor to influence the source and behavior of the content in the page. Now, control over presentation and layout are managed in the presentation layer, and content is managed in the content layer. The design of the IA can break the content down into more manageable chunks, promoting reusability and avoiding redundancy.

To be fair, there are times when sublayouts are a better choice than renderings. For example, for forms or other situations where postback is required, I refer to use sublayouts (ascx) controls.. Also, in cases where the parts of the page structure are immutable, it is more efficient to statically bind renderings into sublayouts (by including them in the sublayout markup). This is fine for cases like fixed headers and footers, or when the site design requires an element (like a title) to always be present. There are also rare occasions when I allow a folder of child items to bubble up into a page, but even then, I usually use a placeholder-bound rendering to do the bubbling.

A highly granular architecture, which maintains separation of content from presentation, is hugely empowering to both developers and content editors. It promotes reusability of both code and content, shifts much of the responsibility for page assembly from code to configuration, and empowers editors with more control over the layout of their pages.