Pull to refresh

Mozart: ссылки Вперед — Назад в списочных материалах

Reading time5 min
Views540
Понадобилось мне в разделе Статьи одного из проектов, что использует в качестве базиса Mozart (mozartframework.ru), реализовать в конце каждой статьи ссылку на следующую и предыдущую. Нет ничего проще, дальше по большей части будет инструкция по использованию XSLT.


Для начала я залез в XML и поправил немножко тот участок, который отвечает за вывод списка уроков и параллельно за полный вывод информации об одном уроке.

Copy Source | Copy HTML<br/><!-- Если lesson_id НЕ подается в УРЛ --><br/> <br/><newt:include match="query[lesson_id/@value='' or not(lesson_id)]"><br/>   <newt:base id="lessons-list" add-query="lessons-list" query-filter="lesson_id"><br/>     <request><br/>         <get limit="20" object="lesson" sort="sort"><br/>           <info attr="shortdescription"/><br/>         </get><br/>     </request><br/>   </newt:base><br/></newt:include><br/> <br/><!-- Если lesson_id подается в УРЛ --><br/> <br/><newt:include match="query[lesson_id/@value!='']"><br/>   <newt:base id="lessons-list" add-query="lessons-list" query-filter="lesson_id"><br/>     <request><br/>         <get limit="20" object="lesson" sort="sort"><br/>           <info attr="description"/><br/>         </get><br/>     </request><br/>   </newt:base><br/></newt:include> <br/>


Get'ом выбираем уроки в кол-ве не более 20 и дополнительно выбираем через Info полный текст. Больше 20 нам пока не понадобится. Я лишь для наглядности привел такую реализацию выборки данных для списка и полного вывода через newt:include, чтобы было более понятно (на самом деле способов сделать это множество). По тексту ясно, что один участок для списка, а второй — для полного текста. В реальной системе все несколько лаконичней описано.

Теперь самая главная фишка — это разворачиваемость объектов. Она нам тут поможет тем, что не заставит нас совершать какие-то сложные действия для того, чтобы выбрать предыдущий и следующий уроки. Когда мы используем get и не указываем дополнительных ограничений по id (именно id), то мы можем использовать понятие разворачиваемости вот каким образом. Если в query (в данном случае в виде параметра через УРЛ) мы подаем параметр lesson_id, и этот параметр пропускаем до нашего newt:base и инструкции get, инструкция эта ведет себя особенным образом: разворачивается (т.е. выбираются полные даные по объекту и все его вложенные инструкции типа info и т.п.) только тот объект, чей id совпадает с переданными нами. Остальные объекты будут просто идти в виде краткой записи в XML до и после развернутого.

Т.е. на выходе в случае наличия lesson_id=85 мы получим:
Copy Source | Copy HTML<br/><base id="lessons-list" add-query="lessons-list" ... ><br/>  <lesson id="83" query="&lesson_id=83" title="Урок 1: Создание новой страницы"/><br/>  <lesson id="84" query="&lesson_id=84" title="Урок 2: Навигация по сайту"/><br/>  <lesson id="85" query="&lesson_id=85" title="Урок 3: Работа с БД"><br/>    <description><br/>      ...<br/>    </description><br/>  </lesson><br/>  <lesson id="86" query="&lesson_id=86" title="Урок 4: Создание раздела Новости"/><br/>  <lesson id="87" query="&lesson_id=87" title="Урок 5: Репликация"/><br/>  <lesson id="88" query="&lesson_id=88" title="Урок 6: Работа с формами"/><br/></base> <br/>


Далее нам осталось только правильно обработать данный XML в XSLT трансформе, а это просто. Под текстом урока ставим вызов нужного созданного нами позже темплейта:
Copy Source | Copy HTML<br/><xsl:template match="lesson[description]"><br/>  ...<br/>  ...<br/>  <xsl:apply-templates select="." mode="pagelisting"/><br/></xsl:template><br/> <br/><xsl:template match="lesson[description]" mode="pagelisting"><br/>  <p style="text-align: center;"><br/>    <xsl:if test="preceding-sibling::lesson[1]"><br/>      <a href="/docs.xml?lesson_id={preceding-sibling::lesson[1]/@id}"><xsl:value-of select="preceding-sibling::lesson[1]/@title"/></a><br/>    </xsl:if><br/>    <xsl:if test="preceding-sibling::lesson[1] and following-sibling::lesson[1]"> | </xsl:if><br/>    <xsl:if test="following-sibling::lesson[1]"><br/>      <a href="/docs.xml?lesson_id={following-sibling::lesson[1]/@id}"><xsl:value-of select="following-sibling::lesson[1]/@title"/></a> <br/>    </xsl:if><br/>  </p><br/></xsl:template> <br/>


В самом темплейте мы используем оси (preceding-sibling и following-sibling) а так же через указания номера элемента ([1]) указываем, какой именно нам нужен, ведь мы хотим поставил ссылку только на один элемент вперед и один элемент назад. Это чистый XSLT и никаких приблуд от Mozart тут нет.
Tags:
Hubs:
Rating0
Comments0

Articles