2011-05-07 3 views
2

umbraco 설치에 superfish 탐색 메뉴를 구현했습니다. Superfish는 단순히 UL 요소를 가져 와서 상위 항목 위로 마우스를 가져 가면 하위 항목을 보여주는 계층 적 메뉴로 바꿉니다.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

당신은 매우 중요한 무언가를 제공하기 위해 forgotton했다. 이렇게하십시오. 또한이 XML 문서에서 예상되는 변환 결과, 실제로 얻은 결과 및 문제를 고려한 실제 결과와 예상 결과의 차이점을 제공하십시오. –

+0

당신은 umbraco와 함께 일하지 않는 것이 좋습니다? XML 문서가 umbraco 프레임 워크에 의해 노출되고 사이트 내의 페이지 목록 인 XML입니다. 예 : .... Baldy

+0

@Baldy : 아니, Umbraco와는 작동하지 않지만 나는 XSLT 문제를 돕고 싶다. 이는 필요한 정보를 제공 한 경우에만 가능합니다. xslt 태그의 독자가 Umbraco에 대해 알아야한다고 가정하지 마십시오. –

답변

1

위에서 설명한 문제는 나를 복제하는 것이 아닙니다 (메모장 + + 및 diff 뷰어를 사용하여 소스 코드를 확인했습니다). 귀하의 코드에서 CogWorks의 유연한 탐색 패키지를 사용하고 있습니다. here의 최신 코드를 사용하고 있는지 확인할 수 있습니까? 변형되고있는 XML 문서 :

많은 감사,

벤자민

+1

안녕 벤자민. 내 자신의 xslt 파일을 처음부터 다시 작성하여 문제를 해결했습니다 (해킹 비트이지만 작동했습니다). 프로젝트가 현재 출하되고 내 손에 들고 있기 때문에 어느 버전이 실행 중인지 잘 모르겠습니다. 디버깅에 도움이되는 원래 질문에 대한 의견에 대한 답을 얻습니다. 건배 :) – Baldy