2011-05-07 23 views
2

我已將superfish導航菜單實施爲umbraco安裝。 Superfish只需要一個UL元素,並將其轉變爲一個分層菜單,當您將鼠標懸停在父項上方(您記得1999年它們已經很酷時,它是否正確?)。使用XSLT宏的Umbraco導航 - 無子節點的問題

我不明白爲什麼,在某些頁面(通常是沒有孩子的頁面),菜單不顯示任何頁面的子項目。我對XSLT的暴露很少,所以我必須忽略一些邏輯。

你可以看到實際的網站here將鼠標懸停在「個人培訓」上查看菜單的工作,現在點擊「體重管理」,嘿,發生魔術停止。

創建UL結構的XSLT位於下方,HTML頁面源告訴我它在問題發生時根本不爲子頁面生成任何LI元素。

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]> 
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxml="urn:schemas-microsoft-com:xslt" 
    xmlns:umbraco.library="urn:umbraco.library" 
    exclude-result-prefixes="msxml umbraco.library"> 

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

<xsl:param name="currentPage" /> 

<!--This sets the level that the nav starts at and tells us if we should recurse through child elements--> 
<xsl:variable name="startDepth" select="/macro/startingLevel" /> 
<xsl:variable name="recurse" select="/macro/recurse" /> 
<xsl:variable name="selectBranches" select="/macro/selectBranches"></xsl:variable> 
<xsl:variable name="maxMenuDepth" select="/macro/maxMenuDepth"></xsl:variable> 
<xsl:variable name="forceNode" select="/macro/forceNode"></xsl:variable> 
<xsl:variable name="walkChildren" select="/macro/expandChildren"></xsl:variable> 
<xsl:variable name="forceHome" select="/macro/forceHome"></xsl:variable> 
<xsl:variable name="securityTrimming" select="/macro/securityTrimming"></xsl:variable> 
<!--Alternate page title variable in here--> 

<!--Styles for the navigation--> 
<xsl:variable name="ulBaseClass" select="/macro/ulBaseClass"></xsl:variable> 
<xsl:variable name="branchClass" select="/macro/branchClass"></xsl:variable> 
<xsl:variable name="selectedClass" select="/macro/selectedClass"></xsl:variable> 

<xsl:variable name="startLevel"> 
    <xsl:choose> 
    <xsl:when test="$startDepth >= 0"> 
     <xsl:value-of select="$startDepth"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$currentPage/@level"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 

    <!--This calls first iteration of the navigation, sending the first node at the correct depth found in the ancestors of the current page--> 
<xsl:template match="/"> 
    <xsl:choose> 
    <xsl:when test="$forceNode"> 
     <xsl:variable name="currentNode" select="umbraco.library:GetXmlNodeById($forceNode)"></xsl:variable> 
     <xsl:call-template name="nodeIterator"> 
     <xsl:with-param name="parentNode" select="$currentNode/ancestor-or-self::*[@isDoc][@level=$startLevel] 
         [ 
          string(umbracoNaviHide) != '1' 
          and ($securityTrimming != '1' 
          or umbraco.library:IsProtected(@id, @path) = false() 
          or umbraco.library:HasAccess(@id, @path) = true()) 
         ]" /> 
     <xsl:with-param name="pseudoCurrentPage" select="$currentNode" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:variable name="currentNode" select="$currentPage"></xsl:variable> 
     <xsl:call-template name="nodeIterator"> 
     <xsl:with-param name="parentNode" select="$currentNode/ancestor-or-self::*[@isDoc][@level=$startLevel] 
         [ 
          string(umbracoNaviHide) != '1' 
          and ($securityTrimming != '1' 
          or umbraco.library:IsProtected(@id, @path) = false() 
          or umbraco.library:HasAccess(@id, @path) = true()) 
         ]" /> 
     <xsl:with-param name="pseudoCurrentPage" select="$currentNode" /> 
     </xsl:call-template> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="nodeIterator"> 
    <xsl:param name="parentNode" /> 
    <xsl:param name="pseudoCurrentPage" /> 
    <!-- do not show info doc node types--> 
    <xsl:variable name="calculatedMenuDepth" select="($parentNode/@level - $startLevel)+1" /> 

    <xsl:if test="$parentNode/*[@isDoc] or ($calculatedMenuDepth = 1 and $forceHome)"> 
    <ul> 

     <xsl:attribute name="class"> 
     <xsl:choose> 
      <xsl:when test="$calculatedMenuDepth = 1"> 
      <xsl:value-of select="$ulBaseClass" /> 
      </xsl:when> 
      <!--<xsl:when test="$calculatedMenuDepth = 1"> 
      <xsl:value-of select="concat($ulBaseClass, ' lv', $calculatedMenuDepth)" /> 
      </xsl:when> 
      <xsl:when test="$calculatedMenuDepth > 1"> 
      <xsl:value-of select="concat('lv', $calculatedMenuDepth)" /> 
      </xsl:when>--> 
     </xsl:choose> 
     </xsl:attribute> 

     <xsl:if test="$forceHome = 1 and $calculatedMenuDepth = 1"> 
     <!-- Create the class for the li element--> 
     <li> 
      <xsl:variable name="isHomeSelected"> 
      <xsl:choose> 
       <xsl:when test="$currentPage/ancestor-or-self::*[@isDoc][@level=1]/@id = $currentPage/@id">1</xsl:when> 
      </xsl:choose> 
      </xsl:variable> 

      <xsl:call-template name="cssClassConstructor"> 
      <xsl:with-param name="isSelected" select="$isHomeSelected" /> 
      <xsl:with-param name="isSelectedBranch" select="0" /> 
      <xsl:with-param name="hasChildren" select="1" /> 
      <xsl:with-param name="selectedClass" select="$selectedClass" /> 
      <xsl:with-param name="branchClass" select="$branchClass" /> 
      </xsl:call-template> 

      <a href="{umbraco.library:NiceUrl($currentPage/ancestor-or-self::*[@isDoc][@level=1]/@id)}"> 

      <xsl:call-template name="cssClassConstructor"> 
       <xsl:with-param name="isSelected" select="$isHomeSelected" /> 
       <xsl:with-param name="isSelectedBranch" select="0" /> 
       <xsl:with-param name="hasChildren" select="0" /> 
       <xsl:with-param name="selectedClass" select="$selectedClass" /> 
       <xsl:with-param name="branchClass" select="$branchClass" /> 
      </xsl:call-template> 

      <!--set the innerText for the a element--> 
      <xsl:value-of select="$currentPage/ancestor-or-self::*[@isDoc][@level=1]/text()"/> 

      <xsl:if test="string($currentPage/ancestor-or-self::*[@isDoc][@level=1]/text()) = ''"> 
       <xsl:value-of select="$currentPage/ancestor-or-self::*[@isDoc][@level=1]/@nodeName"/> 
      </xsl:if> 
      </a> 
     </li> 
     </xsl:if> 
     <!--End force home--> 


     <!--for each node in the parent node that is not hidden by Umbraco--> 
     <xsl:for-each select="$parentNode/*[@isDoc][ 
          string(umbracoNaviHide) != '1' 
          and ($securityTrimming != '1' 
          or umbraco.library:IsProtected(@id, @path) = false() 
          or umbraco.library:HasAccess(@id, @path) = true()) 
         ]"> 

     <!--Set the current node id i.e. the node we have looped to not the current page--> 
     <xsl:variable name="currentNodeID" select="@id" /> 

     <!--Is the node a branch? i.e. are there children and is it in the colletion of ancestor nodes --> 
     <xsl:variable name="isBranch"> 
      <xsl:choose> 
      <xsl:when test="$currentPage/ancestor-or-self::*[@isDoc][@id = $currentNodeID]/child::*[@isDoc]">1</xsl:when> 
      </xsl:choose> 
     </xsl:variable> 

     <!--Is the node selected? i.e. is it the same as the currentPage node--> 
     <xsl:variable name="isSelected"> 
      <xsl:choose> 
      <xsl:when test="$currentPage/@id = $currentNodeID">1</xsl:when> 
      <!-- parent selected --> 
      <xsl:when test="$pseudoCurrentPage/@id = $currentNodeID">1</xsl:when> 

      </xsl:choose> 
     </xsl:variable> 

     <xsl:variable name="isSelectedBranch"> 
      <xsl:choose> 
      <xsl:when test="$isBranch = 1 and $selectBranches = 1">1</xsl:when> 
      </xsl:choose> 
     </xsl:variable> 

     <xsl:variable name="hasChildren"> 
      <xsl:choose> 
      <xsl:when test="./*[@isDoc]">1</xsl:when> 
      </xsl:choose> 
     </xsl:variable> 

     <li> 

      <!-- Create the class attribute for the element--> 
      <xsl:call-template name="cssClassConstructor"> 
      <xsl:with-param name="isSelected" select="$isSelected" /> 
      <xsl:with-param name="isSelectedBranch" select="$isSelectedBranch" /> 
      <xsl:with-param name="hasChildren" select="$hasChildren" /> 
      <xsl:with-param name="selectedClass" select="$selectedClass" /> 
      <xsl:with-param name="branchClass" select="$branchClass" /> 
      </xsl:call-template> 

      <a href="{umbraco.library:NiceUrl(@id)}"> 

      <xsl:call-template name="cssClassConstructor"> 
       <xsl:with-param name="isSelected" select="$isSelected" /> 
       <xsl:with-param name="isSelectedBranch" select="$isSelectedBranch" /> 
       <xsl:with-param name="hasChildren" select="0" /> 
       <xsl:with-param name="selectedClass" select="$selectedClass" /> 
       <xsl:with-param name="branchClass" select="$branchClass" /> 
      </xsl:call-template> 

      <!--set the innerText for the a element--> 
      <xsl:value-of select="./pageTitle/text()"/> 
      <xsl:if test="string(./pageTitle/text()) = ''"> 
       <xsl:value-of select="@nodeName"/> 
      </xsl:if> 
      </a> 

      <!-- if it's a branch recurse through it's children--> 
      <xsl:if test="((($isBranch = 1 and $recurse = 1) or ($walkChildren = 1 and $pseudoCurrentPage/descendant-or-self::*[@isDoc][@id = $currentNodeID]/child::*[@isDoc])) and $maxMenuDepth &gt; $calculatedMenuDepth)"> 
      <xsl:call-template name="nodeIterator"> 
       <xsl:with-param name="parentNode" select="." /> 
       <xsl:with-param name="pseudoCurrentPage" select="$pseudoCurrentPage" /> 
      </xsl:call-template> 
      </xsl:if> 

     </li> 

     </xsl:for-each> 

    </ul> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="cssClassConstructor"> 
    <xsl:param name="isSelected"></xsl:param> 
    <xsl:param name="isSelectedBranch"></xsl:param> 
    <xsl:param name="hasChildren"></xsl:param> 
    <xsl:param name="selectedClass"></xsl:param> 
    <xsl:param name="branchClass"></xsl:param> 

    <xsl:variable name="class"> 
     <xsl:if test="$isSelected = 1"> 
     <xsl:value-of select="concat($selectedClass,' ')"/> 
     </xsl:if> 
     <xsl:if test="$isSelectedBranch = 1"> 
     <xsl:value-of select="concat($branchClass,' ')"/> 
     </xsl:if> 
     <xsl:if test="$hasChildren = 1"> 
     <xsl:value-of select="'hasChildren '"/> 
     </xsl:if> 
    </xsl:variable> 

    <xsl:if test="string-length($class) > 0"> 
     <xsl:attribute name="class"> 
     <xsl:value-of select="normalize-space($class)"/> 
     </xsl:attribute> 
    </xsl:if> 

    </xsl:template> 
</xsl:stylesheet>​ 
+0

你福爾戈提供很重要的事:它正在轉化XML文檔。請這樣做。此外,請提供此XML文檔轉換的預期結果,您實際得到的結果以及您認爲是問題的實際結果和預期結果之間的差異。 – 2011-05-07 16:02:45

+0

這會暗示你不會和umbraco一起工作?因爲xml文檔是由umbraco框架公開的,並且是網站內頁面的xml列表。例如.... Baldy 2011-05-07 19:25:47

+0

@Baldy:不,我不與Umbraco合作,但我想幫助解決XSLT問題。這隻有在您提供必要的信息時纔有可能。永遠不要假設xslt標籤的讀者應該知道任何有關Umbraco的信息。 – 2011-05-07 21:54:32

回答

1

你上面描述的問題不是我複製的(我使用Notepad ++和差異查看器檢查了你的源代碼)。我從您的代碼中看到您正在使用CogWorks的靈活導航軟件包。你能確保你使用的最新代碼是here

非常感謝,

本傑明

+1

嗨本傑明。我通過從頭開始重建我自己的xslt文件解決了這個問題(一點點黑客,但它工作)。由於該項目已發貨並且不在我手中,因此無法確定哪個版本正在運行。你可以在我的原始問題上得到你的評論的答案,這有助於一般的調試。歡呼:) – Baldy 2011-05-18 08:46:01