Say goodbye to Widows and Orphans

In typesetting, a widow is the final word of a paragraph or heading if it falls down on the next line. This is an example of bad typhography and should be corrected if possible.

Our goal with the new property is basically to put a non-breaking space between the last two words in all headings, thus in effect gluing them together and forcing them onto the next line.

Create a new class that inherits from EPiServer.Web.WebControls.Property and add the code below.

public class Hn : Property {
    public string Heading {
        get { return (string)(ViewState["Heading"] ?? "h1"); }
        set { ViewState["Heading"] = value; }
    }
    protected override void Render(HtmlTextWriter output) {
        if (InnerProperty != null) {
            EnsurePropertyControlsCreated();
            if (InnerProperty.Value != null) {
                output.WriteBeginTag(Heading);
                if (InnerProperty is EPiServer.Core.PropertyString) {
                    string value = InnerProperty.ToWebString().Trim();
                    string[] fragments = InnerProperty.ToWebString().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (fragments.Length > 2) {
                        value = string.Empty;
                        for (int i = 0; i < fragments.Length; i++) {
                            if (i == fragments.Length - 2)
                                value += fragments[i] + " ";
                            else
                                value += fragments[i] + " ";
                        }
                    }
                    output.Write(value.Trim());
                } else {
                    base.RenderChildren(output);
                }
                output.WriteEndTag(Heading);
            } else if (string.IsNullOrEmpty(PropertyName.Trim())) {
                output.WriteLine("[Error: PropertyName is not set.]");
            } else if (((PageBase)Page).CurrentPage == null) {
                if (DisplayMissingMessage)
                    output.WriteLine("[Error: Property is contained in a page/control/template that does not have a current page.]");
            } else if (((PageBase)Page).CurrentPage.Property[PropertyName] == null) {
                if (DisplayMissingMessage) {
                    output.WriteLine("[Error: No property \"{0}\".]", PropertyName);
                }
            } else
                output.WriteLine("[Error: Unknown error.]");
        }
    }
}

To use the control you need to have a separate string property on your template like this:

New property on template

Next, add the new control to a page and enjoy your shiny new headings without any widows.

<Kloojed:Hn runat="server" PropertyName="Heading" />
  1. Thanks for sharing a very good idea! /Fredrik

Leave a comment

Use markdown syntax to add formating to your comment.

Enter 2FF, but type the second character two times.