XSLT FAQ

How can I modify the HTML from the Visual Content editor?

I have a situation where I would like to modify the HTML that is created when users are editing page content – I have a ‘right column’ placeholder, where I would like to replace h1 etc. elements with div elements having custom class names. How can I do this in C1?

Answer:

If you have a right column placeholder in your website template, you have an element in the template markup like this:

<rendering:placeholder id="infocolumn" title="Right content" />

This is actually representing an XHTML element and you can pass this object to a C1 Function as a parameter.

Image for a moment that we go create an XSLT Function named "Content.Transformations.InfoColumnTransform" and give it a parameter named "Content" - this will then allow us to wrap the <rendering:placeholder /> tag shown above like this:

<f:function name="Content.Transformations.InfoColumnTransform" xmlns:f="http://www.composite.net/ns/function/1.0">
  <f:param name="Content">
    <placeholder id="infocolumn" title="Right content" xmlns="http://www.composite.net/ns/rendering/1.0" />
  </f:param>
</f:function>

When C1 is rendering this, it will grab the XHTML from the placeholder, pass it to your XSLT Function and the output the result of the function call.

Then all there is left is to write the XSLT you need to do your transformations.

To create the XSLT described above, do the following:

  1. Open the Function perspective
  2. Create a new XSLT function named "InfoColumnTransform" in the namespace "Content.Transformations"
  3. On the ‘Input Parameters’ tab, add a new parameter named "Content"
  4. Set the parameter type to "Object"
  5. Click ‘Specify a test value’ and select Composite.Constant.XhtmlDocument.
  6. Edit the HTML and write some test data.
  7. Click OK twice.
  8. Preview.

You will see the test XhtmlDocument in your XSLT preview input. Now all you need is to create the XSLT. Below is a sample which will replace <h1 /> elements with <div class="myheading" /> elements.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xsl in">
  <xsl:template match="/">
    <!-- grab the html document root from the unput parameter -->
    <xsl:apply-templates select="(/in:inputs/in:param[@name='Content']//xhtml:html)[1]" />
  </xsl:template>
  <!-- general copy of elements -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <!-- specific rule that transform <h1 /> elements to <div class="myclass" /> elements -->
  <xsl:template match="xhtml:h1">
    <xhtml:div class="myclass">
      <xsl:apply-templates select="@*|node()" />
    </xhtml:div>
  </xsl:template>
</xsl:stylesheet>

This sample will work with Composite C1 1.2 SP2 and newer.