Skip to content

Instantly share code, notes, and snippets.

@willprice76
Last active September 1, 2015 15:07
Show Gist options
  • Save willprice76/0d4ca03f65f9193a3640 to your computer and use it in GitHub Desktop.
Save willprice76/0d4ca03f65f9193a3640 to your computer and use it in GitHub Desktop.
Custom Renderer to Extend SmartTarget indexing metadata to include Keyword Key
using System;
using System.Xml;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.Publishing;
using Tridion.ContentManager.Publishing.Rendering;
using Tridion.ContentManager.Publishing.Resolving;
namespace Example.SmartTarget
{
/// <summary>
/// Custom Renderer to extend SmartTarget publishing metadata to add a new index field for each keyword field
/// which contains the keyword Key.
/// </summary>
public class Renderer : IRenderer
{
private const String KEY_SUFFIX = "_key";
public void Render(ResolvedItem resolvedItem, PublishInstruction instruction, PublicationTarget target, RenderedItem renderedItem, RenderContext renderContext)
{
if (resolvedItem.IsDynamicComponentPresentation && renderedItem.Metadata!=null)
{
var metas = renderedItem.Metadata;
for (int i=0; i< metas.Count;i++)
{
if (metas[i].Name == "SmartTarget")
{
//Find all keywords on all the DCPs
foreach (XmlElement node in metas[i].SelectNodes("Component/Keyword"))
{
Keyword keyword = (Keyword)target.Session.GetObject(node.GetAttribute("id"));
if (keyword!=null && !String.IsNullOrEmpty(keyword.Key))
{
var componentRoot = node.ParentNode.SelectSingleNode("Source/*");
foreach (XmlElement field in GetKeywordFields(componentRoot, keyword))
{
var keyNode = field.OwnerDocument.CreateElement(field.Name + KEY_SUFFIX, field.NamespaceURI);
keyNode.InnerText = keyword.Key;
field.ParentNode.InsertAfter(keyNode, field);
}
}
}
}
}
}
}
/// <summary>
/// Gets the fields in component XML that have a certain keyword value.
/// Note that this is a rather simple method that does matching based on
/// The keyword Title. If you happen to have non-keyword text fields with
/// the same value, or keywords in different categories with the same value
/// you might get unexpected results
/// </summary>
/// <param name="componentRoot">component XML</param>
/// <param name="keyword">keyword to look for</param>
/// <returns>list of field elements</returns>
protected XmlNodeList GetKeywordFields(XmlNode componentRoot, Keyword keyword)
{
var title = keyword.Title;
var delimiter = "'";
if (title.Contains("'"))
{
if (title.Contains("\""))
{
//If title contains both double and single quotes we skip it, as its tricky to select these elements using XPath
return null;
}
delimiter = "\"";
}
var xpath= String.Format("//*[text()={1}{0}{1}]",keyword.Title, delimiter);
return componentRoot.SelectNodes(xpath);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment