2008-11-21 4 views
4

Я пытаюсь создать многоуровневое меню CSS для веб-сайта, которое я делаю в системе управления содержимым umbraco.Создание многоуровневого меню для umbraco

мне нужно, чтобы построить его, чтобы иметь следующую структуру:

<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> 

Так что теперь я пытаюсь выяснить, как сделать вложенность с помощью XSLT. Это то, что я до сих пор:

<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> 

То, что я не могу показаться, чтобы выяснить, как проверить, если первый уровень (здесь Страница № 1 и Page # 2) имеет какие-либо детей, и если они делают добавьте дополнительно <ul>, чтобы содержать детей <li>.

Кто-нибудь там, чтобы указать мне в правильном направлении?

ответ

5

Прежде всего, не нужно передавать параметр parent. Контекст будет передавать эту информацию.

Вот XSL таблицу стилей, которая должна решить вашу проблему:

<!-- 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> 

Это XML я проверил его (я не знаю много о Umbraco, но посмотрев на некоторых образцах, я надеюсь, я получил близко к документу 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> 

Это выход:

<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

возвращается мне ошибка при сохранении в Umbraco 4.7.8 произошла ошибка Ошибки в XSLT в строке 33, символ 11 31: 32:

  • 33: >>><<< 34: 35:
  • 2012-07-23 06:36:26

    0

    Существует Nothin g очень особенная проблема. Следующие тесты решение о том, что узел-лист для

    <xsl:apply-templates/>

    не является пустым, перед применением шаблонов:

     
    <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> 
    

    я использовал следующий исходный XML-документ:

     
    <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> 
    

    Кроме того, я прокомментировал какой-либо код, ссылающийся на функции расширения Umbraco, поскольку у меня нет доступа к ним.

    Когда выше преобразование применяются на этом исходном документе XML, правильный, хотел результат получается:

     
    <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> 
    

    Надеется, что это помогло.

    Приветствие,

    Dimitre Novatchev

    Смежные вопросы