Search

I'm currently porting a static website to symphony cms. Looks great so far, but for CSS backwards compatibility I'd like to port my "numbered" CSS classes like "entry1", "entry2" etc. for the navigation.

I thought this might be possible to do in the XSLT template to just do it on the fly but I must admit I have no clue how to do that.

The bare navigation template fragment is the default one:

<xsl:template match="page">
    <li>
        <a href="{$root}/{@handle}/">
            <xsl:if test="@handle = $root-page">
                <xsl:attribute name="class">active</xsl:attribute>
            </xsl:if>
            <xsl:value-of select="name"/>
        </a>
    </li>
</xsl:template>

I'm running into two issues:

  1. How to create the numbering.
  2. How to extend the class attribute value.

For 1.) I have no clue at all, for 2.) I think if I have the value I can use the concat() string function, so this might not be really an issue.

You cannot append (AFAIK) attributes but you can add the logic inside of the attribute nodes. This should help you on your way. I also used the position() but I am suddenly doubting if that works in the context of a template match (it does work with for-loops). Anyway, this should get you going...

<xsl:template match="page">
    <li>
        <a href="{$root}/{@handle}/">
            <xsl:attribute name="class">
                <xsl:if test="@handle = $root-page"><xsl:text>active </xsl:text></xsl:if>
                <xsl:text><xsl:value-of select="concat('entry',position())"/></xsl:text>
            </xsl:attribute>
            <xsl:value-of select="name"/>
        </a>
    </li>
</xsl:template>

Thank you for your suggestion, I was able to modify it so that it works:

<xsl:template match="page">
    <li>
        <a href="{$root}/{@handle}/">
            <xsl:attribute name="class">
                <xsl:value-of select="concat('entry', position()+1)"/>
                <xsl:if test="@handle = $root-page"> active</xsl:if>
            </xsl:attribute>
            <xsl:value-of select="name"/>
        </a>
    </li>
</xsl:template>

The differences:

  1. I first output the numbered classname as it's not conditional, but active is, so I can add the space this needs between for a nice output.
  2. The <xsl:text> around the concat string value didn't work (XSLT processing error). I removed it.
  3. The <xsl:text> round the active is not needed.
  4. I use position()+1 because I prepend the navigation with a link to the homepage.

I also found this interesting looking article while originally googling, but then saw your answer and decided to go with position() as I knew it from xpath:

Thanks a lot!

Cool. Sorry for the little issues: I had little time and typed that from memory without checking. Strange that <xsl:text/> does not seem to work, though. I used it to control whitespace.

Anyway, thanks for that link; I've been meaning to look into <xsl:number/> as I've never used it before and it seems better suited than position() for something like your use-case

I can use it to control whitespace as well (in a similar case for the first menu element which is not part in that template match), however that one around the select gave me an error. I didn't understood I must admit, I'm really new to xslt and had to learn a bit what a template match is first. - however the error was not a stopper for me, I realized it quickly, so no worries. Your suggestion made perfect sense to me and I don't expect production code anyway.

Number might be better suited, however as far as I see <navigation> is flat, so position() works well for the moment.

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