sindri.info

Using Gravatars in Unify

Republished because of my weird fixation on everything having to last forever

Dealing with complex data types in XSL

My motivation for creating this article comes from wanting to implement Gravatars on a blog/comment feature on a Unify site. To create a link to a Gravatar you need to generate a URL that contains an MD5 hash of an email adress in HEX formatting and XSL simply doesn't help much with that sort of thing. In Java code however generating an MD5 hash from an email address is a trivial task.

VYRE Unify uses XSL a lot to generate HTML from the XML data stored in it's content repository. This can often lead to issues for users trying to produce output with anything more complicated than plain text with simple HTML tags and URLs. For example reformating dates is a nightmare to do with just plain XSL and XPath.

This is where XSL Java extensions come in to save the day. Using XSL Java extensions you can effectively call any Java method available from an XSL script. VYRE Unify fully supports XSL Java extensions.

To explain what XSL Java extensions are, here is a simple example that prints the cosinus of a number in the XML source.

To explain what's going on here, I have defined a new namespace “math” to be a Java class format namespace. I can then call static methods on that class in XPath by using the namespace. Note the parameter is a XPath that resolves to a tag containing a number and is automatically cast to a javatype double.

A slightly more complicated example would be printing the current date:

<xsl:template name="currentDate" xmlns:date="xalan://java.util.Date"> <xsl:variable name="current-date" select="date:new()" /> <xsl:value-of select="date:toString( $current-date )" /> </xsl:template>

This is the equivalent of the Java code:

public String getCurrentDate() { java.util.Date currentDate = new java.util.Date(); return currentDate.toString(); }

You might notice that the method calls in the XPath look a bit backward compared to the Java syntax. The rule is a methods declaring class is the first parameter of the method and the following parameters are the Java methods parameters. Calling constructors is the same syntax as calling a static method with the name "new".

Both the examples above use so called Class format namespace, there is also package format namespace and Java format namespace that you can read about in the Xalan documentation.

Using gravatars

Now finally I'll show how I managed to create gravatar links in an item list XSL in Unify. The first place to look was the Gravatar implementor's guide Java section. Where they show a class that can generate the MD5 hash with a simple static method call. What I actually did was cheat, because I knew there was a class in Unify that does exactly the same thing, so I did:

<div xmlns:hasher="xalan://vyre.realms.PasswordService"> <xsl:variable name="hasher" select="hasher:getInstance('MD5', 'hex')"/> <img> <br /> <xsl:attribute name="src"><br /> http://www.gravatar.com/avatar/<xsl:value-of select="hasher:encrypt($hasher, ./creator/email)"/>.jpg </xsl:attribute> </img> </div>

But for non Unify developers it is trivial to compile the class given on the Gravatar site, put it on your Unify servers classpath and calling it like so:

<div xmlns:md5="xalan://MD5Util"> <img> <xsl:attribute name="src"> http://www.gravatar.com/avatar/<xsl:value-of select="md5:md5Hex( ./creator/email )"/>.jpg </xsl:attribute> </img> </div>

Better practices

In the examples above I define the xml namespaces in the outermost tag of the example, this has an annoying side effect of making the xmlns attribute appear in the html output. This can be avoided by defining the namespace in the xsl:stylesheet tag and adding the namespace to xclude-result-prefixes to the xsl:stylesheet tag.

In general you would also usually want to keep this sort of complicated XSL code in separate includable XSL scripts in callable named templates supported in Unify 4.4+.

Published by Sindri Traustason on . Comment?
Bookmark and Share