Sitecore publish certain items on save

My Sitecore solution have some items, where changes to certain fields are so critical that they need to be published immediately. So when my user presses the Save button, I will open a popup dialog, asking if I should publish the change:

Catalog Changed

Catalog Changed

If you click OK, the item is published.

EXTENDING THE SAVEUI PIPELINE

To achieve this, you have several tools in the Sitecore toolbox. One is to extend the SaveUI pipeline. This operation requires me to hook in just after the Save processor, as we need to publish the saved changes:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:env="http://www.sitecore.net/xmlconfig/env/">
  <sitecore>
    <processors>
      <saveUI>
        <processor patch:after="processor[@type='Sitecore.Pipelines.Save.Save, Sitecore.Kernel']" type="MyCode.MyProcessor, MyDll" />
      </saveUI>
    </processors>
  </sitecore>
</configuration>

CREATING A SAVEUI PROCESSOR

The processor consists of 2 parts: One that checks if the template have been saved and shows the dialog box, and another that publishes the item if the user clicks yes in the box:

using System;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Publishing;

namespace MyCode
{
  public class Myprocessor
  {
    // If this template is changed we request a publish
    private static ID _TEMPLATE_ID = new ID("{C24F3426-F599-482E-BBAA-A50645AD3304}");

    public void Process(Sitecore.Pipelines.Save.SaveArgs args)
    {
      Assert.ArgumentNotNull(args, "args");

      if (!args.HasSheerUI)
      {
        return;
      }

      // This piece of code is executed when the user clicks
      // on yes or no in the dialog box
      if (args.IsPostBack)
      {
        Context.ClientPage.Modified = false;
        if (args.Result == "yes")
        {
          foreach (Sitecore.Pipelines.Save.SaveArgs.SaveItem uiItem in args.Items)
          {
            Item dbItem = Context.ContentDatabase.GetItem(uiItem.ID, uiItem.Language, uiItem.Version);
            // PublishItem is an extension metod. I'll explain this one later
            dbItem.PublishItem(PublishMode.SingleItem, true, false, false, false);
          }
        }
        return;
      }

      Assert.IsNotNull(Context.ContentDatabase, "Sitecore.Context.ContentDatbabase");
      foreach (Sitecore.Pipelines.Save.SaveArgs.SaveItem uiItem in args.Items)
      {
        // This code checks if it is the template in question that have been saved
        Item dbItem = Context.ContentDatabase.GetItem(uiItem.ID, uiItem.Language, uiItem.Version);
        if (dbItem.TemplateID == _TEMPLATE_ID)
        {
          // Yes, the template have been saved, but do not ask for a publish
          // if the item is not publishable
          if (!dbItem.Publishing.IsPublishable(DateTime.Now, false))
            return;
          // Show the popup dialog and wait for the respone
          Sitecore.Web.UI.Sheer.SheerResponse.Confirm($"You have changed this catalog. You need to publish it. Would you like to publish now?");
          args.WaitForPostBack();
          return;
        }
      }
    }
  }
}

PUBLISH ITEM USING AN EXTENSION METHOD:

UPDATE 2019-09-13: There is another way of publishing. Read Sitecore Publish Items using the PublishManager for an improved way of publishing.

To do the publish I created this Item extension method:

namespace MyNamespace
{
  public static class ItemExtensions
  {
    public static void PublishItem(this Item item, PublishMode publishMode, bool publishAsync = false, bool deepPublish = false, bool publishRelatedItems = false, bool compareRevisions = false)
    {
      if (item == null)
        return;

      PublishOptions publishOptions = new PublishOptions(item.Database, Database.GetDatabase("web"), publishMode, item.Language, DateTime.Now);
      publishOptions.RootItem = item;
      publishOptions.Deep = deepPublish;
      publishOptions.PublishRelatedItems = publishRelatedItems;
      publishOptions.CompareRevisions = compareRevisions;

      Publisher publisher = new Publisher(publishOptions);
      if(publishAsync)
        publisher.PublishAsync();
      else
        publisher .Publish();
    }
  }
}

FINAL NOTE: BEWARE OF THE CTRL+S BUG IN SITECORE

Sitecore have a bug where the save event is called twice when clicking CTRL+S instead of the [Save] button. This can mess up the SheerResponse and can lead to your checkboxes and dropdowns to be emptied. The bug is easy to fix:

Sitecore CTRL+S fires item:saving event twice

MORE TO READ:

 

 

Advertisements

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in .net, c#, Sitecore 6, Sitecore 7, Sitecore 8, Sitecore 9 and tagged , , . Bookmark the permalink.

1 Response to Sitecore publish certain items on save

  1. Pingback: Sitecore Publish Items using the PublishManager | Brian Pedersen's Sitecore and .NET Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.