Often users are curious why when they publish articles, the media associated with this article was not published.

There is one simple explanation - media items/assets in Sitecore are considered as separate content items and should be published separately.

Thanks to the powerful Sitecore Workflow engine that can be easily extended using workflow actions, it is possible to publish related media items by means of a special workflow action.

So by simply adding a workflow action before the Auto Publish action with the logic below, you will ensure that the relations will be published before the actual item:


The code of the workflow action:

using System;

using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Links;
using Sitecore.Publishing;
using Sitecore.Workflows.Simple;

namespace WebApp.Customizations
{     public class PublishRelationsAction     {         public void Process(WorkflowPipelineArgs args)         {             Item dataItem = args.DataItem;

            // Find all related items             ItemLink[] itemLinks = dataItem.Links.GetValidLinks();

            foreach (ItemLink link in itemLinks)             {                 Item itm = link.GetTargetItem();

                // publishing related media items - the ones that were referenced by the workflow item                 // this can be extended - you can publish related aliases also                 if (itm != null && itm.Paths.IsMediaItem)                 {                     PublishItem(itm);                 }             }         }

        private void PublishItem(Item item)         {             PublishOptions options = new PublishOptions(PublishMode.SingleItem, item.Language, DateTime.Now);             options.RootItem = item;             options.Deep = false;             options.SourceDatabase = item.Database;             // publishing to the web database             // production scenarios may have different publishing targets             // this can be handled by some more advanced logic,             // for example retrieving parameterized targets from the workflow action             options.TargetDatabase = Factory.GetDatabase("web");             new Publisher(options).Publish();         }     } }

Related reading:

The caveats:

  1. If media items are associated with another workflow, they should be in the final state.
  2. Obviously this solution works when you are using workflow. Other solutions such as handing of publish:end events does not seem to be as easy as workflow action. In this case it could be better to introduce a one step workflow with one initial state "Editing" and final "Published" with such action attached.

Thanks to Alexander Tsvirchkov for investigation and code and Kim Hornung