Search

I’m playing around with Allen’s HTML Ninja Technique to replace headers—which works great except it’s pulling in the section node as well.

Here’s my XML:

<?xml version="1.0" encoding="utf-8" ?>
<data>
    <events />
    <html-ninja-technique>
        <section id="16" handle="html-ninja-technique">HTML Ninja Technique</section>
        <entry id="24">
            [...trimmed for sanity...]
        </entry>
    </html-ninja-technique>
</data>

My XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/master.xsl"/>

<xsl:template match="data/html-ninja-technique/entry/text//*">
    <xsl:element name="{name()}">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="data/html-ninja-technique/entry/text//@*">
    <xsl:attribute name="{name(.)}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="h2" priority="1">
    <xsl:element name="h3">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="h1" priority="2">
    <xsl:element name="h2">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

And the resulting HTML:

<body>
    <div id="content">


        HTML Ninja Technique

            <h2>Lorem ipsum
            [...trimmed: it continues as normal from here...]
</body>

Basically, it’s adding the text from the section node even though it shouldn’t as far as I can tell.

Can we see master.xsl?

The rest is the default Symphony install so the master is the same as the Symphony 2.07RC1 master.

This would happen if you just apply-templates to the /data element without any further select. This is due to XSLT’s default templates. Have a gander…

But why would that be the case when I’m actually being very specific of which node is being applied? This is what confuses me. I don’t know what part of my XSLT is wrong.

As far as I can tell I’m only specifying what’s in the data/html-ninja-technique/entry/text node. The section node is back next to entry so I should be bypassing it completely.

What confuses me is if I use the copy-of command with the exact same path everything works fine. However, that wouldn’t allow me to turn H3’s into H4’s and so forth.

I guess you’re doing <xsl:apply-templates select="/data/html-ninja-technique/" /> and not <xsl:apply-templates select="/data/html-ninja-technique/entry/" />.

Can we see the whole XSLT (the apply-templates that calls your ninjas to work), the XML and the whole output in case I’m wrong?

Full XSLT Template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/master.xsl"/>

<!--
<xsl:template match="data">
    <xsl:copy-of select="html-ninja-technique/entry/text"/>
</xsl:template>
-->

<xsl:template match="/data/html-ninja-technique/entry/text//*">
    <xsl:element name="{name()}">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="/data/html-ninja-technique/entry/text//@*">
    <xsl:attribute name="{name(.)}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="h2" priority="1">
    <xsl:element name="h3">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="h1" priority="2">
    <xsl:element name="h2">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Full Master:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/page-title.xsl"/>
<xsl:import href="../utilities/navigation.xsl"/>
<xsl:import href="../utilities/date-time.xsl"/>

<xsl:output method="xml"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
    omit-xml-declaration="yes"
    encoding="UTF-8"
    indent="yes" />

<xsl:variable name="is-logged-in" select="/data/events/login-info/@logged-in"/>

<xsl:template match="/">

<html>
    <head>
        <title>
            <xsl:call-template name="page-title"/>
        </title>
        <link rel="icon" type="images/png" href="{$workspace}/images/icons/bookmark.png" />
        <link rel="alternate" type="application/rss+xml" href="/rss/" />
    </head>
    <body>
        <div id="masthead">
            <h1>
                <a href="{$root}"><xsl:value-of select="$website-name"/></a>
            </h1>
            <xsl:apply-templates select="data/navigation"/>
        </div>
        <div id="package">
            <p class="date">
                <xsl:call-template name="format-date">
                    <xsl:with-param name="date" select="$today"/>
                    <xsl:with-param name="format" select="'d'"/>
                </xsl:call-template>
                <span>
                    <xsl:call-template name="format-date">
                        <xsl:with-param name="date" select="$today"/>
                        <xsl:with-param name="format" select="'m'"/>
                    </xsl:call-template>
                </span>
            </p>
            <div id="content">
                <xsl:apply-templates/>
            </div>
        </div>
        <ul id="footer">
            <li>Orchestrated by <a class="symphony" href="http://getsymphony.com/">Symphony</a></li>
            <li>Broadcasted via <a class="rss" href="{$root}/rss/">XML Feed</a></li>
        </ul>
    </body>
</html>

</xsl:template>

</xsl:stylesheet>

Full XML:

<?xml version="1.0" encoding="utf-8" ?>
<data>
    <events />
    <html-ninja-technique>
        <section id="16" handle="html-ninja-technique">HTML Ninja Technique</section>
        <entry id="24">
            <text mode="formatted"><h1>Lorem ipsum dolor sit amet</h1>
<p>Ipsum non erat, in nunc. Ac dolor ut mollis urna, luctus interdum, eu magna vitae, penatibus suspendisse wisi amet id, morbi sodales cras integer. Justo adipiscing urna quia sit, vel nisl integer amet porta praesent hendrerit, diam suscipit. Et nec aptent interdum nulla ut molestie.</p>
<ul>
<li>Ornare felis at vel posuere vestibulum elementum</li>
<li>Tempus ac lacus curabitur sed ornare</li>
<li>Vitae ornare sollicitudin vitae vitae nulla</li>
<li>Convallis mi amet ante nulla ut a</li>
<li>Magna vestibulum quisque quis</li>
</ul>
<p>Purus habitasse egestas, nam magna ut donec scelerisque convallis, per ornare ac orci, arcu a arcu sed. Dapibus viverra ipsum neque, praesent duis risus donec sit, vivamus sed varius vestibulum justo, leo et turpis sed vitae erat. Dolor lacinia ut id, vel platea fusce neque ac massa per, libero nam venenatis eu faucibus, rhoncus mi felis in in, netus in maecenas dignissim. Occaecati non nunc.</p>
<h2>Mauris arcu condimentum</h2>
<p>Justo velit erat, ac erat turpis ornare vitae eget justo, lacus purus, in semper urna eu nam irure pellentesque. Fusce id, eleifend odio ut. Lorem ornare lobortis. Sem ac justo, etiam nibh quam feugiat velit, ornare sit a. Est nec ut at leo eget. Sapien vel et amet dolor, vitae arcu, auctor vivamus nulla dolor molestie, laoreet varius sit.</p>
<blockquote>
  <p>Aliquam vitae mi parturient orci ultricies, hendrerit accumsan, leo lobortis pulvinar incidunt nibh, sit orci morbi habitasse suscipit ac. Proin dignissim feugiat veniam tristique diam, sit urna velit sed, vulputate nulla, arcu laoreet.</p>
</blockquote>
<p>At orci nunc venenatis quis proin, lorem vel aliquet augue felis bibendum, iaculis phasellus arcu convallis consectetuer non, rhoncus nunc nec accumsan ante purus, est dignissim rerum amet lectus dapibus. Montes mollis, et molestie tempus donec, tempor vestibulum nibh a, auctor viverra sed laoreet integer ex, at erat nunc justo non tincidunt.</p></text>
        </entry>
    </html-ninja-technique>
</data>

I played around with a bit and I’m guessing it has something to do with the apply-templates command on the master.xsl. The problem is it can’t be removed and I’m not sure how it can be made specific and still expected to work with multiple templates.

The only option I can think of would be to not really have a master at all.

I should note that the reason I’m playing with this is I’m looking for a simple way that would allow me to make H1’s into H2’s and so on. However, as far as I can tell, using this technique would require a complete reworking of how I usually build Symphony sites.

Is there some other option sans this one?

And I’m an idiot. I knew it was something simple.

New XSLT Template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="../utilities/master.xsl"/>

<xsl:template match="data">
    <xsl:apply-templates select="html-ninja-technique/entry/text"/>
</xsl:template>

<xsl:template match="html-ninja-technique/entry/text//*">
    <xsl:element name="{name()}">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="html-ninja-technique/entry/text//@*">
    <xsl:attribute name="{name(.)}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="h2" priority="1">
    <xsl:element name="h3">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="h1" priority="2">
    <xsl:element name="h2">
        <xsl:apply-templates select="* | @* | text()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Once I realized the apply-templates was the issue it was all downhill from there. For some reason it failed to register that I would need an apply-templates command in main data template as well. D’uh.

OK. I feel stupid. At least I’ve figured it out. Thanks everyone for the help!

Glad you figured it out.

I must say I was a bit confused of your resulting HTML

<body>
    <div id="content">


        HTML Ninja Technique

            <h2>Lorem ipsum
            [...trimmed: it continues as normal from here...]
</body>

At first it looked like your templates were wrapping everything in the <h2> tag. How could you post invalid XML on the forum? ;-)

Yeah, had I just posted all the XML and XSLT in the first place this could probably have all been solved much sooner.

Oh well. Next time I have a problem…

I often use this template to bulk change headlines (in this case h1 > h3):

<xsl:template match="h1 | h2 | h3 | h4" priority="1">
    <xsl:element name="h{substring-after(name(), 'h') + 2}">
        <xsl:apply-templates select="* | @* | text()" />
    </xsl:element>
</xsl:template>

Now that’s handy! Thanks Nils!

Just to make sure I understand your XSLT correctly, that would turn an h1 into an h3, h2 into h4, h3 into h5, correct?

Hard to believe he’s actually an art historian…

:-)

Just to make sure I understand your XSLT correctly, that would turn an h1 into an h3, h2 into h4, h3 into h5, correct?

That’s correct! I use this template in connection with textareas that are Markdown formatted - this way the user can always start with the first headline and I can adjust the hierarchy of all headlines based on the context.

Edit: I posted this as XSLT utility.

Hard to believe he’s actually an art historian…

Life is not easy with vocal art historians ;)

By the way: Isn’t it the most natural choice to choose art history as profession when building websites?! Who needs mathematics or computer sciences?

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