Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2020-01-30 01:42:17

michaelkpate
Moderator
From: Avon Park, FL
Registered: 2004-02-24
Posts: 1,258
Website

Complex Pagination using Newer/Older with Shift

Having seen the power of the new shift attribute, I kind of got carried away. Hopefully, someone besides me finds this useful.

This version requires no plugins.

Note: This is version 7 – and is designed to work with the default Textpattern template. You will definitely need to make at least slight modifications to get it to work with another.

Credits: Very much based on ideas from etc and Pat64 and etc and philwareham and Pat64. I furthered the design from this article Pagination Design Examples and Best Practices and paging through Wordpress Tavern and seeing how the pagination changes depending on which page you are on.

Demo: You can visit Pagination Demo to see it in action. You’ll notice that the boxes change color as you hover over them – but the separator and current page are white to indicate they aren’t clickable.

pagination

<txp:pages pg="pg" evaluate="5,2,8,4,6">
    <nav aria-label="Blog navigation">
      <ul class="list-inline pagination">
        <txp:newer shift="1" break="li" showalways><span aria-label="Go to previous page">Previous</span></txp:newer>
        <txp:newer shift break="li"><span aria-label="Go to first page"><txp:yield item="page" /></span></txp:newer>
        <txp:evaluate test="newer"><li class="separator"><txp:newer shift="-2" link="" break=""><span role="separator" aria-label="More pages">...</span></txp:newer></li></txp:evaluate>
        <txp:newer shift="1" break="li"><span aria-label="Go to page <txp:yield item="page" />"><txp:yield item="page" /></span></txp:newer>
        <li class="active"><txp:newer shift="0" link=""><span aria-current="page"><txp:yield item="page" /></span></txp:newer></li>
        <txp:older shift="1" break="li"><span aria-label="Go to page <txp:yield item="page" />"><txp:yield item="page" /></span></txp:older>
        <txp:evaluate test="older"><li class="separator"><txp:older shift="-2" link="" break=""><span role="separator" aria-label="More pages">...</span></txp:older></li></txp:evaluate>
        <txp:older shift break="li"><span aria-label="Go to last page"><txp:yield item="page" /></span></txp:older>
        <txp:older shift="1" break="li" showalways><span aria-label="Go to next page">Next</span></txp:older>
      </ul>
    </nav>
</txp:pages>

style pagination

.pagination {
/* Fallback */
display:table;
margin:0 auto;
/* Modern Browsers */
display:flex;
flex-direction:row;
align-items:center;
justify-content:center
}
.pagination li{
display:block;
min-width:2.5em;
background-color:inherit;
color:#000000;
text-align:center;
font:normal 300 normal 1em/1.25 Arial,sans-serif
border-bottom: 1px solid #cccccc;
background-color: #eeeeee;
}

.pagination li:hover {
    background-color: #f8f8f8;
}
.pagination li.active {
    background-color:inherit;
}
.pagination li.separator {
    background-color:inherit;
}
.pagination a {
    color: #333333;
    text-decoration: none;
}
.pagination a:hover, .pagination a:visited {
    color: #333333;
    text-decoration: none;
}

.pagination span{cursor:not-allowed}
.pagination a, .pagination span{display:block}
.pagination li a span{cursor:pointer}
.pagination span{padding: .5em .75em;border:1px solid #dee2e6}
.pagination span[aria-label="current page"]{cursor:default}

@media screen and (max-width: 38em) {

    .pagination {display:table;width:5em}
    .pagination li{display:block;width:100%}

}

Explanation: It all depends on the execution order and the showalways statements.

For example, assume that we are on Page 4 – the pagination will look this on the example blog:

Previous 1 … 3 4 5 … 28 Next

<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to previous page">Previous</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/"><span aria-label="Go to first page">1</span></a></li>
<li class="separator"><span role="separator" aria-label="More pages">...</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to page 3">3</span></a></li>
<li class="active"><span aria-current="page">4</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=5"><span aria-label="Go to page 5">5</span></a></li>
<li class="separator"><span role="separator" aria-label="More pages">...</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=28"><span aria-label="Go to last page">28</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=5"><span aria-label="Go to next page">Next</span></a></li>

Let’s step through the code above. Evaluate says that we should process the lines in the following order “5,2,8,4,6” so let’s do that

<li class="active"><txp:newer shift="0" link=""><span aria-current="page"><txp:yield item="page" /></span></txp:newer></li>

will always output whatever page you are are currently on, so in this case:

<li class="active"><span aria-current="page">4</span></li>

Now line 2

<txp:newer shift break="li"><span aria-label="Go to first page"><txp:yield item="page" /></span></txp:newer>

This one will always output the first page like so:

<li><a href="https://paginationdemo.cmsstyles.com/"><span aria-label="Go to first page">1</span></a></li>

except when you are on the first page. In that case, it has already been used and the line will be blank. Line 8 is next.

<txp:older shift break="li"><span aria-label="Go to last page"><txp:yield item="page" /></span></txp:older>

This is always going to output the last line, 28 in this example, except when you are on page 28, when it will be blank.

<li><a href="https://paginationdemo.cmsstyles.com/?pg=28"><span aria-label="Go to last page">28</span></a></li>

Now line 4

<txp:newer shift="1" break="li"><span aria-label="Go to page <txp:yield item="page" />"><txp:yield item="page" /></span></txp:newer>

shift=“1” means that it will output the page one before the current page – but again, this will be blank if you are on the first page.

<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to page 3">3</span></a></li>

Now Line 6

<txp:older shift="1" break="li"><span aria-label="Go to page <txp:yield item="page" />"><txp:yield item="page" /></span></txp:older>

This will give put the page after the current page – if it is needed.

<li><a href="https://paginationdemo.cmsstyles.com/?pg=5"><span aria-label="Go to page 5">5</span></a></li>

Okay, so now we are done with the out-of-order section. Which means next up is Line 1.

<txp:newer shift="1" break="li" showalways><span aria-label="Go to previous page">Previous</span></txp:newer>

This takes you to the Previous Page – just like Line 4 did. But just like Line 4, it won’t show up if you are on Page 1.

<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to previous page">Previous</span></a></li>

Now Line 3.

<txp:evaluate test="newer"><li class="separator"><txp:newer shift="-2" link="" break=""><span role="separator" aria-label="More pages">...</span></txp:newer></li></txp:evaluate>

We only want this line to show up if we are on Page 3 or higher. But because we can’t add a class to txp:newer and txp:older, the <li> tag has to be hard-coded in advance. But we don’t want this to be output:

<li class="separator"></li>

so wrapping it inside another evaluate means that it only shows up if needed.

<li class="separator"><span role="separator" aria-label="More pages">...</span></li>

7 is the reverse of 3.

<txp:evaluate test="older"><li class="separator"><txp:older shift="-2" link="" break=""><span role="separator" aria-label="More pages">...</span></txp:older></li></txp:evaluate>

and 9 is the reverse of 1.

<li><a href="https://paginationdemo.cmsstyles.com/?pg=5"><span aria-label="Go to next page">Next</span></a></li>

Basically, every page from 4 to 25 will output all 9 lines. But on Page 1 you only get:

<li class="active"><span aria-current="page">1</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=2"><span aria-label="Go to page 2">2</span></a></li>
<li class="separator"><span role="separator" aria-label="More pages">...</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=28"><span aria-label="Go to last page">28</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=2"><span aria-label="Go to next page">Next</span></a></li>

Because 1 was the first page, 5 executes first but then 2, 4, 1, and 3 all had no output. On Page 2:

<li><a href="https://paginationdemo.cmsstyles.com/?pg=1"><span aria-label="Go to previous page">Previous</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/"><span aria-label="Go to first page">1</span></a></li>
<li class="active"><span aria-current="page">2</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to page 3">3</span></a></li>
<li class="separator"><span role="separator" aria-label="More pages">...</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=28"><span aria-label="Go to last page">28</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=3"><span aria-label="Go to next page">Next</span></a></li> 

5 worked. Then Lines 2 and 8. 4 was blank but 6 output. Then Line 1. 3 was blank. 7 and 9 both had output. And finally, on Page 3 we get:

<li><a href="https://paginationdemo.cmsstyles.com/?pg=2"><span aria-label="Go to previous page">Previous</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/"><span aria-label="Go to first page">1</span></a></li>    
<li><a href="https://paginationdemo.cmsstyles.com/?pg=2"><span aria-label="Go to page 2">2</span></a></li>
<li class="active"><span aria-current="page">3</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=4"><span aria-label="Go to page 4">4</span></a></li>
<li class="separator"><span role="separator" aria-label="More pages">...</span></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=28"><span aria-label="Go to last page">28</span></a></li>
<li><a href="https://paginationdemo.cmsstyles.com/?pg=4"><span aria-label="Go to next page">Next</span></a></li>

Every line output something but 3. The reverse of Pages 1-3 will be Pages 26-28.

I hope this helps.

Feedback is welcome.

Offline

#2 2020-01-30 17:03:14

towndock
Member
From: Oriental, NC USA
Registered: 2007-04-06
Posts: 284
Website

Re: Complex Pagination using Newer/Older with Shift

I’d love to see what this looks like being used on the public side. Can you link to a page where the above code is being used?

Offline

#3 2020-01-30 18:06:37

michaelkpate
Moderator
From: Avon Park, FL
Registered: 2004-02-24
Posts: 1,258
Website

Re: Complex Pagination using Newer/Older with Shift

towndock wrote #321434:

I’d love to see what this looks like being used on the public side. Can you link to a page where the above code is being used?

Sort of – I have it running at Pate Technologies but, of course, it changes depending on what I how I set <txp:article limit=“5” />.

I guess I need to whip up some demo sites.

Offline

#4 2020-01-31 12:38:30

etc
Developer
Registered: 2010-11-11
Posts: 3,580
Website

Re: Complex Pagination using Newer/Older with Shift

That’s creative! You might want to play with new <txp:pages /> tag too:

<txp:variable name="pages">
    <txp:pages total shift="3">
        <txp:yield item="page" />
    </txp:pages>
</txp:variable>

<nav>
    <txp:newer showalways>&laquo;</txp:newer>
    <txp:newer shift showalways>First</txp:newer>
    <txp:newer shift="-2" link="">...</txp:newer>
    <txp:variable name="pages" />
    <txp:older shift="-2" link="">...</txp:older>
    <txp:older shift showalways>Last</txp:older>
    <txp:older showalways>&raquo;</txp:older>
</nav>

Offline

#5 2020-01-31 12:55:38

colak
Admin
From: Cyprus
Registered: 2004-11-20
Posts: 7,776
Website

Re: Complex Pagination using Newer/Older with Shift

etc wrote #321448:

That’s creative! You might want to play with new <txp:pages /> tag too…

I saw the pages part of the tag in your example but it is still undocumented:) What is the expected output of <txp:pages /> and what attributes does it have? Can it be used by itself?


Yiannis
——————————
neme.org | hblack.net | LABS | State Machines | NeMe @ github | Covid-19; a resource
I do my best editing after I click on the submit button.

Offline

#6 2020-01-31 14:16:59

etc
Developer
Registered: 2010-11-11
Posts: 3,580
Website

Re: Complex Pagination using Newer/Older with Shift

colak wrote #321449:

I saw the pages part of the tag in your example but it is still undocumented:) What is the expected output of <txp:pages /> and what attributes does it have? Can it be used by itself?

It is from the same family that newer/older and works alike, but can produce both newer an older links. For example,

<txp:pages shift="-2,-1,0,1,2" />

outputs links to n-2,n-1,n,n+1,n+2 pages. Another nifty feature is e.g. that

<txp:pages total shift="2" />

will adapt itself to output 5 links even when n is close to the extremities: n-3,n-2,n-1,n,n+1 (last).

But its main purpose is to be able to set pagination parameters: the total number of pages and page URL variable. For example,

<txp:pages total="20" pg="page" />

will not display anything, but consecutive calls to newer/older/pages will output ?page=n links for n between 1 and 20. This is useful for creating pagination bars for custom articles and so on.

Offline

#7 2020-01-31 15:50:23

michaelkpate
Moderator
From: Avon Park, FL
Registered: 2004-02-24
Posts: 1,258
Website

Re: Complex Pagination using Newer/Older with Shift

I made some updates to the original post above and added a demo.

Offline

#8 2020-02-01 12:06:12

etc
Developer
Registered: 2010-11-11
Posts: 3,580
Website

Re: Complex Pagination using Newer/Older with Shift

Thanks for sharing. This will not interfere with links ‘shown’ state:

<txp:variable name="currentpage" value='<txp:page_url type="pg" />' />
<txp:variable name="lastpage" value='<txp:pages total />' />

And smd_if can be replaced with

<txp:if_variable name="currentpage" value="^([5-9]|\d\d)" match="pattern" />

Offline

#9 2020-02-01 16:26:32

michaelkpate
Moderator
From: Avon Park, FL
Registered: 2004-02-24
Posts: 1,258
Website

Re: Complex Pagination using Newer/Older with Shift

This works

<txp:if_variable name="currentpage" value="^([5-9]|\d\d)" match="pattern" />
    <txp:output_form form="pagination-master" />

This does not

<txp:if_variable name="currentpage" value="^([5-9]|\d\d)" match="pattern" >
    <txp:output_form form="pagination-master" />
</txp:if_variable>

That isn’t what I expected.

Offline

#10 2020-02-01 16:37:25

etc
Developer
Registered: 2010-11-11
Posts: 3,580
Website

Re: Complex Pagination using Newer/Older with Shift

value="^[5-9]|\d\d" is a regex meaning ‘value starts with 5, 6, 7, 8, 9 or has at least two digits’. To check for value > 5 it will be value="^[6-9]|\d\d". You can test regex here and there.

Offline

Board footer

Powered by FluxBB