Wednesday, April 22, 2009

Coldfusion writing simple xslt

I think it would be kinda cool to not have to write xslt as much any more, so a coworker and I created some helper functions to handle tables for us. So instead of writing xslt to create a table tag where we can pump xml into we created coldfusion functions with which can shoot args and write the xslt for us.

Here we call a beginTable() with which we can give it attributes.

<cffunction name="beginTable" access="public" returntype="string" output="false" >

<cfset var local = {} />

<cfset arguments = getArguments(arguments) />

<cfsavecontent variable="local.string">
<cfoutput>
<xsl:call-template name="beginTable">

#renderXSLTParams(argumentCollection=arguments)#

</xsl:call-template>
</cfoutput>
</cfsavecontent>

<cfreturn local.string>

</cffunction>

First we can getArguments which handles our common attributes of the tag we are trying to create. getArguments() can be used to set out defaults but of simplicity we just loop a list of common attributes.

<cffunction name="getArguments" access="public" output="false" returntype="struct">
<cfargument name="args" required="true" />

<cfset var local = {} />

<cfset local.args = arguments.args />

<cfloop list="class,style,title,alt,id,height,width,colspan,cellspacing,cellpadding,align,border,src,value" index="local.i">
<cfset local.args[lcase(local.i)] = getKey(lcase(local.i),local.args,"#local.i#") />
</cfloop>

<cfreturn local.args />

</cffunction>

Second, we write the xlst beginTable template and create the xslt params using renderXSLTParams.

<cffunction name="renderXSLTParams" access="public" returntype="string" output="false" >

<cfset var local = {} />
<cfset var i = "" />

<cfsavecontent variable="local.string">
<cfoutput>
<cfloop collection="#arguments#" item="i">
<xsl:with-param name="#lcase(i)#">
<cfif (FindNoCase('%',arguments[i],1) or FindNoCase('px',arguments[i],1) )>
<xsl:text>#arguments[i]#
<cfelse>
<xsl:value-of select="#lcase(arguments[i])#"/>
</cfif>
</xsl:with-param>
</cfloop>
</cfoutput>
</cfsavecontent>

<cfreturn local.string/>

</cffunction>

That takes care of creating the xslt snippet for the begin table tag, now we have to load the tag at the bottom of the xslt so we can call the template and invoke the params. To do this we output the load function which contains all our template snippets.

<cffunction name="load" access="public" output="false" returntype="string" >

<cfset var local = {}/>

<cfsavecontent variable="local.string">
<cfoutput>
<xsl:template name="beginTable">
#getTemplateParams()#
<xsl:text disable-output-escaping="yes"><</xsl:text>table
#getXSLTParams()#
<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:template>

<xsl:template name="endTable">
<xsl:text disable-output-escaping="yes"><</xsl:text>/table
</xsl:template>

</cfoutput>
</cfsavecontent>

<cfreturn local.string/>

</cffunction>

In the load function we call getTemplateParams() to create our template params.


<cffunction name="getTemplateParams" access="public" returntype="string" output="false" >

<cfset var local = {}/>
<cfset var i = ""/>

<cfset arguments = getArguments(arguments)/>

<cfsavecontent variable="local.string">
<cfoutput>

<cfloop collection="#arguments#" item="i">

<xsl:param name="#lcase(i)#"/>

</cfloop>

</cfoutput>

</cfsavecontent>

<cfreturn local.string/>

</cffunction>

Next we call getXSLTParams(). to actually invoke the xslt params

<cffunction name="getXSLTParams" access="public" returntype="string" output="false" >

<cfset var local = {}/>
<cfset var i = ""/>

<cfset arguments = getArguments(arguments)/>

<cfsavecontent variable="local.string">
<cfoutput>

<cfloop collection="#arguments#" item="i">
<xsl:if test="$#lcase(i)# != '' ">
#lcase(i)# ='
</xsl:if>
</cfloop>

</cfoutput>
</cfsavecontent>

<cfreturn local.string/>

</cffunction>

And that should do it.

No comments:

Post a Comment