Mixed glossary index

5 April 2016

Keywords: merge, sort, xml

We have already seen how to mix and reorder two (or more) lists via XSL transforms. Now we exploit the same idea, but our list will be a mix of article fields. The original question is here :

We’re working on a glossary project at CSF. Each term in the glossary will be it’s own Txp article. However, we need a slightly more robust index for navigation purposes than just making lists of the article titles. … Some main entry terms have synonymous terms (…) that won’t have their own articles, but need to be used in the index somehow as user redirection cues to the associated main definitions.

One idea I’ve been stewing over is to use custom fields in the actual definition articles to list any associated synonymous terms …

And we really want this to be as hack-free as possible; i.e.., no blank articles for the sake of making lists, if it can be avoided. But maybe not?

Although this is the most straightforward solution, I agree that blank articles look weird. Not very easily, but it can be avoided, let us see how.

Following the author’s idea, we store comma-separated synonymous terms in some article field. For this demo, I have chosen Keywords because they are already populated, but you could use a custom field, say synonyms.

The first step will be to create a structured list of all terms (“main” and “synonyms”). We retrieve it directly from the database and store in <txp:variable name="terms" />:

<txp:etc_query name="terms" markup="db" data="Section='tips'" populate="article" wraptag="ul">
	<li data-title="{!title||strtolower}">
		<txp:permlink><txp:title /></txp:permlink>
	</li>
	<txp:etc_query data="{{?synonyms}}" markup="list">
		<li data-title="{{$strtolower}}">
			{{?}} (see <txp:permlink><txp:title /></txp:permlink>)
		</li>
	</txp:etc_query>
</txp:etc_query>

Now we reorder the li items of this list by their data-title attribute:

<txp:etc_query data='<txp:variable name="terms" />'>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" />
<xsl:template match="ul">
	<ul>
	<xsl:for-each select="li">
		<xsl:sort select="@data-title" order="ascending" />
		<xsl:copy-of select="." />
	</xsl:for-each>
	</ul>
</xsl:template>
</xsl:stylesheet>
</txp:etc_query>

And voilà! Some terms (i.e. keywords) in my list can have multiple entries, because articles share them:

File(s)