Skip to content

Instantly share code, notes, and snippets.

@bkoopman
Last active January 9, 2017 20:13
Show Gist options
  • Save bkoopman/6436263 to your computer and use it in GitHub Desktop.
Save bkoopman/6436263 to your computer and use it in GitHub Desktop.
[TcmTemplateTitle("Add ECL Metadata into Package and Component")]
public class AddEclMetadataIntoPackageAndComponent : Base.TemplateBase
{
// ecl metadata fieldname
const string SkuField = "sku";
public override void Transform(Engine engine, Package package)
{
Initialize(engine, package);
if (IsPageTemplate)
{
// log error
Logger.Error("This Template Building Block is only supposed to be used on a Component Template.");
return;
}
// get component xml from package
Item componentItem = package.GetByType(ContentType.Component);
string componentUri = componentItem.GetAsSource().GetValue("ID");
XmlDocument doc = componentItem.GetAsXmlDocument();
// get value from ecl metadata
string sku = GetEclMetadata(componentUri, SkuField);
// create a namespace manager to resolve the namespaces
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("tcm", Tridion.Constants.TcmNamespace);
Component component = (Component)engine.GetObject(componentUri);
nsmgr.AddNamespace("custom", component.MetadataSchema.NamespaceUri);
// add sku field to component metadata (field must be defined in ecl stub schema)
XmlNode metadata = doc.DocumentElement.SelectSingleNode("/tcm:Component/tcm:Data/tcm:Metadata/custom:Metadata", nsmgr);
XmlNode skuNode = metadata.SelectSingleNode("custom:" + SkuField, nsmgr);
if (skuNode == null)
{
skuNode = doc.CreateNode(XmlNodeType.Element, SkuField, component.MetadataSchema.NamespaceUri);
skuNode.InnerText = sku;
metadata.AppendChild(skuNode);
// update component xml in package (updates are not saved to cms)
componentItem.SetAsXmlDocument(doc);
// add to actual component
UpdateComponentMetadataField(component, SkuField, sku);
Logger.Info(string.Format("'{0}' field added with value: {1}", SkuField, sku));
}
else if (!skuNode.InnerText.Equals(sku))
{
skuNode.InnerText = sku;
// update component xml in package (updates are not saved to cms)
componentItem.SetAsXmlDocument(doc);
// update actual component
UpdateComponentMetadataField(component, SkuField, sku);
Logger.Info(string.Format("'{0}' field updated to value: {1}", SkuField, sku));
}
}
// this method requires allowWriteOperationsInTemplates to be set to: true
// see http://sdllivecontent.sdl.com/LiveContent/content/en-US/SDL_Tridion_2013/concept_547C3E9D9A684B00BB8CB498B8AF7BBD
// (requires login - http://docportal.sdl.com/sdltridion)
private void UpdateComponentMetadataField(Component component, string field, string value)
{
if (component.IsShared)
{
TcmUri parentUri = new TcmUri(component.Id.ItemId, component.Id.ItemType, component.OwningRepository.Id.ItemId);
CheckInitialized();
component = (Component)m_Engine.GetObject(parentUri);
}
ItemFields metadataFields = new ItemFields(component.Metadata, component.MetadataSchema);
component.CheckOut();
((SingleLineTextField)metadataFields[field]).Value = value;
component.Metadata = metadataFields.ToXml();
component.Save(true);
}
private string GetEclMetadata(string eclOrTcmUri, string name)
{
CheckInitialized();
using (IEclSession eclSession = SessionFactory.CreateEclSession(m_Engine.GetSession()))
{
IEclUri eclUri = eclOrTcmUri.StartsWith("tcm:") ? eclSession.TryGetEclUriFromTcmUri(eclOrTcmUri) : eclSession.HostServices.CreateEclUri(eclOrTcmUri);
if (eclUri != null)
{
using (IContentLibraryContext context = eclSession.GetContentLibrary(eclUri))
{
IContentLibraryMultimediaItem eclItem = (IContentLibraryMultimediaItem)context.GetItem(eclUri);
if (!string.IsNullOrEmpty(eclItem.MetadataXml))
{
XNamespace ns = GetNamespace(eclItem.MetadataXml);
XDocument metadata = XDocument.Parse(eclItem.MetadataXml);
XElement property = (from xml in metadata.Descendants(ns + name) select xml).FirstOrDefault();
if (property != null)
{
return property.Value;
}
}
}
}
}
return string.Empty;
}
private static string GetNamespace(string xml)
{
// ecl metadata string looks like <Metadata xmlns="..">..</Metadata>
const string nsAttribute = "xmlns=\"";
int start = xml.IndexOf(nsAttribute);
int end = xml.IndexOf('\"', start + nsAttribute.Length);
return xml.Substring(start + nsAttribute.Length, end - start - nsAttribute.Length);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment