Re: [xsl] displaying selective links in ouput

Subject: Re: [xsl] displaying selective links in ouput
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 30 Oct 2003 10:38:33 +0000
Hi James,

> I am stil having a bit of trouble with the selective links problem.
> Bascially i would like to display the the alpahbet at the top of the
> page and have a link (#b for example) to a letter if a title starts
> with it.

The easiest way to do this, I think, is with a recursive template that
goes through the letters of the alphabet one by one and on each
recursion checks whether there's anything to link to, using the key
that you've set up.

The recursive template needs to take a string as its only parameter:
it's initialised to the uppercase alphabet:

<xsl:template name="alphabetLinks">
  <xsl:param name="alphabet" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  ...
</xsl:template>

We'll be recursing through this alphabet, using the first letter each
time and passing the rest of the alphabet on to the next recursion. So
the letter we're interested in is the first character in the value of
the $alphabet parameter:

<xsl:template name="alphabetLinks">
  <xsl:param name="alphabet" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  <xsl:variable name="letter" select="substring($alphabet, 1, 1)" />
  ...
</xsl:template>

And if there's anything left in the alphabet, we want to recurse on to
the rest of the alphabet:

<xsl:template name="alphabetLinks">
  <xsl:param name="alphabet" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  <xsl:variable name="letter" select="substring($alphabet, 1, 1)" />
  ...
  <xsl:variable name="rest" select="substring($alphabet, 2)" />
  <xsl:if test="$rest">
    <xsl:call-template name="alphabetLinks">
      <xsl:with-param name="alphabet" select="$rest" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

To actually create the output, we need to check whether there are any
entries to link to: if there are, we make a link; if there aren't, we
don't:

<xsl:template name="alphabetLinks">
  <xsl:param name="alphabet" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  <xsl:variable name="letter" select="substring($alphabet, 1, 1)" />
  <xsl:choose>
    <xsl:when test="key('ve-by-firstoccurrence', $letter)">
      <a href="#{$letter}">
        <xsl:value-of select="$letter" />
      </a>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$letter" />
    </xsl:otherwise>
  </xsl:choose>
  <xsl:variable name="rest" select="substring($alphabet, 2)" />
  <xsl:if test="$rest">
    <xsl:call-template name="alphabetLinks">
      <xsl:with-param name="alphabet" select="$rest" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Just call this template at the place where you want the alphabet links
to be inserted, with:

  <xsl:call-template name="alphabetLinks" />

I'll leave you to add the finishing touches such as any punctuation
you want around the letters.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread