Search

Heloo,

Would the Ninja technique be something that could check if a H2 tag follows directly after a H1 tag or not? and if a H2 is present in the condition add a class to it?

I've got a design that has H1 and H2 butted up right next to each other if there is a H2 straight after the H1... it looks really nice, but I wondered whether I could target the nodes with ninja technique?

Oh and the h1 is in the pagetemplate, but the H2 might come from a content block in a copy-of output. possible?

If this is CSS related could you not just use an adjacent selector?

.container h1 + h2 { /* Stylez */ }

You could write a fallback quite easily if your using a JS library already on your project, ( jQuery? http://api.jquery.com/next/ ).

Am afraid I couldn't answer from an XLST perspective but that may assist as an interim if you're struggling?

Would the Ninja technique be something that could check if a H2 tag follows directly after a H1 tag or not? and if a H2 is present in the condition add a class to it?

Definitely.

Match your h2 and something like:

<xsl:if test="name(preceding-sibling::*[last()])='h1'">...</xsl:if>

The preceding-sibling::* axis will return all children (regardless of the element name) before the current (h2) element, starting from the parent, so you want the last sibling (the one just before the current element). Check the element name is an h1 or not.

Thanks Nick, Ryu. XSLT is preferable here - will get playing!

Hi Nick, would have a minute to check I've got this xpathr test right? Not getting a class on H2 at present?

I'll keep playing but if you had any advice as to where It's not matching correctly, that would be ace!

You don't have an h1 in the source XML. I was expecting XML like:

<h1>Foo</h1>
<h2>Bar</h2>
<p>...</p>

Oh and the h1 is in the pagetemplate, but the H2 might come from a content block in a copy-of output. possible?

Ah I did not read this bit.

Would it work at all, based on this new info you think? by matching on the data node and applying the html ninja technique or would the match and template manipulation have already been processed?

Do you add the h1 and h2 manually or are they present in your XML?

H1 is preset from the Page template and H2 is added by user.. so I'm trying to determine if the user has entered a H2 tag and if it follows the H1 - append a specific class if the condition is true.

There are a few other H2's I don't want to affect and I'd rather target it using XSLT as there is a danger of overloaded styles and conditions for each H2/H1 in the main content block of the page if possible.

Surely then you're just looking to see whether the first element inside page-content is an h2, or whether it contains any h2s at all?

When you put it like that yes I guess I am :)

Ok so I'm trying the matching of preceding sibling just out of interest and nothing gets renedered in the result for the sub-title class of H2.

Could a NINJA give me a pointer as to why this might not be working pretty please?

http://xpathr.com/view/2036268/

How should the desired output look like?

I've not tested it, but are you looking for something like this?
http://xpathr.com/view/2038224/

Yes! Thanks Nils, this is what I was trying to achieve. Thank you very much. I added the ability to append any classes that might have already been on the h2 tag just in case I needed it.

Works great now! http://xpathr.com/view/2036268

You are currently adding each and every attribute as class. Change <xsl:value-of select="@*"/> to <xsl:value-of select="@class"/> to change this – you'll need a few more steps if you'd like to keep other attributes, too.

Ahh gotcha! thanks for pointing this out. Getting to understand how the match is working a little better now.

I am wondering if the proposed code will really work as expected because to my knowledge the preceding-sibling:: axis is reversed. So preceding-sibling::*[1] will return the element directly preceding the context and precesing-sibling::*[last()] will be the one at the very top, i.e.

<div>
    <h1 last() />
    <p 3 >
    <p 2 >
    <h1 1 />
    <h2 context />
</div>

Oh I see you already figured out the correct axis direction.

After reading through your messages a second time I am still confused what you're trying to achieve and what your code does.

<xsl:when test="name(following-sibling::*[1])">

to me that maches all nodes that have a following sibling whose name isn't false. In your example it does work because the second h2 doesn't have any following siblings at all.

It looks like you're looking for "the very first element of my text, if it's a h2", right?

In this case I would suggest

<xsl:template match="h2[not(preceding-sibling::*)]" mode="html" priority="1">
    <h2>
        <xsl:attribute name="class">sub-title</xsl:attribute>
        <xsl:apply-templates select="* | text()" mode="html"/>
    </h2>
</xsl:template>

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