2008-11-21 22 views
4

J'essaie de créer un menu CSS à plusieurs niveaux de dropdown pour un site Web que je fais sur le système de gestion de contenu umbraco.Construire un menu à plusieurs niveaux pour umbraco

J'ai besoin de construire pour avoir la structure suivante:

<ul id="nav"> 
    <li><a href="..">Page #1</a></li> 
    <li> 
    <a href="..">Page #2</a> 
    <ul> 
     <li><a href="..">Subpage #1</a></li> 
     <li><a href="..">Subpage #2</a></li>   
    </ul> 
    </li> 
</ul> 

Alors maintenant, je suis en train de comprendre comment faire l'imbrication en utilisant XSLT. Voilà ce que j'ai jusqu'à présent:

<xsl:output method="xml" omit-xml-declaration="yes"/> 

<xsl:param name="currentPage"/> 

<!-- update this variable on how deep your menu should be --> 
<xsl:variable name="maxLevelForMenu" select="4"/> 

<xsl:template match="/"> 
    <ul id="nav"> 
    <xsl:call-template name="drawNodes"> 
     <xsl:with-param 
     name="parent" 
     select="$currentPage/ancestor-or-self::node [@level=1]" 
     /> 
    </xsl:call-template> 
    </ul> 
</xsl:template> 

<xsl:template name="drawNodes"> 
    <xsl:param name="parent"/> 
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)"> 
    <xsl:for-each select="$parent/node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForMenu]"> 
     <li> 
     <a href="{umbraco.library:NiceUrl(@id)}"> 
      <xsl:value-of select="@nodeName"/> 
     </a> 
     <xsl:if test="count(./node [string(./data [@alias='umbracoNaviHide']) != '1' and @level &lt;= $maxLevelForMenu]) &gt; 0"> 
      <xsl:call-template name="drawNodes">  
      <xsl:with-param name="parent" select="."/>  
      </xsl:call-template> 
     </xsl:if> 
     </li> 
    </xsl:for-each> 
    </xsl:if> 
</xsl:template> 

Ce que je ne peux pas sembler comprendre comment vérifier si le premier niveau (ici Page # 1 et Page # 2) a des enfants, et si elles ajoutez le <ul> supplémentaire pour contenir les enfants <li>.

Quelqu'un est là pour me diriger dans la bonne direction?

Répondre

5

Tout d'abord, pas besoin de passer le paramètre a parent autour. Le contexte transportera cette information.

Voici la feuille de style XSL qui devrait résoudre votre problème:

<!-- update this variable on how deep your menu should be --> 
<xsl:variable name="maxLevelForMenu" select="4"/> 

<!--- match the document root ---> 
<xsl:template match="/root"> 
    <div id="nav"> 
    <xsl:call-template name="SubTree" /> 
    </div> 
</xsl:template> 

<!-- this will be called by xsl:apply-templates --> 
<xsl:template match="node"> 
    <!-- the node is either protected, or the user is logged on (no need to check for IsProtected twice) --> 
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or umbraco.library:IsLoggedOn() = 1"> 
    <li> 
     <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a> 
     <xsl:call-template name="SubTree" /> 
    </li> 
    </xsl:if> 
</xsl:template> 

<xsl:template name="SubTree"> 
    <!-- render sub-tree only if there are any child nodes ---> 
    <xsl:if test="node"> 
    <ul> 
     <xsl:apply-templates select="node[data[@alias='umbracoNaviHide'] != '1'][@level &lt;= $maxLevelForMenu]"> 
     <!-- ensure sorted output of the child nodes ---> 
     <xsl:sort select="@sortOrder" data-type="number" /> 
     </xsl:apply-templates> 
    </ul> 
    </xsl:if> 
</xsl:template> 

C'est le XML je l'ai testé sur (je ne sais pas beaucoup sur Umbraco, mais après avoir regardé quelques exemples que j'espère que je suis fermer un document Umbraco):

<root id="-1"> 
    <node id="1" level="1" sortOrder="1" nodeName="Page #1"> 
    <data alias="umbracoNaviHide">0</data> 
    </node> 
    <node id="2" level="1" sortOrder="2" nodeName="Page #2"> 
    <data alias="umbracoNaviHide">0</data> 
    <node id="3" level="2" sortOrder="2" nodeName="Subpage #2.2"> 
     <data alias="umbracoNaviHide">0</data> 
    </node> 
    <node id="4" level="2" sortOrder="1" nodeName="Subpage #2.1"> 
     <data alias="umbracoNaviHide">0</data> 
     <node id="5" level="3" sortOrder="3" nodeName="Subpage #2.1.1"> 
     <data alias="umbracoNaviHide">0</data> 
     </node> 
    </node> 
    <node id="6" level="2" sortOrder="3" nodeName="Subpage #2.3"> 
     <data alias="umbracoNaviHide">1</data> 
    </node> 
    </node> 
    <node id="7" level="1" sortOrder="3" nodeName="Page #3"> 
    <data alias="umbracoNaviHide">1</data> 
    </node> 
</root> 

C'est la sortie:

<div id="nav"> 
    <ul> 
    <li><a href="http://foo/">Page #1</a></li> 
    <li><a href="http://foo/">Page #2</a> 
     <ul> 
     <li><a href="http://foo/">Subpage #2.1</a> 
      <ul> 
      <li><a href="http://foo/">Subpage #2.1.1</a></li> 
      </ul> 
     </li> 
     <li><a href="http://foo/">Subpage #2.2</a></li> 
     </ul> 
    </li> 
    </ul> 
</div> 
+0

me a renvoyé l'erreur lors de l'enregistrement dans Umbraco 4.7.8 Une erreur est survenue Erreur dans XSLT à la ligne 33, char 11 31: 32:

  • 33: >>> 34: 35:
  • +0

    @Alexa C'est facile . Si vous regardez très fort à la ligne 33, vous verrez une erreur de syntaxe.(J'ai aussi corrigé ma réponse, mais vous auriez pu le voir vous-même.) – Tomalak

    +0

    Salut Tomalak, je suis très nouveau avec Umbraco, donc je n'ai pas repéré l'erreur de syntaxe: | –

    0

    Il n'y a rien g très spécial à propos de ce problème. Les tests de solution suivants que le nœud liste pour

    <xsl:apply-templates/>

    n'est pas vide, avant d'appliquer les modèles:

     
    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes"/> 
        <xsl:variable name="vLevel" select="0"/> 
    
        <xsl:template match="root"> 
         <xsl:variable name="vnextLevelNodes" 
          select="node[@level = $vLevel+1]"/> 
         <xsl:if test="$vnextLevelNodes"> 
         <ul> 
         <xsl:apply-templates select="$vnextLevelNodes"/> 
         </ul> 
         </xsl:if> 
        </xsl:template> 
    
        <xsl:template match="node"> 
        <!-- the node is either protected, or the user is logged on (no need to check for IsProtected twice) --> 
        <!-- <xsl:if test= 
         "umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 
         or 
         umbraco.library:IsLoggedOn() = 1"> --> 
        <xsl:if test="1"> 
         <li> 
          <!-- <a href="{umbraco.library:NiceUrl(@id)}"> --> 
          <a href="'umbraco.library:NiceUrl(@id)'"> 
          <xsl:value-of select="@nodeName"/> 
          </a> 
    
            <xsl:variable name="vnextLevelNodes" 
             select="node[@level = current()/@level+1]"/> 
            <xsl:if test="$vnextLevelNodes"> 
            <ul> 
            <xsl:apply-templates select="$vnextLevelNodes"/> 
            </ul> 
            </xsl:if> 
         </li> 
        </xsl:if> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    J'ai utilisé le document source XML suivant:

     
    <root id="-1"> 
        <node id="1" level="1" sortOrder="1" nodeName="Page #1"> 
         <data alias="umbracoNaviHide">0</data> 
        </node> 
        <node id="2" level="1" sortOrder="2" nodeName="Page #2"> 
         <data alias="umbracoNaviHide">0</data> 
         <node id="3" level="2" sortOrder="2" nodeName="Subpage #2.2"> 
          <data alias="umbracoNaviHide">0</data> 
         </node> 
         <node id="4" level="2" sortOrder="1" nodeName="Subpage #2.1"> 
          <data alias="umbracoNaviHide">0</data> 
          <node id="5" level="3" sortOrder="3" nodeName="Subpage #2.1.1"> 
           <data alias="umbracoNaviHide">0</data> 
          </node> 
         </node> 
         <node id="6" level="2" sortOrder="3" nodeName="Subpage #2.3"> 
          <data alias="umbracoNaviHide">1</data> 
         </node> 
        </node> 
        <node id="7" level="1" sortOrder="3" nodeName="Page #3"> 
         <data alias="umbracoNaviHide">1</data> 
        </node> 
    </root> 
    

    Aussi, je J'ai commenté tout code faisant référence aux fonctions d'extension d'Umbraco, car je n'y ai pas accès.

    Lorsque la transformation ci-dessus est appliquée sur ce document XML source, la bonne, est produit voulu résultat:

     
    <ul> 
        <li> 
         <a href="'umbraco.library:NiceUrl(@id)'">Page #1</a> 
        </li> 
        <li> 
         <a href="'umbraco.library:NiceUrl(@id)'">Page #2</a> 
         <ul> 
          <li> 
           <a href="'umbraco.library:NiceUrl(@id)'">Subpage #2.2</a> 
          </li> 
          <li> 
           <a href="'umbraco.library:NiceUrl(@id)'">Subpage #2.1</a> 
           <ul> 
            <li> 
             <a href="'umbraco.library:NiceUrl(@id)'">Subpage #2.1.1</a> 
            </li> 
           </ul> 
          </li> 
          <li> 
           <a href="'umbraco.library:NiceUrl(@id)'">Subpage #2.3</a> 
          </li> 
         </ul> 
        </li> 
        <li> 
         <a href="'umbraco.library:NiceUrl(@id)'">Page #3</a> 
        </li> 
    </ul> 
    

    Hope this aidé.

    Cheers,

    Dimitre Novatchev

    Questions connexes