문제
Umbraco Content Management 시스템에서하고있는 웹 사이트를위한 다단계 드롭 드라운 CSS 메뉴를 구축하려고합니다.
다음 구조를 확보하려면 구축해야합니다.
<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 <= $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 <= $maxLevelForMenu]) > 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 페이지와 페이지 #2 페이지)에 어린이가 있는지 확인하는 방법과 추가 사항을 추가하는지 확인하는 방법입니다. <ul>
포함 <li>
어린이들.
나를 올바른 방향으로 가리키는 사람이 있습니까?
해결책
우선, a를 통과 할 필요가 없습니다 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 <= $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>
다른 팁
이 문제에 대해 특별한 것은 없습니다. 다음 솔루션은 노드 목록을 테스트합니다
<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
제휴하지 않습니다 StackOverflow