Search

Hi Guys, I'm quite new to XSLT but I was wondering about emulating some Wordpress shorttag functionality.

Given a Page-Content Section with a body (textfield, formatted) would it be possible to pick up e.g. <h2>[video]</h2> and replace that with e.g. a YouTube embedding code?

(I'm not interested in the video embedding, simply the shorttag XSLR functionality :) )

In my mind this should be fairly easy but I have not yet succeeded…

I can match the node like this:

<xsl:apply-templates select="/data/page-content/entry[1]/body/h2[.= '[video]']"/>

In combination with:

<xsl:template match="/data/page-content/entry[1]/body/h2[.= '[video]']"> <div style="border: 2px solid red"><xsl:text>VIDEO STUFFZ!</xsl:text></div></xsl:template>

BUT (obviously) the markup is generated at the location of my apply-templates element. I would like to replace my <h2>[video]</h2> with my new content.

I am thinking Ninja-Technique but I can't quite figure this out. How do I replace my <h2>[video]</h2> content with something else?

Start by using the ninja technique. Add a template match to find the element you want to replace, like the Image Formatter utility. Perhaps you want something like:

<xsl:template match="h2[text()='[video]']" mode="html" priority="1">
    <!-- embed video here rather than building an <h2> element -->
</xsl:template>

I'm not sure i understood correctly, but doesn't your template already replace content as you wanted?

You can make it a bit more generic, like this:

<xsl:template match="h2[.='[video]'">
   <div style="border: 2px solid red"><xsl:text>VIDEO STUFFZ!</xsl:text></div>
</xsl:template>

Then just call:

<xsl:apply-templates select="/data/page-content/entry[1]/body/*"/>

We're doing something similar in project i'm working on right now. But we're using Templated Text Formatters to make formatted content include some special tags/classes/URIs, and then render them however we want in XSLT :).

nickdunn was quicker :).

David: The missing piece to your puzzle may be the understanding what the Ninja technique does.

Granted, their selectors may be a bit cryptic but the templates essentially do one single thing: they process your markup recursively and create a copy of it. Exactly the same as copy-of does.

The main difference to copy-of is that you can overload and change every single step in the process by creating a template of higher priority. Instead of picking the default template (wich in your case creates an element named h2 before descending deeper into the tree) it will then use your custom markup and do whatever you like.

@nickdunn see I was on the right track ;)

Still, I added the Ninja Utility and added your match template but the original H2 is still there. It does not seem to work.

The matching works (checked with ?debug).

My H2 is part of a body textfield that is targetted before with a apply-templates and later <xsl:copy-of select="body/*" />

@phoque Thx. Yes, I think I understand (it recursively loops through elements and attributes, while allowing overriding at each) but somehow I must be missing something here (I've linked to my templates)

@ahwayakchih no, the H2 is not replaced. I can add/use/copy this content somewhere else though a apply-templates but I want to replace my original H2 (in the body HTML) with new content.

Here are the two relevant templates: http://pastebin.com/SKKdwgRX

You have to replace

<xsl:copy-of select="body/*" />

with

<xsl:apply-templates select="body/*" mode="html" />

to actually start the Ninja technique templates instead of a plain copy-of.

davidhund, what phoque wrote. Also check if mode values are the same. When you use:

<xsl:apply-templates select="page-content/entry" mode="main-col"/>

mode is main-col. That means that only templates with the same mode value will be applied.

@phoque thanks! That was it…

I only included the Ninja Technique for this particular problem, so I forgot to add them in my inc-page-content.xsl template.

@ahwayakchih yeah it worked with the mode="html" while the 'outer' template was still using the mode="main-col". So I only had to replace the body/* thing (as Phoque pointed out).

To conclude: The Ninja Technique makes it quite easy to add shorttag-like functionality.

My only question, now, is: is there any reason not to always use the Ninja Technique? In my case I only needed it because I wanted to replace one element with something else. Is there a performance overhead or any other reason not to always approach this CMS-generated content 'The Ninja Way'?

PS: Thanks guys for the quick response!

I could see two reasons: Performance and readability.

Lots of recursions are slow. Really really slow. And (at least to beginners) a simple copy-of is a lot more verbose than apply-templates mode="html".

@phoque thanks. I suspected that much recursion would have a significant performance drawback. I think there's nothing I can do about this besides keeping an eye on the performance and (maybe) conditionally using the Ninja Technique.

As for verbosity: the Ninja Technique is a little more verbose, but that would hardly be a problem, when the concept is clear.

Thanks again: I'll keep performance in mind but, for now, this works just fine.

Oh don't worry. Nobody will read an article that's too long for XSLT to handle anyways. ;-)

;-)

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details