Sitecore
Sitecore How To: Show Section Icons in the Content Editor
May 11, 2017 Pete Navarra

In more recent Sitecore updates the section icons in the Content Editor seemed to have gone away. There are a couple options for you to get these icons showing up again.

Sitecore supports two ways to render the Content Editor.

  1. Standard Sitecore Render
  2. Themed XML Skin Rendering

The pipeline you want to focus on is

<renderContentEditor>

 You'll find the following: 

<renderContentEditor>
    <processor type="Sitecore.Shell.Applications.ContentEditor.Pipelines.RenderContentEditor.RenderSkinedContentEditor, Sitecore.Client"/>
	<processor type="Sitecore.Shell.Applications.ContentEditor.Pipelines.RenderContentEditor.RenderStandardContentEditor, Sitecore.Client"/>
</renderContentEditor>

In this post I'll focus on how to override the Standard Content Editor. I would probably advocate for using the Theme/Skinning option that is available, but will need to defer that answer until I am more versed in how to do the themeing.

If you look at Sitecore.Shell.Applications.ContentEditor.Pipelines.RenderContentEditor.RenderStandardContentEditor pipeline process you'll find that it is calling the EditorFormatter class RenderSections(...)

 public class RenderStandardContentEditor
  {
    /// Gets the field value.
    ///The arguments.
    /// 
    ///   
    /// 
    public void Process(RenderContentEditorArgs args)
    {
      Assert.ArgumentNotNull((object) args, "args");
      args.EditorFormatter.RenderSections(args.Parent, args.Sections, args.ReadOnly);
    }
  }</span></pre>

Digging down further, you'll find that RenderSections is calling RenderSectionBegin(...).

 

The real issue with the Section Icon going away is that Sitecore decided just not to render the image. But as you can see from the decompiled code below, Sitecore still supports the section icon, just never utilizes it.

public void RenderSectionBegin(System.Web.UI.Control parent, string controlId, string sectionName, string displayName, string icon, bool isCollapsed, bool renderFields)
{
  Assert.ArgumentNotNull((object) parent, "parent");
  Assert.ArgumentNotNullOrEmpty(controlId, "controlId");
  Assert.ArgumentNotNullOrEmpty(sectionName, "sectionName");
  Assert.ArgumentNotNullOrEmpty(displayName, "displayName");
  Assert.ArgumentNotNull((object) icon, "icon");
  HtmlTextWriter htmlTextWriter = new HtmlTextWriter((TextWriter) new StringWriter(new StringBuilder(1024)));
  if (this.Arguments.ShowSections)
  {
    string str1 = isCollapsed ? "scEditorSectionCaptionCollapsed" : "scEditorSectionCaptionExpanded";
    string str2;
    if (UserOptions.ContentEditor.RenderCollapsedSections)
      str2 = "javascript:scContent.toggleSection('" + controlId + "','" + sectionName + "')";
    else
      str2 = "javascript:return scForm.postRequest('','','','" + StringUtil.EscapeQuote("ToggleSection(\"" + sectionName + "\",\"" + (isCollapsed ? "1" : "0") + "\")") + "')";
    htmlTextWriter.Write("<div id=\"{0}\" class=\"{1}\" onclick=\"" + str2 + "\">", (object) controlId, (object) str1);
    ImageBuilder imageBuilder1 = new ImageBuilder()
    {
      ID = controlId + "_Glyph",
      Src = isCollapsed ? "Images/accordion_down.png" : "Images/accordion_up.png",
      Class = "scEditorSectionCaptionGlyph"
    };
    htmlTextWriter.Write(imageBuilder1.ToString());
    ImageBuilder imageBuilder2 = new ImageBuilder()
    {
      Src = Images.GetThemedImageSource(icon, ImageDimension.id16x16),
      Class = "scEditorSectionCaptionIcon"
    };
    htmlTextWriter.Write(Translate.Text(displayName));
    htmlTextWriter.Write("</div>");
  }
  if (renderFields || !isCollapsed)
  {
    string str1 = !isCollapsed || !this.Arguments.ShowSections ? string.Empty : " style=\"display:none\"";
    string str2 = this.Arguments.ShowSections ? "scEditorSectionPanelCell" : "scEditorSectionPanelCell_NoSections";
    htmlTextWriter.Write("<table width=\"100%\" class=\"scEditorSectionPanel\"{0}><tr><td class=\"{1}\">", (object) str1, (object) str2);
  }
  this.AddLiteralControl(parent, htmlTextWriter.InnerWriter.ToString());
}

Note that in this class, the icon comes in as part of the argument of the method. Highlighting the following piece: 

 

ImageBuilder imageBuilder2 = new ImageBuilder()
{
    Src = Images.GetThemedImageSource(icon, ImageDimension.id16x16),
    Class = "scEditorSectionCaptionIcon"
}:
htmlTextWriter.Write(Translate.Text(displayName));
htmlTextWriter.Write("</div>");

imageBuilder2 contains everything that we need to know in order to render the Section icon. however, scanning this method, imageBuild2 is never utilized. Instead, immediately after imageBuilder2 is created, it writes the displayName.

 

However, if you look at the accordion image just above this:

ImageBuilder imageBuilder1 = new ImageBuilder()
{    
	ID = controlId + "_Glyph",
	Src = isCollapsed ? "Images/accordion_down.png" : "Images/accordion_up.png",
	Class = "scEditorSectionCaptionGlyph" 
};
htmlTextWriter.Write(imageBuilder1.ToString());

You'll note that it's sending the image to the htmlTextWriter which sets up an awesome example as how to implement the section icon as well. 

 

In Summary

This actually smells like a Sitecore Bug. However, if it's completely intentional, and you want to activate the icon, I would create a custom RenderContentEditor pipeline processor, extend the EditorFormatter class and override RenderSectionBegin method, sending the icon to the HtmlTextWriter.

OP ED

Based on the amount of code changes that are required to add the display icon back in may not be worth it (in fact, it's not worth it).

One must take into consideration upgradability, and maintainability.

Using a new processor, as described above, allows you to pull out the change relatively quickly and the approach above does not harm core functionality. However, if changes occur with this class (as they most certainly will) in order to maintain the icons, you'd have to update this custom class.

Lastly, while my professional recommendation is to not utilize all of this, just for the icon, and nor do I think creating a whole new XML Skin just for icon make sense either, this is a often requested feature from client who are used to the section icon.

Therefore my true feeling is to appeal to Sitecore to offer an easier toggle, config setting or otherwise, in order to display it. Otherwise, I would advocate against trying to implement this at all.

But it is possible! =)

Pete Navarra
Development Manager