One of the features of Sitecore which challenges correct development practise is XslExtensions (or XslHelpers as we call them). Good examples of XslExtensions are the Sitecore.Xml.Xsl.XslHelper and Sitecore.Xml.Xsl.SqlHelper classes (read more here).
The possibility of hooking in your own .NET functions into your XSLT code is a vital part of Sitecore, but the concept of XslExtensions brings a few problems to the party:
- XslExtensions are actually a return to the world of functional programming and removes the concept of which context your code is running.
- XslExtensions are loosly bound to where it is used. In practise it is difficult to know from where your code is being called – if it is called at all.
- Hooking in XslExtensions requires changes to your web.config file. This is actually not a big problem, but it would be nice to be without.
- XslExtension methods require specific types as input and output. Therefore if you introduce nice functionality in a XslExtension method, it is bound to the XSLT compliant types.
- XslExtensions lies on the border between the UI and the business logic tier of your application. Therefore XslExtensions can often be cluttered with methods which replicate and port functionality in your business logic to XSLT compliancy, or actually introduces new business logic functionality.
A good example of this last two points are Sitecore.Xml.Xsl.XslHelper.HasBaseTemplate() method, which is actually the only place in the Sitecore API where you can query whether an Item derives from a given template. This means that if you need this code in ASP.NET, you need to replicate the functionality in your own classes or – even worse – call Sitecore.Xml.Xsl.XslHelper.HasBaseTemplate() from your ASP.NET codebehind.
So, what can we do to try to enforce good development practise while still maintaining the essential functionality of exposing .NET methods to XSLT’s? I’ll get back to that in part two of my post.