(For introduction to the new publishing architecture, read the part 1: New Publishing Pipelines and Events in Sitecore 6)
Today’s example is using the publish:itemProcessed event to publish related media items.
A little background first. Imagine a new item structure being created, and some content items have an image field that uses items from the media library. Neither the content items nor the media items have been published yet. Now if the editor publishes the content item in a “single-item” mode (i.e. selects the publish in the ribbon, and not the incremental, smart or full publishing), the item will get published to the web database, but the media items will not.
The event handler below listens to the publish:itemProcessed event, and if the content item had been published in the single-item mode and has links to media items, they get published too.
public class ItemProcessedHandler {
public void ItemProcessed(object sender, EventArgs rawArgs) {
var args = rawArgs as ItemProcessingEventArgs;
Assert.IsNotNull(args, "args");
var context = args.Context;
// [1] publish mode check
if (context.PublishOptions.Mode != PublishMode.SingleItem) {
return;
}
var item = context.PublishHelper.GetSourceItem(context.ItemId);
if (item == null) {
return;
}
if (!item.Paths.IsContentItem) {
return;
}
// [2] Triggering publishing of the related item by running the publishItem pipeline again
var options = new PublishOptions(
context.PublishOptions.SourceDatabase,
context.PublishOptions.TargetDatabase,
PublishMode.SingleItem,
context.PublishOptions.Language,
context.PublishOptions.PublishDate);
var relatedMedia = GetRelatedMedia(item);
foreach(var mediaItem in relatedMedia) {
PublishItemPipeline.Run(mediaItem.ID, options);
}
}
// [3] related media items are retrieved using the link database
IList- GetRelatedMedia(Item item) {
var references = Globals.LinkDatabase.GetReferences(item);
var result = new List
- ();
foreach(var reference in references) {
if (reference.SourceDatabaseName != item.Database.Name) {
continue;
}
var referenceItem = item.Database.GetItem(reference.TargetItemID);
if (referenceItem == null) {
continue;
}
if (referenceItem.Paths.IsMediaItem) {
result.Add(referenceItem);
}
}
return result;
}
}
Notes:
- Check the publish mode – no need to intervene in the incremental or full publishes, Sitecore will publish everything needed by itself
- Programmatically running the publishItem pipeline for each media item. Higher level PublishManager API could have been used as well
- Link database is used to retrieve the related media items. Nothing new here.
To activate the event:
<event name="publish:itemProcessed">
<handler type="Pipelines.Publishing.ItemProcessedHandler, Pipelines" method="ItemProcessed" />
</event>