Textpattern tips, tutorials and code snippets

Navigate articles by custom field

A recurrent question on the TXP forum is “How to navigate articles following some list”. For example, if you have a custom field “album” in your songs articles, you may want to display a “link_to_next song” in this album on the current song page.

The logical idea to put <txp:link_to_next><txp:next_title /></txp:link_to_next> in the article form will not work (as desired), since “next” means “next by posting date” for these tags.

First attempt, with random success

You can try to cheat (with random success):

<txp:article_custom id='<txp:article_id />' album='<txp:custom_field name="album" />'>
 <txp:link_to_next><txp:next_title /></txp:link_to_next>
</txp:article_custom>

But the idea is natural: guide the navigation by some custom list. If we look at the output of:

<txp:article_custom limit="100" album='<txp:custom_field name="album" />'>
 <a href='<txp:permlink />'><txp:title /></a>
</txp:article_custom>

we will see something like:

<a href="...?id=1">Dinah</a>...<a href="...?id=8[current]">Tears</a><a href="...?id=9[next]">St Louis Blues</a>...<a href="...?id=25">Lover Man</a>

Using XPath to associate your article with a next/current article

So, how to pick the [next] to [current] link from this list? That’s where the XPath magic comes in handy.

Basically, Xpath associates some (self-explanatory) “path” with any node of a XML document (link list in our case). It also allows to find a node by its path/attributes. For example, to match the [current] link, we could query the list for

a[@href='<txp:permlink />']

and the next one will be:

a[@href='<txp:permlink />']/following-sibling::a[position()=1]

Integrate XPath queries with the etc_query plugin

All we have to do now is to integrate XPath queries into TXP with etc_query plugin. Feed the plugin with data (link list) and tell it what you want to extract. This is as easy as

<txp:etc_query
 data='<txp:article_custom limit="100" album=''<txp:custom_field name="album" />''>
   <a href=''<txp:permlink />''><txp:title /></a>
 </txp:article_custom>'
 query='a[@href=''<txp:permlink />'']/following-sibling::a[position()=1]'
 specials="" 
/>

It will output <a href="...?id=9">St Louis Blues</a> to our common delight.

2 Comments Comment feed

  • Edward
  • 7 November 2012

Thanks for this!

Going a little further, I am using this as my main navigation, so how would I set the class to “active” ?

Something along these lines i guess :

<txp:article_custom limit="8" wraptag="ul" break=""> <li<some_if_statement> class="active"</end_if_statement>><a href='<txp:permlink />'><txp:title /></a></li> </txp:article_custom>

But I am struggling to find the right if statement…

Any ideas?

  • etc
  • 9 November 2012

Hi Edward,

if I get it right, you want to make “active” the current article class? You could do it like this:

<txp:etc_query wraptag="ul"
 data='<txp:article_custom limit="100" album=''<txp:custom_field name="album" />''>
   <a href=''<txp:permlink />''><txp:title /></a>
 </txp:article_custom>'
 query='a[@href=''<txp:permlink />'']'>
    <li>{preceding-sibling::a[1]}</li>
    <li class="active">{.}</li>
    <li>{following-sibling::a[1]}</li>
</txp:etc_query>

This will output something like

<ul>
<li><a href="...">[previous]</a></li>
<li class="active"><a href="...">[current]</a></li>
<li><a href="...">[next]</a></li>
</ul>

Add a comment

Use Textile help to style your comments