So ermitteln Sie die Position eines Navigationspunktes

Dieser Artikel beschreibt, wie Sie die Position eines Navigationspunktes ermitteln können, um so z.B. den ersten und/oder letzten Navigationspunkt anders gestalten zu können.

Um in einer Navigation den ersten bzw. letzten Navigationspunkt im Menü anders darzustellen, greifen Sie einfach auf die Bordmittel von XSLT zurück. Nachfolgendes Beispiel führt an, wie Sie den letzten Navigationspunkt eines Levels z.B. mit einer anderen Klasse versehen können. Hierzu wird die xPath-Funktion position() verwendet, die die Position eines Knotens ermittelt, also z.B. auch den ersten (first: "position() = 1") oder letzten (last: "position() = last()").

...
  <xsl:template match="/wNavigation">
    <div>
      <!-- Hier steht später die generierte Navigation -->
      <xsl:apply-templates select="/wNavigation/navPoint"/>
    </div>
  </xsl:template>

  <!--Dieses Template wird auf jeden Navigtionspunkt des ersten Levels angewandt-->
  <xsl:template match="/wNavigation/navPoint">
    <xsl:choose>
      <xsl:when test="@selected = '1'">
        <a class="navLevel1Selected" href="{@link}{@navidExtIfNeeded}">
          <xsl:if test="@target != ''"><xsl:attribute name="target"><xsl:value-of select="@target"/></xsl:attribute></xsl:if>
          <xsl:value-of select="@text"/>
        </a>
      </xsl:when>
      <xsl:otherwise>
        <a class="navLevel1" href="{@link}{@navidExtIfNeeded}">
          <xsl:if test="@target != ''"><xsl:attribute name="target"><xsl:value-of select="@target"/></xsl:attribute></xsl:if>
          <xsl:if test="position() = last()"><xsl:attribute name="class">navLevel1Last</xsl:attribute></xsl:if>
          <xsl:value-of select="@text"/>
        </a>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
...

Wollen Sie zu einem bestimmten Navigationspunkt (z.B. Unternehmen) z.B. die ersten beiden Unterpunkte hervorheben, kann dies so aussehen (Auszug aus sub.wNavigation.php, Stelle: test="position()&lt;= 2 and ancestor::navPoint/@text = 'Unternehmen'"):

...
  <!--Dieses Template wird auf jeden Navigtionspunkt des zweiten Levels angewandt-->
  <xsl:template match="/wNavigation/navPoint/navPoint">
  
    <xsl:choose>
      <xsl:when test="@selected = '1' and @open = '1' and count(child::*) > 0">
        .....
      </xsl:when>
      <xsl:otherwise>
        <li class="navLevel2">
          <a class="navLevel2" title="{@title}" href="{@link}{@navidExtIfNeeded}">
            <xsl:if test="@target != '' and @target != '_self'"><xsl:attribute name="target"><xsl:value-of select="@target" /></xsl:attribute></xsl:if>
            <xsl:if test="position()&lt;= 2 and ancestor::navPoint/@text = 'Unternehmen'"><xsl:attribute name="class">navLevel2Important</xsl:attribute></xsl:if>
            <xsl:value-of select="@text"/>
          </a>
        </li>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
...
FAQs
Wie kann ich die Position eines Navigationspunktes in XSLT ermitteln?
Mit der XPath-Funktion <code class="codeInline">position()</code> können Sie die Position eines Knotens innerhalb seiner Geschwister ermitteln. Damit lassen sich z.B. der erste und/oder letzte Navigationspunkt erkennen, z.B. über <code class="codeInline">position() = 1</code> bzw. <code class="codeInline">position() = last()</code>.
Wie markiere ich in einer Navigation den letzten Navigationspunkt eines Levels anders (z.B. mit anderer CSS-Klasse)?
Im passenden XSLT-Template prüfen Sie, ob der aktuelle <code class="codeInline">navPoint</code> die letzte Position im jeweiligen Level hat. Beispiel-Idee: In einem Template für den ersten Level kann bei <code class="codeInline">position() = last()</code> eine zusätzliche Klasse gesetzt werden, z.B. <code class="codeInline">class="navLevel1Last"</code>.
Wie kann ich den ersten Navigationspunkt in einer Liste gesondert behandeln?
Analog zum letzten Navigationspunkt können Sie den ersten erkennen, indem Sie prüfen, ob <code class="codeInline">position() = 1</code> gilt. Über diese Bedingung können Sie z.B. eine andere Klasse oder einen anderen Link-Output erzeugen.
Wie hebe ich gezielt die ersten beiden Unterpunkte hervor, die zu einem bestimmten übergeordneten Navigationspunkt gehören?
Nutzen Sie eine Bedingung, die sowohl die Position (z.B. <code class="codeInline">position() <= 2</code>) als auch das zugehörige Eltern-Element berücksichtigt. Im Beispiel wird im zweiten Level geprüft, ob <code class="codeInline">position() <= 2</code> gilt und ob der betreffende Unterpunkt ein Nachfahre eines <code class="codeInline">navPoint</code> ist, dessen <code class="codeInline">@text</code> z.B. den Wert <code class="codeInline">Unternehmen</code> hat (<code class="codeInline">ancestor::navPoint/@text = 'Unternehmen'</code>). Dann wird z.B. eine Klasse wie <code class="codeInline">navLevel2Important</code> gesetzt.
Kann ich die Logik zur Ausgabe der Navigation in XSLT-Templates je Level trennen?
Ja. Für jeden Navigationslevel können eigene Templates verwendet werden, z.B. ein Template für <code class="codeInline">/wNavigation/navPoint</code> (Level 1) und ein weiteres Template für <code class="codeInline">/wNavigation/navPoint/navPoint</code> (Level 2). So können Sie pro Level unterschiedliche Klassen oder Ausgaberegeln anwenden.
Wie kann ich beim Hervorheben eines Navigationspunktes zusätzliche Attribute wie CSS-Klassen setzen?
Innerhalb eines <code class="codeInline">xsl:if</code> bzw. <code class="codeInline">xsl:when</code> können Sie mit <code class="codeInline">xsl:attribute</code> dynamisch Attribute setzen. Das Beispiel zeigt, dass bei erfüllter Bedingung (z.B. letzter Eintrag oder „wichtige“ Unterpunkte) eine Klasse per <code class="codeInline">xsl:attribute name="class"</code> hinzugefügt wird.