Showing posts with label Processors. Show all posts
Showing posts with label Processors. Show all posts

Thursday, 10 December 2020

Custom Header Icon for your items?

Custom Header Icon for your Items?

On many occasions I have thought it would be nice to be able to display a different icon in the header of an item, rather than the one chosen for the template.  For example you might want a different icon based on the some status or perhaps an image relating to the item context.  For example a head-shot of a member of staff.

In this example I will show you how I change the header icon based on an image field on that item.  But hopefully you will see that the possibilities are endless.

The example I am using is based on an import I built, that created faculty/staff items in the content tree, for an educational institution.  I thought it would be a nice touch to display the faculty member's image as the header icon, if there was an image attached to the item.

What am I changing?

This processor will switch out the icon shown top left of the image below with a custom image:


And the end result:
 

How do you do it?

We need to add our pipeline processor to the Render Content Editor Header pipeline, which needs to come before the Add Title pipeline processor:
<pipelines>
	<renderContentEditorHeader>
		<processor type="MyProject.Feature.Image.Processors.GetEditorIcon, MyProject.Feature.Image"
		           patch:before="processor[@type='Sitecore.Shell.Applications.ContentEditor.Pipelines.RenderContentEditorHeader.AddTitle, Sitecore.Client']" resolve="true" />
	</renderContentEditorHeader>
</pipelines>
And here's the custom processor:
namespace MyProject.Feature.Image.Processors
{
	public class GetEditorIcon
	{
		private readonly ISitecoreService _sitecoreService;

		public GetEditorIcon(ISitecoreServiceFactory sitecoreServiceFactory)
		{
			_sitecoreService = sitecoreServiceFactory.CreateInstance();
		}

		public void Process(RenderContentEditorHeaderArgs args)
		{
			Assert.ArgumentNotNull(args, "args");
			var item = args.Item;
			using (var htmlTextWriter = new HtmlTextWriter(new StringWriter()))
			{
				var imageBuilder = new ImageBuilder();

				if (item.TemplateID == Constants.MemberDetailsPage)
				{
					var provider = _sitecoreService.GetItem<FacultyStaffMember>(item.ID.Guid);
                    
					if (!string.IsNullOrEmpty(provider?.FacultyMemberProfileImage?.Src))
					{
						var src = provider.FacultyMemberProfileImage.Src;

						var urlString =
							new UrlString(src + "?height=32&width=32")
							{
								["rev"] = item[FieldIDs.Revision],
								["la"] = item.Language.ToString()
							};
						imageBuilder.Src = urlString.ToString();
						imageBuilder.Class = "scEditorHeaderIcon";
						htmlTextWriter.Write("<span class=\"scEditorHeaderIcon\">");
						htmlTextWriter.Write(imageBuilder.ToString());
						htmlTextWriter.Write("</span>");

						//Remove other icon added
						args.Parent.Controls.Clear();
						args.EditorFormatter.AddLiteralControl(args.Parent, 
                        	                    htmlTextWriter.InnerWriter.ToString());
					}
				}
			}
		}
	}
}
The process method does the following:
  • Checks the template of the item to ensure that it is using the template we are wanting to update.
  • We then get the item (in this case using GlassMapper), but you could just use the Sitecore item
  • We then build the image HTML and replace the Sitecore one in the header

This processor gets called every time the item is refreshed in the Content Editor.