Идентифицировать нужные нам системные страницы мы будем при помощи атрибутов module
и method
тега result
в ответе UMIData (см. «Формат UMI Data»):
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head></head>
<body>
<div class="content">
<xsl:apply-templates select="result" />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="result[@module = 'content'][@method = 'notfound' or @method = 'sitemap']">
... здесь будет карта сайта ...
</xsl:template>
</xsl:stylesheet>
Теперь на этих системных страницах будет отображаться надпись "... здесь будет карта сайта ...".
Укажем место вывода результатов макроса при помощи <xsl:apply-templates>
и подключим макрос при помощи функции document()
:
<xsl:template match="result[@module = 'content'][@method = 'notfound' or @method = 'sitemap']">
<xsl:apply-templates select="document('udata://content/sitemap/')/udata"/>
</xsl:template>
Теперь необходимо создать шаблон для обработки результатов макроса:
<xsl:template match="udata[@module = 'content'][@method = 'sitemap']">
<xsl:apply-templates select="items" mode="sitemap"/>
</xsl:template>
В этом шаблоне мы выбираем элемент items
из ответа макроса так как этот элемент содержит список страниц (элементов item
).
Теперь создадим 2 шаблона, оформляющие список, и отдельный элемент списка:
<xsl:template match="items" mode="sitemap">
<ul>
<xsl:apply-templates select="item" mode="sitemap"/>
</ul>
</xsl:template>
<xsl:template match="item" mode="sitemap">
<li>
<a href="{@link}">
<xsl:value-of select="@name" />
</a>
</li>
</xsl:template>
Первый шаблон с условием соответствия match="items"
выводит элемент <ul>
и указывает где вывести элементы списка при помощи <xsl:apply-templates>
. Второй шаблон match="item"
оформляет отдельный элемент списка, выводя название страницы и ссылку на нее в атрибуте href
тега <a>
.
Однако сейчас эти 2 шаблона обработают только первый уровень карты сайта. Нам же необходимо сделать так, чтобы в ситуации, когда у страницы есть подстраницы, которые также должны попасть на карту сайта, они были вложены в элемент <li>
списком второго уровня:
<xsl:template match="item" mode="sitemap">
<li>
<a href="{@link}">
<xsl:value-of select="@name" />
</a>
</li>
</xsl:template>
Поскольку в таких случаях ответ макроса %content sitemap()% будет содержать внутри элемента item
еще один элемент items
с вложенными элементами item
, то их также можно выбрать и обработать по шаблонам при помощи инстукции <xsl:apply-templates>
:
<xsl:template match="item" mode="sitemap">
<li>
<a href="{@link}">
<xsl:value-of select="@name" />
</a>
<xsl:apply-templates select="items" mode="sitemap"/>
</li>
</xsl:template>
Важно понимать, что сами шаблон, для обработки элемента items
у нас уже есть — это шаблон с условием соответствия match="items". Этот шаблон снова выведет элемент <ul>
и отправит на обработку элементы item
, для которых опять будет задействован шаблон с match="item"
.
Если в этом элементе также есть вложенные подстраницы, будет снова вызван шаблон с условием соответствия match="items", который вызовет шаблон с условием соответствия match="item" и так далее. Таким образом, эти два шаблона обработают XML-дерево ответа макроса и построят списки для любой степени вложенности.
Количество шаблонов можно еще сократить, поскольку мы и так используем режим mode="sitemap"
и можем выбрать элемент items
первого уровня непосредственно в запросе макроса:
<xsl:template match="result[@module = 'content'][@method = 'notfound' or @method = 'sitemap']">
<xsl:apply-templates select="document('udata://content/sitemap/')/udata/items" mode="sitemap"/>
</xsl:template>
Таким образом шаблон с match="udata[@module = 'content'][@method = 'sitemap']"
нам больше не нужен.