3

I have a requirement where Authors don't want to go to media item to publish it and then then actual content item.

Publish related items has been disabled as it is publishing way more items than required and in some cases publishing items that are not supposed to go at that point of time.

Is there a way/module to enable users to Publish Related Media Items only? This way we can have at least some control on the items that are getting published along with the content item.

2 Answers 2

3

If you only want to publish related media items, there are a few things you'll need to do.

Disclaimer

It sounds like workflow would work best to satisfy your use-case and reduce the number of customizations you need to make. That would be my first recommendation. However, an outline for what you've asked for is below.

Remove Existing Processors From getItemReferences

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <getItemReferences>
        <patch:delete />
      </getItemReferences>
      <getItemReferences>
        <!-- Finds linked media items on related items -->
        <processor type="MyNamespace.GetRelatedMediaItems, MyDll" />
      </getItemReferences>
    </pipelines>
  </sitecore>
</configuration>

Notice how I've also included a processor to meet your needs-- GetRelatedMedaiItems.

GetRelatedMediaItems Processor

namespace MyNamespace
{
    public class GetRelatedMediaItems : GetItemReferencesProcessor
    {
        protected override List<Item> GetItemReferences(PublishItemContext context)
        {
            Assert.ArgumentNotNull(context, nameof(context));
            var objList = new List<Item>();
            if (context.PublishOptions.Mode != SitecorePublishing.PublishMode.SingleItem)
                return objList;
            switch (context.Action)
            {
                case SitecorePublishing.PublishAction.PublishSharedFields:
                    var sourceItem = context.PublishHelper.GetSourceItem(context.ItemId);
                    if (sourceItem == null)
                        return objList;
                    objList.AddRange(GetReferences(sourceItem, true));
                    break;
                case SitecorePublishing.PublishAction.PublishVersion:
                    var versionToPublish = context.VersionToPublish;
                    if (versionToPublish == null)
                        return objList;
                    objList.AddRange(GetReferences(versionToPublish, false));
                    break;
                default:
                    return objList;
            }
            return objList;
        }

        private IEnumerable<Item> GetReferences(Item item, bool sharedOnly)
        {
            Assert.ArgumentNotNull(item, nameof(item));
            var sharedFilter = sharedOnly ? (Func<ItemLink, bool>)SharedFilter : link => true;

            return item
                .Links
                .GetValidLinks()
                .Where(sharedFilter)
                .Select(link => link.GetTargetItem())
                .Where(Is.NotNull)
                .SelectMany(GetLinkedMediaItems);
        }

        private static bool SharedFilter(ItemLink source)
        {
            var sourceItem = source.GetSourceItem();
            if (sourceItem == null)
                return false;
            return ID.IsNullOrEmpty(source.SourceFieldID) || sourceItem.Fields[source.SourceFieldID].Shared;
        }

        private static IEnumerable<Item> GetLinkedMediaItems(Item item)
        {
            return item
                .Links
                .GetValidLinks()
                .Select(link => link.GetTargetItem())
                .Where(Is.NotNull)
                .Where(target => target.Paths.IsMediaItem) // this is they key
                .SelectMany(
                    target =>
                        target
                            .GetAncestorsUntil(parent => parent.ID == ItemIDs.MediaLibraryRoot, true) // you can remove this step if you wish.  this ensures the parents to a media item are published to ensure the media item ACTUALLY gets published
                            .Reverse()
                );
        }
    }
}

Then, it is important to note that you would instruct your Content Authors to select the Publish related items option.

2
  • +1 for adding workflow to the content items so they don't get published until they're ready to go. Oct 31, 2018 at 14:54
  • 1
    @jrap: Thanks for the detailed response. I also thought of the workflow first but apparently our authors and reviewers are same people. Also, they don't want the hassle of "Lock and Edit" items.
    – Shaurya
    Nov 1, 2018 at 8:19
0

Yes. You can take a look at Sitecore.Buckets.Pipelines.Publish.AddBucketFoldersToQueue class. It adds bucket folder to publishing queue whenever item from the bucket is published. Then add your implementation in <publishing> pipeline in appropriate place. Blog post

1
  • OP is not asking about buckets, so this seems like an incomplete solution. If there is more relevant content in the linked blog post you think would solve OP's issue, can you add it directly into your answer? (Answers should be able to stand alone without links.) Oct 31, 2018 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.