Я создал меню в umbraco, используя XSLT. В меню используются обычные элементы ul и li, и я отображаю только первый уровень меню. Цель состоит в том, чтобы создать меню, которое раскрывается для отображения подменю при щелчке по родительскому узлу (на верхнем уровне).
Я после xslt мне нужно было бы открыть подменю при нажатии.
Я думаю, мне нужно будет использовать ancestor-or-self для определения текущего меню и родительского меню и их отображения, а также переменной $ currentPage.
У меня есть следующий xslt:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:tagsLib="urn:tagsLib" xmlns:urlLib="urn:urlLib"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib urlLib ">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:template match="/">
<div id="kb-categories">
<h3>Categories</h3>
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="$currentPage/ancestor-or-self::node [@level=1]"/>
</xsl:call-template>
</div>
</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 $parent/@level = 1">
<ul class="kb-menuLevel1" >
<xsl:for-each select="$parent/node [string(./data [@alias='showInMenu']) = 1]">
<li>
<a href="/kb{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
<xsl:variable name="level" select="@level" />
<xsl:if test="(count(./node [string(./data [@alias='showInMenu']) = '1']) > 0)">
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="."/>
</xsl:call-template>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</xsl:if>
<xsl:if test="(umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1)) and $parent/@level > 1">
<ul class="kb-menuLevel{@level}" style="display: none;">
<xsl:for-each select="$parent/node [string(./data [@alias='showInMenu']) = 1]">
<li>
<a href="/kb{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName"/>
</a>
<xsl:variable name="level" select="@level" />
<xsl:if test="(count(./node [string(./data [@alias='showInMenu']) = '1']) > 0)">
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="."/>
</xsl:call-template>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Я подозреваю, что это можно улучшить с помощью apply-templates, но я еще не в курсе этого (это всего лишь второй день моего изучения xslt).
Мое меню:
- Пункт меню 1
- Пункт меню 2
- Пункт меню 3
- Пункт меню 4
когда я нажимаю на пункт меню 2, я перехожу на страницу для пункта меню 2, и также отображается подменю:
- Пункт меню 1
- Пункт меню 2
- Пункт меню 2.1
- Пункт меню 2.2
- Пункт меню 3
- Пункт меню 4
и т. Д. Во вложенном меню.
Вот пример xml для вышеперечисленного.
<root>
<node id="1" nodeTypeAlias="kbHomepage" nodeName="Home" level="1">
<data alias="introduction">
<![CDATA[<p>Welcome</p>]]>
</data>
<node id="2" nodeTypeAlias="guide" nodeName="Menu Item 1" level="2">
<data alias="bodyText">
<![CDATA[<p>This is some text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 1</data>
</node>
<node id="3" nodeTypeAlias="guide" nodeName="Menu Item 2" level="2">
<data alias="bodyText">
<![CDATA[<p>This is some text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 2</data>
<node id="4" nodeTypeAlias="guide" nodeName="Menu Item 2.1" level="3">
<data alias="bodyText">
<![CDATA[<p>Some Text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 2.1</data>
</node>
<node id="5" nodeTypeAlias="guide" nodeName="Menu Item 2.2" level="3">
<data alias="bodyText">
<![CDATA[<p>Some Text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 2.2</data>
<node id="6" nodeTypeAlias="guide" nodeName="Item 2.2.1 Guide" level="4">
<data alias="bodyText">
<![CDATA[<p>Some Text</p>]]>
</data>
<data alias="showInMenu">0</data>
<data alias="menuName"></data>
</node>
</node>
</node>
<node id="8" nodeTypeAlias="guide" nodeName="Menu Item 3" level="2">
<data alias="bodyText">
<![CDATA[<p>This is some text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 3</data>
</node>
<node id="9" nodeTypeAlias="guide" nodeName="Menu Item 4" level="2">
<data alias="bodyText">
<![CDATA[<p>This is some text</p>]]>
</data>
<data alias="showInMenu">1</data>
<data alias="menuName">Menu Item 4</data>
</node>
</node>
<node id="7" nodeTypeAlias="someAlias" nodeName="Some Other Page" level="1">
<data alias="bodyText">
<![CDATA[<p>This is some text</p>]]>
</data>
</node>
</root>
edit: следующее почти делает то, что мне нужно:
<xsl:variable name="visibleChidren" select="node[data[@alias='showInMenu'] = 1 and (@level = 2 or descendant-or-self::*[generate-id($currentPage) = generate-id(.)] or preceding-sibling::*[generate-id($currentPage) = generate-id(.)] or following-sibling::*[generate-id($currentPage) = generate-id(.)])]" />
Мне просто нужно включить прямых детей с текущей страницы.