In the web site I’m creating for a client he’ll be entering in the full date for an entry and then in the HTML I need them to be grouped by decade in reverse chronological order.

That might not be too difficult except that I would like each decade to auto-generate as it’s needed. So, for example, if the first entry is dated back to 1974 then the 1970’s would be the first decade show. Since there were no entries in the 1960’s it wouldn’t show and so forth.

The one saving grace is that while the 70’s or there abouts might be the first entry they do exist in every decade until current times. I’m sure I could manually create every decade I needed until 2010 but I’m wondering if it wouldn’t be more future-proof to have the decades created with XSLT.

This will likely be the most advanced piece of XSLT I have done to date and I’m not sure where exactly to start…

The XML will look similar to this:

    <date>2010-05-22, 13:23</date>

I’ve done something simiar a couple of weeks ago: I’ve created a yearly grouping template.

It’s basically a generic loop template (loop.xsl), another one to overload each loop iteration and wrap the looping head (years.xsl) and the calling page (page.xsl).

All you have to do is make the incremental parameterizeable (and redo the “limit hit”-condition) and change the logic in <xsl:template name="years-item" />.

Thanks Phoque, this’ll be a great start for me.

Very cool Phoque!

All you have to do is make the incremental parameterizeable…


I had to look at that a few times before I figured out what he meant. I half expected to see ‘paradigm’ and ‘shifting’ sneak in there somewhere…

<xsl:sort select="substring(entry/date, 1, 3)" data-type="number" order="ascending"/>

That’ll do, Doug, that’ll do.

Your’s is close, Tony. The issue is I also needed to insert the decade in there, which yours wouldn’t do. However, I was able to make it work with this bit of XSLT:

<xsl:for-each select="year">
    <xsl:sort select="@value" order="descending"/>
    <xsl:variable name="decade" select="substring(@value,1,3)" />
    <xsl:variable name="position" select="position()" />
    <xsl:if test="substring(@value,1,3) != substring(../year[position() = $position - 1]/@value,1,3)">
        <dt><xsl:value-of select="substring(@value,1,3)"/>0's</dt>
    <xsl:for-each select=".">
        <xsl:if test="$decade = substring(@value,1,3)">
            <xsl:for-each select="month/entry">
                <dd><xsl:value-of select="date"/></dd>

It’s probably a bit messy by most standards but it does the trick perfectly. (I did simplify a few things so you didn’t have all my extra nonsense in there.)

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