Sitecore CMS and everything related RSS 2.0
 Monday, September 15, 2008

Sitecore’s renderField pipeline is a supporting pillar for the Page Editor. The pipeline ties together XSL and .NET field rendering code into one and provides a single place to affect how each field type (rich text, image, link) is rendered on the website.

It doesn’t matter if the field is being output using XSL extension methods (sc:field, sc:image), XSL controls (<sc:text />, <sc:image />) or the new family of .NET web controls (Sitecore.Web.UI.WebControls.FieldRenderer, Date, Image, etc) – the renderField pipeline is always the one that provides the actual output.

How does this support the Page Editor? Whenever a page is being run in the page editor mode, the renderField pipeline knows that and renders additional html/javascript around each field.

How is the pipeline useful to you? The ability to hook into a field rendering process and modify the look of any field on a website is a powerful feature. For example you could completely change the way some or all images are rendered, or merely postprocess the rich text fields, like in the following example. This pipeline would also interest implementers of new field types, because it’s now possible to teach standard output methods to render third party fields types.

The code below checks all links rendered as a part of the rich text field and adds the “external” CSS class to all external links. This can be useful to style external links differently, like using different colors or adding an icon next to them.

public class MarkExternalLinks {
  public void Process(RenderFieldArgs args) {
    if (args.FieldTypeKey != "html" && args.FieldTypeKey != "rich text") {
      return;
    }

    if (!args.Result.ToString().ToLower().Contains("<a")) {
      return;
    }

    var firstPart = new HtmlDocument();
    firstPart.LoadHtml(args.Result.FirstPart);
    MarkLinks(firstPart);
    args.Result.FirstPart = firstPart.DocumentNode.OuterHtml;
  }

  private void MarkLinks(HtmlDocument document) {
    var nodes = document.DocumentNode.SelectNodes("//a");
    if (nodes == null || nodes.Count == 0) {
      return;
    }

    foreach (var node in nodes) {
      if (node.GetAttributeValue("href", string.Empty).Contains("http")) {
        var className = node.GetAttributeValue("class", string.Empty);
        if (className.Length > 0) {
          className += " ";
        }

        className += "external";
        node.SetAttributeValue("class", className);
      }
    }
  }
}

OK, what happens here? First, the check for the field type is performed. This processor is only designed to alter the output of html and rich text fields. If the field contains any links, output is being processed using the Html Agility Pack. The rendered field is stored in args.Result. The reason for having both FirstPart and LastPart is to render fields that can have other content embedded in them, such as general link; rich text fields only have the FirstPart.

Now the processor needs to be placed in web.config. I’m putting it just before the RenderWebEditing processor, so that it doesn’t affect the additional links rendered to support Page Editor. It’s also important that it comes after the GetLinkFieldValue processor:

<renderField>
  <processor type="Sitecore.Pipelines.RenderField.GetFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.ExpandLinks, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.GetLinkFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.GetInternalLinkFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.GetMemoFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.GetDateFieldValue, Sitecore.Kernel"/>
  <processor type="Sitecore.Pipelines.RenderField.AddBeforeAndAfterValues, Sitecore.Kernel"/>
  <processor type="Pipelines.MarkExternalLinks, Pipelines" />
  <processor type="Sitecore.Pipelines.RenderField.RenderWebEditing, Sitecore.Kernel"/>
</renderField>

Once again, here are the different ways of properly rendering a field:

  1. sc:field XSL extension method, and the family of field type specific methods such as the sc:image, sc:link, sc:date and so on
  2. XSL controls: <sc:text />, <sc:image />, <sc:date /> and so on
  3. The Sitecore.Web.UI.WebControls.FieldRenderer web control, and a family of field type specific web controls, such as Sitecore.Web.UI.WebControls.Image, Date, etc [new]
  4. The Sitecore.Web.UI.WebControls.FieldRenderer.Render() shortcut method. Use it when having the web control is not desirable, and you’d rather just have a string. [new]

It’s important to understand when the renderField pipeline is not used:

  1. sc:fld XSL extension method returns raw field value, bypassing the pipeline.
  2. Field values read using the Sitecore API (item[“FieldName”] or item.Fields[“FieldName”].Value) also return raw values.
  3. Any static html included in the aspx or ascs files is also not processed.

Consequently, these are also the ways of supporting the new Page Editor in Sitecore 6: as long as you output the field using any of the options from the first list so that the renderField is used, you’re automatically getting the full Page Editor support.

In the next post I’ll focus on the new FieldRenderer web control and the family of field controls, added to make rendering fields in .NET to be as easy as using XSL controls.

Monday, September 15, 2008 6:33:45 AM (FLE Standard Time, UTC+02:00)  #    Comments [1]
Sitecore | Crestone
Tuesday, September 16, 2008 5:12:24 PM (FLE Standard Time, UTC+02:00)
This is very cool. I like the new pipeline

You should consider renaming the sc:fld extension to sc:rawfld. In 5 and backwords this methods functionality is now represented in sc:field. This means that upgraded sites will have sc:fld in all their XSLT's, which is unwanted.
Comments are closed.
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Blogroll
 Alex de Groot
Few words about SiteCore from Holland
 Alexander Shyba
Sitecore Support
 Anders Dreyer
Anders Dreyer on Sitecore Development
 Jakob Christensen
Sitecore Core Development
 Lars Fløe Nielsen
Lars's ramblings about development and business processes
 Ole Thrane
Sitecore API
 Runi Thomsen
Runi Thomsen Sitecore Toughts
 The Sitecore Experience
The Sitecore Experience
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010
Alexey Rusakov
Sign In
Statistics
Total Posts: 211
This Year: 0
This Month: 0
This Week: 0
Comments: 0
Themes
Pick a theme:
All Content © 2010, Alexey Rusakov
DasBlog theme 'Business' created by Christoph De Baene (delarou)