It pays to use a separate web form for each web content type.

My client uses web forms in Alfresco 3.0E to create web content. This means that when users want to create HTML (web content), they open an "authoring" form (defined ahead of time using XSD), populate its fields with the desired content, and save it. On save, Alfresco does two things:

  • saves the content item as an XML file;
  • transforms the XML to HTML using an XSL rendering template (also written beforehand).

The client publishes company policies as web content on its intranet portal. Recently I was tasked with changing the styles of the client's policies. The policies would now be styled differently from other web content on the same portal. For example, headers would be teal instead of green. Additionally, any section header with a value of "Policy" appearing within the body of a policy would have an underline extending the width of the portlet window. Other section headers would not have these underlines, although they would otherwise be styled identically.

Fortunately we had rendered all of the policies using a custom web form called "Policy." This meant that all I would have to do is make some changes to the XSL rendering template associated with the Policy web form, then force a re-rendering of all content created using that form.

Here were my steps:

  1. Define policy-specific styles (including the underlining style) and save them in the portal CSS file with a class name like
    ".content-policy";
  2. In the Policy.xsl file, surround the all of the lines that render content with enclosing

    tags using the same class name (e.g.,

    );
  3. Insert tags into the XSL to dynamically identify "Policy" section headers, and style them accordingly;
Force re-rendering of all content created using the Policy web form.

Here is the XSL markup:

xsl:preserve-space elements="*"/>
 
xsl:template match="/">
 xsl:apply-templates/>
xsl:template>
 
xsl:template match="ns:content">

Here is the opening

tag to ensure policy styles are applied to content rendered by this template:
 div class="content-policy">
 h1>xsl:value-of select="ns:title"/>h1>
 
 
 xsl:for-each select="ns:section">
 div class="no-float">
 
 
 xsl:choose>
 xsl:when test="ns:section_header=''">xsl:when>
 xsl:otherwise>

Section headings are defined as separate fields in the web form, and are typically rendered with

tags. Here is the code for dynamically rendering section headers based on whether the value is "Policy" (I used a specially styled

class if it is a "Policy" section header ):
 xsl:choose>
 xsl:when test="ns:section_header='Policy'">
 p class="policy-header">xsl:value-of select="ns:section_header"/>p>
 xsl:when>
 xsl:otherwise>
 h2>xsl:value-of select="ns:section_header"/>h2>
 xsl:otherwise>
 xsl:choose>
 xsl:otherwise>
 xsl:choose>

The "body" element is created in the web form using a TinyMCE control. TinyMCE is a WYSIWYG editor that generates HTML. The HTML it generates, rendered here, is still subject to the styles defined with the "content-policy" class.

 
 xsl:value-of select="ns:body" disable-output-escaping="yes"/>
 div>
 xsl:for-each>
 div>
 
xsl:template>

The big lesson here is that it paid to have a separate web form for the policy content type. The policy web form is not much different than other web forms we use, including a catch-all form we call "Generic". We could have used Generic to render policies, but then we would have been forced to make time-consuming manual edits to them when the requirements for policy styles changed. This is why it is so critical to create a separate web form for each content type you discover over the lifetime of the content management system.

A word of caution: there is danger in granting too many people the power to decide what warrants a new content type and allowing them to create their own web forms, without sufficient oversight, resulting in a chaotic situation. A solid content management governance model featuring centralized oversight prevents this problem.