In this blog post I wanted to show a more advanced feature available in SDL Tridion, this feature gives developers a more deeper control on the Transport Package. Unfortunately this nice feature is neither documented nor supported but I think it is good enough to show how to use it in a Blog Post.
Developing a Transport Handler is very similar to developing other Tridion extension points like Resolvers or Event Systems. So, let’s provide a list of steps in order to develop one. In this sample I am writing a Transport Handler that overrides the existing TaxonomyTransportHandler in order to add the user that published the Category in the Instructions document.
1. Implement a class that inherits ITransportHandler interface. This interface is not available in the DLLs available in /bin/client, you have to reference Tridion.ContentManager.Publishing.Transporting.dll that is in the GAC
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Tridion.ContentManager.Publishing.Rendering;
using Tridion.ContentManager.Publishing.Resolving;
using Tridion.ContentManager.Publishing.Transporting;
namespace TransportHandlers {
public class CustomTaxonomyTransportHandler : ITransportPackageHandler {
private TaxonomyTransportPackageHandler _defaultTaxonomyHandler;
private XmlDocument _defaultInstructionsDocument;
private string _user;
public CustomTaxonomyTransportHandler(TransportPackage package) {
_defaultTaxonomyHandler = new TaxonomyTransportPackageHandler(package);
_defaultInstructionsDocument = package.InstructionsDocument;
_user = package.PublishTransaction.Creator.Title;
}
public void HandleItemForPublishing(object item, XmlElement parentElement) {
_defaultTaxonomyHandler.HandleItemForPublishing(item, parentElement);
}
public XmlElement HandleRenderedItemForPublishing(RenderedItem renderedItem, XmlElement parentElement) {
XmlElement customCategoryElement = _defaultInstructionsDocument.CreateElement("CustomCategoryInfo");
customCategoryElement.InnerXml = string.Format("<Category>{0}</Category><User>{1}</User>", renderedItem.ResolvedItem.Item.Id, _user);
_defaultInstructionsDocument.DocumentElement.AppendChild(customCategoryElement);
return _defaultTaxonomyHandler.HandleRenderedItemForPublishing(renderedItem, parentElement);
}
public void HandleResolvedItemForUnPublishing(ResolvedItem resolvedItem) {
_defaultTaxonomyHandler.HandleResolvedItemForUnPublishing(resolvedItem);
}
}
}
2. The class above should be compiled in an Strong Name Assembly and registered in the GAC
3. Register it in the Tridion.ContentManager.config configuration file
<transporting rootStorageFolder="c:\Temp">
<mappings>
.
.
.
<add itemType="Tridion.ContentManager.ContentManagement.Category">
<handler type="TransportHandlers.CustomTaxonomyTransportHandler" assembly="TransportHandlers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b4b2f6e0f11afc8" />
</add>
.
.
.
</mappings>
</transporting>
4. Restart the TcmPublisher Windows Service
5. Publish any Publishable Category, as a Result you will see a custom Xml Element appended in the Transport Package Instructions document
<ProcessorInstructions version="7.1.0.1290">
<Publication Id="tcm:0-3-1" Title="400 Example Site" Key="400 Example Site" PublicationPath="\" PublicationUrl="/" MultimediaPath="\media" MultimediaUrl="/media/" />
<Action>Deploy</Action>
<Target Type="6" />
<CustomCategoryInfo>
<Category>tcm:3-29-512</Category>
<User>T2013SP1\Administrator</User>
</CustomCategoryInfo>
<Section Type="Taxonomies" Name="Taxonomies">
<Taxonomy Id="tcm:3-29-512" Name="tcm_3-29-512.xml" UseForIdentification="False" />
</Section>
</ProcessorInstructions>