📜 ⬆️ ⬇️

Mozart: Links Forward - Back In List Materials

It took me in the Articles section of one of the projects that uses Mozart (mozartframework.ru) as the basis to implement a link to the next and previous one at the end of each article. There is nothing easier, then for the most part there will be instructions on how to use XSLT.


For a start, I climbed into XML and corrected a little bit the area that is responsible for displaying the list of lessons and in parallel for the complete output of information about one lesson.

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'om choose lessons in a number of no more than 20 and optionally select the full text through Info. More than 20 we will not need. For clarity, I cited such an implementation of the data selection for the list and the full output through newt: include, so that it is more understandable (in fact, there are ways to do this). In the text it is clear that one site for the list, and the second - for the full text. In a real system, everything is somewhat more concisely described.

Now the most important feature is the deployment of objects. She will help us here by not forcing us to perform some difficult actions in order to choose the previous and next lessons. When we use get and do not specify additional restrictions on id (id), then we can use the concept of deployability in this way. If in query (in this case, in the form of a parameter through an URL), we give the lesson_id parameter, and skip this parameter to our newt: base and get instructions, this instruction behaves in a special way: it unfolds (i.e. the full data on the object is selected and all of its nested instructions such as info, etc.) only the object whose id matches the ones we passed. The rest of the objects will simply go as a brief entry in XML before and after being expanded.

Those. at the output in the case of lesson_id = 85 we get:
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/>


Then we just need to correctly handle the given XML in the XSLT transform, and this is simple. Under the text of the lesson we place a call on the template we created later:
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/>


In the template itself, we use axes (preceding-sibling and following-sibling) as well as specifying the element number ([1]) and specifying which one we need, because we want to link only one element forward and one element back. This is pure XSLT and there is no Mozart priblud here.

Source: https://habr.com/ru/post/89262/


All Articles