Textpattern tips, tutorials and code snippets

Customizable Google style navigation

Our mission will be to create a Google-like pagination for front-page articles, with Prev/Next and/or Last/First links, like this:

Prev 1 ... 5 6 7 8 9 ... 99 Next

ob1_pagination plugin

There is, of course, the wonderful ob1_pagination plugin, but it does not preserve url parameters, see this tip. On the other hand, our solution will be much more customizable, since we will construct it “from scratch”.

Get the tools for the job

Our tools are etc_url and etc_query plugins. The first one is tiny and serves only to modify some parameters (pg in our case) of url whilst preserving the other ones.

<txp:variable name="url" value='<txp:etc_url query="pg" queue="1" />' />

will store the current page url with pg parameter stripped in the variable url. Additionally, ? or & will be appended to the url, so we will be able to add a new parameter to it.

Let etc_query do its work

The rest of the job is done by etc_query. Digging the TXP code, we find that the current page and the total number of pages produced by <txp:article /> tag, are stored in global $thispage['pg'] and $thispage['numPages'] variables. We now can easily create a list of all page links (with etc_query or rah_repeat, if you prefer):

<txp:etc_query data="[1..{?numPages|1}]" markup="json" globals="variable,thispage">
<a href="{?url}pg={#row}">{#row}</a>
</txp:etc_query>

Now we pass this list as data to another etc_query tag, instructing it to find the current page link by pg url parameter and display its neighbors, and other stuff. We will also change the values of the previous and next links to Prev/Next, and fill the “gaps” with ....

The final solution is..

<txp:variable name="url" value='<txp:etc_url query="pg" queue="1" />' />

<txp:etc_query
 data='<txp:etc_query
   data="[1..{?numPages|1}]"
   markup="json"
   globals="variable,thispage">
   <a href="{?url}pg={#row}">{#row}</a>
 </txp:etc_query>'
 query="a[{?pg|1}]"
 globals="thispage">

 <txp:variable name="navlinks">
   {preceding-sibling::a[position()<3]}
   <b>{?}</b>
   {following-sibling::a[position()<3]}
 </txp:variable>
 {preceding-sibling::a[1]=Prev}
 {preceding-sibling::a[position()>=3 and position()=last()]}
 $[?|{preceding-sibling::a[position()>=3 and position()=last()-1]?}|...|]$
 <txp:variable name="navlinks" />
 $[?|{following-sibling::a[position()>=3 and position()=last()-1]?}|...|]$
 {following-sibling::a[position()>=3 and position()=last()]}
 {following-sibling::a[1]=Next}
</txp:etc_query>

You can now rename or (re)move the current/next/prev/first/last links or gaps, mix them with other stuff and style it all as you like. Do not expect it to be as fast as a dedicated plugin, but you get much flexibility for less than 0.005s.

4 Comments Comment feed

  • etc
  • 12 June 2012

Somehow the closing > of <txp:etc_query ... (after globals) have been replaced by empty lines, sorry. And the values of hrefs in <a> should be in quotes, of course.

@etc – try it now and see if it is ok…thanks for spotting the typos..

  • etc
  • 12 June 2012

Jonathan: now it should be fine, thanks, just remove the empty lines inside etc_query.

@etc – removed the extra line. Should be ok now..

Add a comment

Use Textile help to style your comments