EPiPattern: How to render valid xhtml (part 1/2)

How do you inject dynamic content into your web page? Following is a list of the most common methods I find when doing quality and code reviews with some comments and dangerous pitfalls.

#1: Inline Expressions with Code Render Blocks

Using inline expressions is a shortcut for calling the Write method.

Example – DONT:

<h2><%= CurrentPage.PageName %></h2>
<img src="<%= CurrentPage["ImageUrl"] %>" alt="<%= CurrentPage["MainIntro"] %>" />
<div class="mainarea">

     <%= CurrentPage["MainBody"] %>
</div>

Since xhtml is just text, writing some more in-between existing static blocks is fast and simple. Probably the easiest way to inject dynamic content but it is also dangerous!

Example – DO always use HtmlEncode:

<h2><%= HttpUtility.HtmlEncode(CurrentPage.PageName) %></h2>

What happens if our PageName property contains a “<” or “&” character in the example above? Your page will not validate and you risk that it breaks down. It can also be exposed to script injection if the content is user generated.

To be on the safe side you should always call HttpUtility.HtmlEncode on all strings that you inject with inline expressions.

Example – DO always use a fallback for src-attributes

<img src="<%= CurrentPage["ImageUrl"] ?? "/Missing.png" %>" />

If your ImageUrl property is empty you would get a img-tag with an empty src-attribute. This can lead to the page being rendered twice. FireFox interpret a null src-attribute a relative url and evaluate it using the page url as base returning the same url.

#2: With EPiServer:Property web control

Using the EPiServer Property Web Controls instead of inline expressions has several benefits. It could be used for rendering the PageName and MainBody in the example above.

Example – DO use EPiServer:Property web control

<h2><EPiServer:Property PropertyName="PageName" runat="server" /></h2>
<EPiServer:Property CssClass="mainarea" PropertyName="MainBody" runat="server" />

1) When rendering EPiServer’s ToWebString() is used. This does almost the same job as always calling HtmlEncode yourself.

public virtual void CreateDefaultControls()
{
    Label target = new Label();
    target.Text = PropertyData.ToWebString();
    CopyWebAttributes(target);
    Controls.Add(target);
}

2) It enables the Simple Edit feature for the editors without any extra work. (If you do not know what “Simple Edit” is, you should read the Editors Manual for EPiServer before doing any more development.)

3) Different types have get different rendering automatically. Commonly used for PageReferences and Url’s that are rendered as a Hyperlink.

Example – DO use EPiServer:Property for rendering links if possible

<EPiServer:PageList PageLinkProperty="NewsArchivePage" MaxCount="5" runat="server" >
  <HeaderTemplate>
    <h3><EPiServer:Property PropertyName="PageLink" runat="server" /></h3>
    <ul>
  </HeaderTemplate>
  <ItemTemplate>
    <li><EPiServer:Property PropertyName="PageLink" runat="server" /></li>
  </ItemTemplate>
  <FooterTemplate>
    </ul>
  </FooterTemplate>
</EPiServer:PageList>

4) Use PageLinkProperty to follow a Page-property to another page and render a value. Takes care of all hassle and calls GetPage() and check for nulls for you.

Example – DO use EPiServer:Property to render values from another page

<h3><EPiServer:Property PageLinkProperty="FeatureArticlePage" PropertyName="PageLink" runat="server" /></h3>
<div><EPiServer:Property PageLinkProperty="FeatureArticlePage" PropertyName="MainIntro" runat="server" /></div>