Home » Customization » Omit HTML Breaks From Rendered Multi-Line Text Fields in Sitecore

Omit HTML Breaks From Rendered Multi-Line Text Fields in Sitecore

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

Tweets

Earlier today while preparing a training session on how to add JavaScript from a Multi-Line Text field to a rendered Sitecore page, I encountered something I had seen in the past but forgot about: Sitecore FieldControls and the FieldRenderer Web Control will convert newlines into HTML breaks.

For example, suppose you have the following JavaScript in a Multi-Line Text field:

javascript-in-field

You could use a Text FieldControl to render it:

<%@ Control Language="c#" AutoEventWireup="true" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<sc:Text ID="scJavaScript" Field="JavaScript" runat="server" />

Unfortunately, your JavaScript will not work since it will contain HTML breaks:

html-breaks-in-rendered-value

Why does this happen? In the RenderField() method in Sitecore.Web.UI.WebControls.FieldRenderer — this lives in Sitecore.Kernel.dll, and is called by all FieldControls — passes a “linebreaks” parameter to the <renderField> pipeline:

field-renderer-html-breaks

The Process() method in Sitecore.Pipelines.RenderField.GetMemoFieldValue — this serves as one of the “out of the box” processors of the <renderField> pipeline — converts all carriage returns, line feeds, and newlines into HTML breaks:

get-memo-field-value

What can we do to prevent this from happening? Well, you could spin up a new class with a Process() method to serve as a new <renderField> pipeline processor, and use that instead of Sitecore.Pipelines.RenderField.GetMemoFieldValue:

using System;

using Sitecore.Diagnostics;
using Sitecore.Pipelines.RenderField;

namespace Sitecore.Sandbox.Pipelines.RenderField
{
    public class GetRawMemoFieldValueWhenApplicable
    {
        public void Process(RenderFieldArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if(!AreEqualIgnoreCase(args.FieldTypeKey, "memo") && !AreEqualIgnoreCase(args.FieldTypeKey, "multi-line text"))
            {
                return;
            }

            bool omitHtmlBreaks;
            if (bool.TryParse(args.Parameters["omitHtmlBreaks"], out omitHtmlBreaks))
            {
                return;
            }

            Assert.IsNotNull(DefaultGetMemoFieldValueProcessor, "DefaultGetMemoFieldValueProcessor must be set in your configuration!");
            DefaultGetMemoFieldValueProcessor.Process(args);
        }

        private static bool AreEqualIgnoreCase(string stringOne, string stringTwo)
        {
            return string.Equals(stringOne, stringTwo, StringComparison.CurrentCultureIgnoreCase);
        }

        private GetMemoFieldValue DefaultGetMemoFieldValueProcessor { get; set; }
    }
}

The Process() method in the class above looks for an “omitHtmlBreaks” parameter, and just exits out of the Process() method when it is set to true — it leaves the field value “as is”.

If the “omitHtmlBreaks”parameter is not found in the RenderFieldArgs instance, or it is set to false, the Process() method delegates to the Process() method of its DefaultGetMemoFieldValueProcessor property — this would be an instance of the “out of the box” Sitecore.Pipelines.RenderField.GetMemoFieldValue, and this is passed to the new <renderField> pipeline processor via the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <renderField>
        <processor patch:instead="processor[@type='Sitecore.Pipelines.RenderField.GetMemoFieldValue, Sitecore.Kernel']"
                   type="Sitecore.Sandbox.Pipelines.RenderField.GetRawMemoFieldValueWhenApplicable, Sitecore.Sandbox">
          <DefaultGetMemoFieldValueProcessor type="Sitecore.Pipelines.RenderField.GetMemoFieldValue, Sitecore.Kernel" />
        </processor>  
      </renderField>
    </pipelines>
  </sitecore>
</configuration>

Let’s test this.

I added the “omitHtmlBreaks” parameter to the control I had shown above:

<%@ Control Language="c#" AutoEventWireup="true" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<sc:Text ID="scJavaScript" Field="JavaScript" Parameters="omitHtmlBreaks=true" runat="server" />

When I loaded my page, I was given a warm welcome:

alert-box-welcome

When I viewed my page’s source, I no longer see HTML breaks:

javascript-no-html-breaks

If you have any thoughts on this, or know of another way to do this, please share in a comment.

Advertisements

14 Comments

  1. we used asp:Literal control to render the MLT field value to prevent line-breaks,but this approach is better anyway!!

  2. wensveen says:

    Hi Mike,
    I’ve created a RawFieldRenderer control for this purpose:
    public class RawFieldRenderer : FieldControl
    {
    protected override void DoRender(System.Web.UI.HtmlTextWriter output)
    {
    Item item = GetItem();
    if (item != null && Field != null && !item.IsFieldNullOrEmpty(Field))
    {
    output.Write(item[Field]);
    }
    }
    }
    (IsFieldNullOrEmpty is a little extension method that checks if the field exists and contains any data)
    I like the omitHtmlBreaks param idea as well. Literals are okay too, but require code-behind.

  3. Jan Sommer says:

    Hi
    An alternative for writing all that code you could do this:
    <sc:fieldrenderer runat="server" FieldName="hesting" Parameters='’ />
    Remember to call DataBind() in your code behind or above the fieldrenderer.

    • This will not work since the “linebreaks” parameter is in the RenderParameters dictionary, not Parameters on the args instance.

      • Jan Sommer says:

        Try it out. It works on my Sitecore 7 instance.

      • I will give it a go.

        Thanks!

        Mike

      • Jan Sommer says:

        I got curious after your comment. My code works because of the SetParameters pipeline in renderField which contains a function called MoveLineBreaksParameterToRender. Check it out!

      • Jan Sommer says:

        setParameters pipeline = setParameters processor

      • Ah ha! Another great find!

        Thanks again!

        Mike

      • I got your solution working!

        Thanks again!

        Mike

      • wensveen says:

        Haha, the “MoveLineBreaksParameterToRender” function. That doesn’t sound hacky *at all*.
        But seriously, it might be a little dangerous depending on an undocumented feature like this, which may or me not be removed in future versions. But then again, it does work and without any code. It’s a cool find, in any case.

      • Jan Sommer says:

        I’m sure it’s safe to use this undocumented feature. It’s in Sitecore 6 and Sitecore 7, so I’m pretty sure it’s going to be in Sitecore 8 unless they break their API.

  4. Jan Sommer says:

    Seems like there a problem showing code…
    Inside parameters you should write: <%# “line-breaks=\n” %>
    if not > and < is shown correctly they should be replaced with > and <

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: