Sitecore CMS and everything related RSS 2.0
 Friday, August 08, 2008

(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:

  1. Check the publish mode – no need to intervene in the incremental or full publishes, Sitecore will publish everything needed by itself
  2. Programmatically running the publishItem pipeline for each media item. Higher level PublishManager API could have been used as well
  3. 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>
Friday, August 08, 2008 8:44:30 AM (FLE Standard Time, UTC+02:00)  #    Comments [4] -
Sitecore | Crestone
Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
Blogroll
 Alex de Groot
Few words about SiteCore from Holland
 Alexander Shyba
Sitecore Support
 Anders Dreyer
Anders Dreyer on Sitecore Development
 Jakob Christensen
Sitecore Core Development
 Lars Fløe Nielsen
Lars's ramblings about development and business processes
 Ole Thrane
Sitecore API
 Runi Thomsen
Runi Thomsen Sitecore Toughts
 The Sitecore Experience
The Sitecore Experience
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008
Alexey Rusakov
Sign In
Statistics
Total Posts: 199
This Year: 49
This Month: 3
This Week: 0
Comments: 0
Themes
Pick a theme:
All Content © 2008, Alexey Rusakov
DasBlog theme 'Business' created by Christoph De Baene (delarou)