Thursday, 30 January 2014

How to publish referenced (linked) items in sitecore?

Have you come across a situation where you want to publish all referenced (linked) items while publishing any item in sitecore? If yes, then you are at correct place. Continue reading...

The default behavior of sitecore is to publish only selected item. Now think that if you have added few images to sitecore item and you want to publish these newly added (linked) images automatically when you publish that item.
How can you achieve it? Well, answer is - we need to pick all references of publishing item and add all these reference items to publishing queue pro-grammatically. That's it.

How to achieve it?
namespace Customization.Sitecore
    public class PublishReferenceItemsPipeline : PublishProcessor
        private Database _sourceDatabase;
        public override void Process(PublishContext context)
            Assert.ArgumentNotNull(context, "context");
            Log.Info(GetType().FullName + ": Adding items to publish queue - START", this);
            _sourceDatabase = context.PublishOptions.SourceDatabase;
            IEnumerable<ID> publishQueueItems = FetchPublishQueueItems(context.PublishOptions);
            IEnumerable<ID> publishQueueReferencedItems = publishQueueItems.SelectMany(GetReferences).ToArray();
            IEnumerable<PublishingCandidate> publishingCandidates = publishQueueReferencedItems.Select(itemId => new PublishingCandidate(itemId, context.PublishOptions)).ToArray();
            Log.Info(GetType().FullName + ": Adding items to publish queue - END", this);

        private IEnumerable<ID> FetchPublishQueueItems(PublishOptions options)
            if (options.Mode == PublishMode.Incremental)
                return PublishQueue.GetPublishQueue(options).Select(candidate => candidate.ItemId).ToArray();
            return PublishQueue.GetContentBranch(options).Select(candidate => candidate.ItemId).ToArray();

        private IEnumerable<ID> GetReferences(ID itemID)
            Item item = _sourceDatabase.GetItem(itemID);
            if (item == null)
                return Enumerable.Empty<ID>();
            ItemLink[] references = Globals.LinkDatabase.GetReferences(item);
            return references.Select(reference => reference.TargetItemID).ToArray();
Next step is to hook this newly created processor to Sitecore.Publishing.Pipelines.Publish.AddItemsToQueue processor of sitecore.
We have 2 options to hook our processor:

1) Add <processor type="Customization.Sitecore.PublishReferenceItemsPipeline, Customization.Sitecore" /> after <processor type="Sitecore.Publishing.Pipelines.Publish.AddItemsToQueue, Sitecore.Kernel"/> in web.config file.

2) If you don't want to touch web.config then second option is suitable for you. Add a .config file under App_Config folder.

Give any meaningful name to it. I will name it like "PublishingReference.config"
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="">
        <processor type="Customization.Sitecore.PublishReferenceItemsPipeline, Customization.Sitecore" patch:after="*[@type='Sitecore.Publishing.Pipelines.Publish.AddItemsToQueue, Sitecore.Kernel']"/>

Customize your publishing, make your life easy !!!