Belangrijke mededeling over deze pagina:

Deze pagina is niet beschikbaar in het Nederlands en daarom wordt de Engelse versie van het artikel getoond. Dit komt vooral voor bij technische artikelen.

Someone on StackOverflow asked if it is possible to display some kind of indication showing whether or not an item has been published. This is not possible by default, but I decided to quickly throw some code together and created a GutterRenderer for this.

You can find the StackOverflow question here: http://stackoverflow.com/questions/15172346/sitecore-flag-new-items-as-unpublished-items

Sitecore doesn't give us any indication of an item's publication status by default, but it's very easy to create a so called GutterRenderer to provide users with this information.
So let's build our GutterRenderer!
The class will first retrieve all the publishing targets and then check those targets for the existance of the item the gutter is being rendered for.
There are three possible results:

1) The item was not published to any of the targets
2) The item was published to at least one of the targets
3) The item was published to all the targets

The gutter will then display an icon that indicates the state of the item (1 = red, 2 = yellow, 3 = green).
When you click on the gutter icon, the Publish dialog will be shown for that item.

This is the code for our renderer:

using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor.Gutters;

namespace ParTech.Library.Gutters
{
  public class PublicationStatus : GutterRenderer
  {
    private readonly ID publishingTargetsFolderId = new ID("{D9E44555-02A6-407A-B4FC-96B9026CAADD}");
    private readonly ID targetDatabaseFieldId = new ID("{39ECFD90-55D2-49D8-B513-99D15573DE41}");

    protected override GutterIconDescriptor GetIconDescriptor(Item item)
    {
      bool existsInAll = true;
      bool existsInOne = false;

      // Find the publishing targets item folder
      Item publishingTargetsFolder = Context.ContentDatabase.GetItem(publishingTargetsFolderId);

      if (publishingTargetsFolder == null)
      {
        return null;
      }

      // Retrieve the publishing targets database names
      List publishingTargetsDatabases = publishingTargetsFolder.GetChildren()
        .Select(x => x[targetDatabaseFieldId])
        .ToList();

      // Check for item existance in publishing targets
      publishingTargetsDatabases.ForEach(delegate(string databaseName)
      {
        if (Database.GetDatabase(databaseName).GetItem(item.ID) != null)
        {
          existsInOne = true;
        }
        else
        {
          existsInAll = false;
        }
      });

      // Return descriptor with tooltip and icon
      string tooltip = Translate.Text("This item has not yet been published");
      string icon = "People/16x16/flag_red.png";

      if (existsInAll)
      {
        tooltip = Translate.Text("This item has been published to all targets");
        icon = "People/16x16/flag_green.png";
      }
      else if (existsInOne)
      {
        tooltip = Translate.Text("This item has been published to at least one target");
        icon = "People/16x16/flag_yellow.png";
      }

      return new GutterIconDescriptor()
      {
        Icon = icon,
        Tooltip = tooltip,
        Click = string.Format("item:publish(id={0})", item.ID)
      };
    }
  }
}

You need to setup the gutter in the Core database, like this:


When this is done, you can activate the gutter by right-clicking the gutter area (left side of the tree) and selecting your gutter, like this:


And here is the result of this all:


Enjoy!

BTW: The screenshots come from the development environment of our new upcoming website; a complete redesign and rebuild in Sitecore 6.6 with MVC!
Stay tuned :-)

6 Reacties

  • Door Ruud van Falier op 8/23/2013 om 2:00 PM

    Hi Reinoud,

    Thanks for the suggestion about the info dialog. When I get to a point where I need it in a project, I will add it and update the module here.

    The revision field seems a good choice to determine whether an item has changed. The alternative (comparing fields) would ruin the performance.

    Cheers!
    Ruud

  • Door Reinoud van Dalen op 8/23/2013 om 7:31 AM

    Nice work. Was looking to see if somebody had already found a solution. Didn't think to use the gutter, nice touch. What I would like to see as well is a comparison on fields, but this needs to exlude certain types because they are meant to differ, any thoughts on that?

    I found Sitecore uses the Revision field to determine if an item is changed (smart publish uses this field). I use this to show a yellow flag for changes, red for not published at all. Maybe add a info dialog in the future to show more details about targets, languages and version.

    Multiple comments were merged into one by the administrator.

  • Door Ruud van Falier op 4/19/2013 om 11:04 AM

    Chackrapani,

    You don't need to change those fields. They represent the ID of the Publishing Targets folder that is located in your master database and of the ID of the Target database field from the publishing target template. Those values are Sitecore's default values and will never change.

    Good luck!

  • Door Chackrapani op 4/2/2013 om 6:36 AM

    I need some further clarification about your code. private readonly ID publishingTargetsFolderId = new ID("{D9E44555-02A6-407A-B4FC-96B9026CAADD}"); private readonly ID targetDatabaseFieldId = new ID("{39ECFD90-55D2-49D8-B513-99D15573DE41}"); I here, can you tell me what is publishingTargetsFolderId and targetDatabaseFieldId because, I don't get the idea of these item ids.
    Thank you.

  • Door Ruud van Falier op 3/19/2013 om 7:59 PM

    Thanks Mike!

    Having a lot of items will impact the performance for sure. It's never advised to have more than 100 children directly underneath one item, whether you use this gutter extension or not. So as long as you use best practice defining your tree, your performance is gonna be fine.

  • Door Mike Reynolds op 3/19/2013 om 7:58 PM

    This is an awesome solution!  Excellent work!
    Do you think there could be a slight performance impact when items retrieved aren't in cache?
    This would require items to be pulled from the database directly.

    Kind regards,
    Mike Reynolds

Plaats een reactie