After a long and time consuming projects it’s now time for another post:)
Today I’m going to show some examples of Gutters I use when developing and that we recommend editors to use. But first of lets look at what a Gutter is.
A Gutter is an indicator that displays any kind of simple information of an item to the left of the Content Tree in the Content Editor like this:
Image may be NSFW.
Clik here to view.
What kind of information is up to you. I’m going to show two simple examples to indicate if:
- if related items of an item has been published and if it is the latest version.
- a media items is used anywhere.
To be able to create a Gutter we will have to create a class that inherits from Sitecore.Shell.Applications.ContentEditor.Gutters.GutterRenderer and override the GetIconDescriptor method. If we want to indicate something we return a GutterIconDescriptor and if we have nothing to indicate we return null. So lets start with the first example to indicate if related items are published and if it’s the latest versions. I going to call my class “RelatedItemsPublishedNotification”, easy and simple Image may be NSFW.
Clik here to view.
public class RelatedItemsPublishedNotification : Gutters.GutterRenderer { protected override GutterIconDescriptor GetIconDescriptor(Item item) { return null; } }
This is the base class for the Gutter. What we want to do is to get all related items, in other words all links of that item. This is done by calling item.Links.GetAllLinks() which will return an array of ItemLink. A ItemLink isn’t the actual Item, we will have to get the item from the Master database using the TargetItemID attribute. Now you might ask why I don’t use the GetTargetItem method? Well it seems like this method checks with the web database and returns a valid version and if non exist the latest. So if we want to compare versions later on we will have to do like this.
Since we want check if it is published we will have to check if the item exist in the Web database. If it doesn’t exist I want to return a GutterIconDescriptor that tells the user “A related item is not published!”. The Gutter also displays a Icon and I’ve choosen the Network/16×16/environment_error.png icon. I also want to isolate the usage of this Gutter to the sitecore/content section of the Content Tree which I will do by checking if the item path starts with /sitecore/content/
public class RelatedItemsPublishedNotification : Sitecore.Shell.Applications.ContentEditor.Gutters.GutterRenderer { protected override GutterIconDescriptor GetIconDescriptor(Sitecore.Data.Items.Item item) { if (!item.Paths.FullPath.StartsWith("/sitecore/content/")) return null; var itemLinks = item.Links.GetValidLinks(); var webDb = Factory.GetDatabase("web"); var masterDb = Factory.GetDatabase("master"); foreach (var itemLink in itemLinks) { var masterItem = masterDb.GetItem(itemLink.TargetItemID); var webItem = webDb.GetItem(masterItem.ID); if (webItem == null) { var descriptor = new GutterIconDescriptor(); descriptor.Icon = "Network/16x16/environment_error.png"; descriptor.Tooltip = "A related item is not published!"; return descriptor; } } return null; } }
So this will indicate if a related item hasn’t been published. I also wants to indicate if it isn’t the latest version. To do this I will have to compare the version numbers of the item in the web and the master. If the item in the master database have a higher version number I want to tell the user “A related items latest version has not been published!” and indicate with another icon Network/16×16/environment_warning.png. Like this:
public class RelatedItemsPublishedNotification : Sitecore.Shell.Applications.ContentEditor.Gutters.GutterRenderer { protected override GutterIconDescriptor GetIconDescriptor(Sitecore.Data.Items.Item item) { if (!item.Paths.FullPath.StartsWith("/sitecore/content/")) return null; var itemLinks = item.Links.GetValidLinks(); var webDb = Factory.GetDatabase("web"); var masterDb = Factory.GetDatabase("master"); foreach (var itemLink in itemLinks) { var masterItem = masterDb.GetItem(itemLink.TargetItemID); var webItem = webDb.GetItem(masterItem.ID); if (webItem == null) { var descriptor = new GutterIconDescriptor(); descriptor.Icon = "Network/16x16/environment_error.png"; descriptor.Tooltip = "A related item is not published!"; return descriptor; } if (masterItem.Version.Number > webItem.Version.Number) { var descriptor = new GutterIconDescriptor(); descriptor.Icon = "Network/16x16/environment_warning.png"; descriptor.Tooltip = "A related items latest version has not been published!"; return descriptor; } } return null; } }
The Gutter is now complete and it’s time to configure it in Sitecore. This is really simple and is all done in the Core database and are stored at /sitecore/content/Applications/Content Editor/Gutters. Just duplicate on of the available Gutter nodes like the one called “Locked Items”. Alter the text in the Header field to something like “Related Items Published” and change the Type to the namespace, assembly of the class. I my example it’s Pyramid.Utils.Gutters.RelatedItemsPublishedNotification, Pyramid.Utils. And now you’re done. You will now be able to activate the new Gutter in the Sitecore Content Tree.
Image may be NSFW.
Clik here to view.
Now lets dive into the other Gutter which will indicate if a media item is being used, and tell how often it is being used using the tooltip. This is kind of straight forward. After some digging around in the Sitecore assemblies looking at how Sitecore displays the usage in the Media Library folder view I found out that I can get all references to an item by calling Sitecore.Globals.LinkDatabase.GetReferrers(item); This will return an array of ItemLinks which represent all items that reference to the current item. And by using the length of the array I’ll get the usage count. So basically the class will look like this:
public class MediaInUseNotification : GutterRenderer { protected override GutterIconDescriptor GetIconDescriptor(Sitecore.Data.Items.Item item) { if (!item.Paths.FullPath.StartsWith("/sitecore/media library/")) return null; var referrers = Globals.LinkDatabase.GetReferrers(item); if (referrers.Length == 0) return null; var descriptor = new GutterIconDescriptor(); descriptor.Icon = "Business/16x16/paperclip_delete.png"; descriptor.Tooltip = string.Format("This media items is used {0}!", referrers.Length == 1 ? "1 time" : referrers.Length + " times"); return descriptor; } }
When configured in Sitecore the result will look like this:
Image may be NSFW.
Clik here to view.
Kind of cool huh? Well you can do more Image may be NSFW.
Clik here to view. You can actually add a command on the Click event of the Gutter. This is done on the GutterIconDescriptor object that is return. Find the command you want to run and add it like this before returning the descriptor:
descriptor.Click = String.Format("pagedesigner:reset(id={0})", item.ID);
This click event will trigger the pagedesigner:reset command with the current item id as parameter which will reset the current items layout definitions to standard values. This is a snippet from an older Gutter that in later Sitecore version has been implemented as an default Gutter (Presentation Overridden).
Thats all for now