Xsl transformations in templates for umbraco v4

10. marts 2009 by Kasper B

This weekend I finally got around to play with umbraco v4, and its a joy!

I really like the new .net masterpage templates, and will try to share how I experienced some of the nice new features that they provide.

First of, its now possible to use .net code in the templates, which certainly will raise the numbers of wtf's per minute - a quick example:

You can now use something like this directly in your template

 <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<% if (Request.QueryString["test"] != null) { %>
Now theres a test in the querystring
<% } else { %>
Add a <a href="?test=haha">test in the querystring</a>
<% }%>
</asp:Content>


Aswell as inserting standard .net controls and binding them to datasources

<script language="c#" runat="server">
protected void Page_Load() {
System.Collections.Generic.List<string> list = new System.Collections.Generic.List<string>();
list.Add("Boom");
rpt.DataSource = list;
rpt.DataBind();
}
</script>

<asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<asp:Repeater id="rpt" runat="server">
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:repeater>
</asp:Content>

Now that this is a fact, why not try to do something useful

How to use inline xsl in umbraco templates:

1: Create a custom control that takes the literal contents (which is the text/code in between the start and end element of the custom control) assumes that its xsl and then perform the transformation in the overridden render method.

2: In order to make it work as the xsl based macros - add in the umbraco xml data, the currentPage param and the xsl extension objects.

I have done so and the result is baffling - it works!

 Its now possible to do something like:

<%@ Master Language="C#" MasterPageFile="/umbraco/masterpages/default.master" AutoEventWireup="true" %>
<%@ Register assembly="InlineXsl" namespace="InlineXsl" tagprefix="Inline" %> <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<Inline:XslTransformer ID="mytransform" runat="server">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxml umbraco.library">
<xsl:output method="html" omit-xml-declaration="yes"/> <xsl:param name="currentPage"/>
<xsl:template match="/">
You are on the page <xsl:value-of select="$currentPage/@nodeName" />
</xsl:template>
</xsl:stylesheet> </Inline:XslTransformer>
</asp:Content>

Which is pure inline xsl in your templates :)

To make it a bit easier to start up - I added an option to omit the doctype and stylesheet declarations - which makes it alot shorter and readable - you just need to add the following attribute to the custom control:  OmitStyleSheetAndDoctypeDeclaration="True"

Same example:

<%@ Master Language="C#" MasterPageFile="/umbraco/masterpages/default.master" AutoEventWireup="true" %>
<%@ Register assembly="InlineXsl" namespace="InlineXsl" tagprefix="Inline" %> <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
<Inline:XslTransformer ID="mytransform" runat="server" OmitStyleSheetAndDoctypeDeclaration="True">
<xsl:param name="currentPage"/>
<xsl:template match="/">
You are on the page <xsl:value-of select="$currentPage/@nodeName" />
</xsl:template>
</Inline:XslTransformer>
</asp:Content>

 

It really is that easy - try it out for yourself: download a .zip file with the assembly containing the custom control, extract - drop it in your umbraco v4 installations bin folder and copy paste the code from this page into a master template :)

If it fails you can add the attribute DebugMode="True" aswell - it will output a nice error message, if you dont - its in the trace.