Hi, I hope this hasn't been covered loads of times but I did do a search and couldn't find anything. I have an Umbraco V4 website and I want to know if I can call an XSLT file from within an XSLT and if so how. I have some XSLT code that I don't want to have to repeat in a number of XSLT files because it is going to be a pain if I have to make a change to a bit of it (I will then have to make the change to all other XSLT files). Therefore is it possible to have this code in an XSLT file then call that XSLT within other XSLT files?
Yes, you can use the <xsl:include> tag to pull in a different XSLT:
<xsl:include href="OtherTemplate.xslt" />
There are a few gotchas! So be careful!
The "parent" XSLT will cache the included XSLT. So if you make a change to the nested/included XSLT - it wont show up straight away in the parent XSLT transformation. I "think" this might be to do with using XslCompiledTransform - but not 100% on that. Anyway, if you modify the parent XSLT, it will refresh the cache. (This has been a very annoying issue on some projects)
Secondly, you'll probably encounter issues with the $currentPage param. It can only be declared once in the entire XSLT stylesheet - that includes any "includes"!!! So just be careful where you reference the <xsl:param name="currentPage" /> element!
Thanks for this, that is exactly what I wanted although the caching issue is a bit annoying because it does mean that I have to open each XSLT that references it everytime I make a change. I suppose it is better than having to make the change in each XSLT like I would have to without doing this. Is there no other way around it to make it refresh the cache? What about touching the webconfig?
As far as I'm aware, no, there isn't a way to invalidate the cache if the nested/included XSLT is modified. If anyone knows of a way, I'd love to know!
I've taken a look through the Umbraco core (via Reflector again) to understand how the caching is happening. As far as I can tell it's not the XslCompiledTransform doing the nested/include caching, but Umbraco itself.
If you go to the Cache Browser in the developer section (back-office admin) you'll see a bunch of entries for "System.Xml.Xsl.XslCompiledTransform" - all prefixed with "macroXslt_" (followed by the XSLT filename). All the caching happens in "umbraco.macro.getXslt()" call - which is has a dependency set on the filesystem ... so if an XSLT file is modified - it expires the cache.
Well, I hear you say this is all very interesting and technical ... so what can we do?
Well not much to be honest. There are no "hookable" events in the SaveXslt method - at least I can't find any. So we have way of knowing when an XSLT is modified (via Umbraco). Peter's way (from the other thread) using a FileSystemWatcher will work well, but it's only suitable for dedicated servers.
Is it possible to call another XSLT from an XSLT
Hi, I hope this hasn't been covered loads of times but I did do a search and couldn't find anything. I have an Umbraco V4 website and I want to know if I can call an XSLT file from within an XSLT and if so how. I have some XSLT code that I don't want to have to repeat in a number of XSLT files because it is going to be a pain if I have to make a change to a bit of it (I will then have to make the change to all other XSLT files). Therefore is it possible to have this code in an XSLT file then call that XSLT within other XSLT files?
Yes, you can use the <xsl:include> tag to pull in a different XSLT:
There are a few gotchas! So be careful!
The "parent" XSLT will cache the included XSLT. So if you make a change to the nested/included XSLT - it wont show up straight away in the parent XSLT transformation. I "think" this might be to do with using XslCompiledTransform - but not 100% on that. Anyway, if you modify the parent XSLT, it will refresh the cache. (This has been a very annoying issue on some projects)
Secondly, you'll probably encounter issues with the $currentPage param. It can only be declared once in the entire XSLT stylesheet - that includes any "includes"!!! So just be careful where you reference the <xsl:param name="currentPage" /> element!
Apart from that, good luck!
Cheers, Lee.
Hi Lee,
Thanks for this, that is exactly what I wanted although the caching issue is a bit annoying because it does mean that I have to open each XSLT that references it everytime I make a change. I suppose it is better than having to make the change in each XSLT like I would have to without doing this. Is there no other way around it to make it refresh the cache? What about touching the webconfig?
As far as I'm aware, no, there isn't a way to invalidate the cache if the nested/included XSLT is modified. If anyone knows of a way, I'd love to know!
This (I think) is the solution we're all waiting for to this problem... but Peter hasn't released the project as far as I know. http://our.umbraco.org/forum/templating/templates-and-document-types/5599-Including-XSL-file-changes-not-picked-up,-needs-parent-file-tickled-to-update
Seems like an ideal little package for someone to make (*cough* Lee *cough*)
cheers,
doug.
Thanks for the hint Doug! ;-) haha
I've taken a look through the Umbraco core (via Reflector again) to understand how the caching is happening. As far as I can tell it's not the XslCompiledTransform doing the nested/include caching, but Umbraco itself.
If you go to the Cache Browser in the developer section (back-office admin) you'll see a bunch of entries for "System.Xml.Xsl.XslCompiledTransform" - all prefixed with "macroXslt_" (followed by the XSLT filename). All the caching happens in "umbraco.macro.getXslt()" call - which is has a dependency set on the filesystem ... so if an XSLT file is modified - it expires the cache.
Well, I hear you say this is all very interesting and technical ... so what can we do?
Well not much to be honest. There are no "hookable" events in the SaveXslt method - at least I can't find any. So we have way of knowing when an XSLT is modified (via Umbraco). Peter's way (from the other thread) using a FileSystemWatcher will work well, but it's only suitable for dedicated servers.
Cheers, Lee.
is working on a reply...