Skip to content
Pagination plugin for Textpattern CMS.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



Download | Packagist

This Textpattern plugin creates a paginated navigation bar on listings. It has a wide variety of attributes – so you are able to customise it until you drop! It can be used alone for <txp:article /> and <txp:article_custom /> pagination, but it also has the ability to paginate any list, with a little help from etc_query.

Please report bugs and problems with this plugin at the GitHub project’s issues page.

Note that this plugin creates a list that is meant to be styled by you using CSS.


Using Composer:

$ composer require etc-plugins/etc_pagination:*

Or download the latest version of the plugin from the GitHub project page, paste the code into the Textpattern Plugins administration panel, install and enable the plugin. Visit the forum thread for more info or to report on the success or otherwise of the plugin.


  • Textpattern 4.5.0 or newer.


etc_pagination tag

<txp:etc_pagination />

The etc_pagination tag is a single or a container tag that renders the pagination widget HTML structure.

If used as a container, it must be specified as an opening and closing pair of tags, like this:

    ...contained statements...


  • atts="value"
    Additional attributes to apply to the wraptag attribute value.
  • break="value"
    Where value is an HTML element, specified without brackets (e.g., break="li") to separate list items.
  • class="class name"
    HTML class to apply to the wraptag attribute value.
  • current="text"
    A text active on the current tab.
  • delimiter="value"
    A string to use as delimiter in general,current link pairs, see below. Default: , (a comma).
  • first="text"
    Enables you to alter the text inside the ‘first’ link.
  • gap="text"
    One or two delimiter-separated symbols that state that there are more tabs before or after the ones currently viewable. Default: .
  • html_id="id"
    The HTML id attribute assigned to the wraptag attribute value.
  • last="text"
    Enables you to alter the text inside the ‘last’ link.
  • link="text"
    Enables you to alter the text in the titles of the page tabs. If two delimiter-separated strings are given, then the first one will be used on general pages, and the second one on the current page. Default: {*}, where {*} will be replaced by appropriate tab numbers, see ‘Replacements’ section below.
  • mask="value"
    If set, the whole output will be constructed by replacing the patterns {links}, {first}, {last}, {prev}, {next}, {<+} (gap before) and {+>} (gap after) by corresponding strings. Default: unset.
  • next="text"
    Enables you to alter the text inside the ‘next’ link.
  • offset="number"
    Page number offset. Default: 0.
  • page="number"
    An integer to be considered as default page (typically 1).
  • pages="value"
    The total number of pages, or a range start..end, or a delimiter-separated list of page[::title] items. Not needed when paginating <txp:article /> tag (default value).
  • pgcounter="value"
    The URL parameter to drive the navigation. Not needed when paginating <txp:article /> tag. Default: pg.
  • prev="text"
    Enables you to alter the text inside the ‘previous’ link.
  • query="a&b=c"
    A &-separated list of GET parameters to be unset/modified in root.
  • range="number"
    The maximum number of left/right neighbours (including gaps) to display. If negative (default), all pages will be displayed. The plugin tries to avoid ‘nonsense’ gaps like 1 … 3 4 and adjust the output so that the number of displayed tabs is 2*range+1.
  • reversenumberorder="number"
    Makes it possible to reverse the numbers in the tabs. Setting to value to 0 (default) renders 1,2,3,..., setting value to 1 reverses the link numbers, 2 reverses theirs hrefs, and 3 reverses both numbers and hrefs.
  • root="URL"
    The URL to be used as base for navigation, defaults to the current page URL.
  • scale="1"
    An integer to be used as grid for ‘gap’ links.
  • wraptag="element"
    HTML element to wrap (markup) block, specified without brackets (e.g., wraptag="ul").


If you are not happy with the default <a> links, use <etc_pagination /> as container to construct your own links. The following replacement tokens are available inside etc_pagination:

  • {$}
    The absolute page number.
  • {#}
    The displayed page number.
  • {*}
    The page title.
  • {current}
    The text given by current attribute, enabled only on the current tab.
  • {href}
    The page URL.
  • {link}
    The text given by link attribute, replaced by first, prev, etc when necessary.
  • {pages}
    The total pages number.
  • {rel}
    The page relation (next, prev).

For example, the following (container tag) will generate a <select> pagination list:

<txp:etc_pagination link="Page {*}" current="selected" wraptag="select" atts='name="pg"'>
    <option value="{*}" {current}>{link}</option>


Example 1
<txp:etc_pagination range="2" prev="Previous" next="Next"  wraptag="ul" break="li" />

This example outputs, if there are ten pages and we are on the third one, like so:

        <a href="" rel="prev">Previous</a>
        <a href="">1</a>
        <a href="">2</a>
        <span data-rel="current">3</span>
        <span data-rel="gap">…</span>
        <a href="">10</a>
        <a href="" rel="next">Next</a>

The <a> and <span> tags linking to first, prev, current, next, last, gap pages, will be given the corresponding value of rel or data-rel attributes.

Example 2
<txp:etc_pagination range="0">
    <p>Page {*} of {pages}</p>

This example outputs, if there are eight pages and we are on the sixth one, like so:

<p>Page 6 of 8</p>
Example 3
<txp:etc_pagination wraptag="nav" class="paginator" range="3" atts='aria-label="Blog navigation"'
    prev='<a class="prev" rel="prev" href="{href}" title="Go to previous page" aria-label="Go to previous page">Prev</a>,
          <span class="prev disabled" aria-label="This is the first page">Prev</span>'
    next='<a class="next" rel="next" href="{href}" title="Go to next page" aria-label="Go to next page">Next</a>,
          <span class="next disabled" aria-label="This is the last page">Next</span>'
    link='<li><a href="{href}" title="Go to page {*}" aria-label="Go to page {*}">{*}</a></li>,
          <li class="current"><b title="Current page" aria-label="Current page">{*}</b></li>'
    gap='<li><span title="More pages" aria-label="More pages">…</span></li>'
    <ul class="pagination">

Fully customised HTML solutions can be achieved – this example outputs, if there are eleven pages and we are on the fifth one, like so:

<nav class="paginator" aria-label="Blog navigation">
    <a class="prev" rel="prev" href="" title="Go to previous page" aria-label="Go to previous page">Prev</a>
    <a class="next" rel="next" href="" title="Go to next page" aria-label="Go to next page">Next</a>
    <ul class="pagination">
            <a href="" title="Go to page 1" aria-label="Go to page 1">1</a>
            <span title="More pages" aria-label="More pages">…</span>
            <a href="" title="Go to page 4" aria-label="Go to page 4">4</a>
        <li class="current">
            <b title="Current page" aria-label="Current page">5</b>
            <a href="" title="Go to page 6" aria-label="Go to page 6">6</a>
            <span title="More pages" aria-label="More pages">…</span>
            <a href="" title="Go to page 11" aria-label="Go to page 11">11</a>

etc_numpages tag

<txp:etc_numpages />

The etc_numpages tag is a single helper tag that counts the number of pages in various lists (articles, images, links, …).

This tag is typically used as a pages attribute value, passed to etc_pagination, like this:

<txp:etc_pagination pages='<txp:numpages section="example" />' />


Most attributes come from <txp:article /> and other Textpattern list tags:

  • limit="10"
    The default value of pageby, see below.
  • offset="0"
    The number of items to exclude from the beginning of the list.
  • pageby="number"
    The maximum number of items per page.
  • table="txp_table"
    A name of Textpattern database table from which the list will be extracted. Default: textpattern (articles).
  • total="number"
    An optional list length, if known.
  • author, category, excerpted, exclude, expired, id, include, keywords, month, realname, section, status, time
    These attributes have the same function as in txp:article_custom and other list tags.


Example 1
    <txp:etc_pagination pgcounter="page" pages='<txp:etc_numpages section="news" />' />

This example shows pagination on individual article pages within the news section (i.e., not on an article list context page).

etc_offset tag

<txp:article_custom offset='<txp:etc_offset pgcounter="page" pageby="5" />' limit="5" />

Used as helper tag to calculate the offset of article|image|… listing tags. The example above sets the offset to 15 on a page with ...&page=4 URL, so <txp:article_custom /> will display the fourth page of 5 articles.


  • pageby="10"
    The number of items per page.
  • pgcounter="pg"
    The URL variable to be considered as page number.
  • offset="0"
    An optional page offset.
  • type="value|page|start|end"
    Outputs either the raw (escaped) value of pgcounter, or the calculated page number, or the start page item number, or the end page item number.


Example 1
Showing articles <txp:etc_offset type="start" /> to <txp:etc_offset type="end" />

Outputs Showing articles 21 to 30 on the third page of the standard <txp:article /> list.


Written by Oleg Loukianov and inspired by ob1_pagination. Many thanks to all additional contributors.

You can’t perform that action at this time.