Skip to content

Commit

Permalink
Adding support for pagination trails, fix for #10
Browse files Browse the repository at this point in the history
  • Loading branch information
sverrirs committed Jan 29, 2017
1 parent 6cfdf42 commit da74c50
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 6 deletions.
62 changes: 62 additions & 0 deletions README-GENERATOR.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The **Generator** forms the core of the pagination logic. It is responsible for
* [How to paginate on combination of filters](#paginate-on-combination-of-filters)
* [Overriding site configuration](#configuration-overrides)
* [Advanced Sorting](#advanced-sorting)
* [Creating Pagination Trails](#creating-pagination-trails)
* [How to detect auto-generated pages](#detecting-generated-pagination-pages)
* [Formatting page titles](#formatting-page-titles)
* [Common issues](#common-issues)
Expand Down Expand Up @@ -79,6 +80,14 @@ pagination:
# in reality this can be any value, suggested are the Microsoft locale-codes (e.g. en_US, en_GB) or simply the ISO-639 language code )
locale: ''

# Optional,omit or set both before and after to zero to disable.
# Controls how the pagination trail for the paginated pages look like.
# this feature enables the user to display a <prev, 1, 2, 3, 4, 5, next> pagination trail on their page
# By default this feature produces two pages before and two pages after the current page (total of 5 pages)
trail:
before: 2
after: 2

############################################################
```

Expand Down Expand Up @@ -356,6 +365,59 @@ pagination:
---
```

## Creating Pagination Trails

<p align="center">
<img src="https://raw.githubusercontent.com/sverrirs/jekyll-paginate-v2/master/res/pagination-trails.png" width="59" />
</p>

Creating a trail structure for your pagination as shown above can be achieved by enabling the `trail` configuration and including a little extra code in your liquid templates.

``` yml
pagination:
trail:
before: 2 # The number of links before the current page
after: 2 # The number of links after the current page
```

Your layout file would then have to include code similar to the following to generate the correct HTML structure

``` HTML
{% if paginator.page_trail %}
{% for trail in paginator.page_trail %}
<li {% if page.url == trail.path %}class="selected"{% endif %}>
<a href="{{ trail.path | prepend: site.baseurl }}" title="{{trail.title}}">{{ trail.num }}</a>
</li>
{% endfor %}
{% endif %}
```
_See [example 3](https://github.com/sverrirs/jekyll-paginate-v2/tree/master/examples/03-tags) for a demo of a pagination trail_

The `trail` value exposes three properties:
* `num`: The number of the page
* `path`: The path to the page
* `title`: The title of the page

The algorithm will always attempt to keep the same trail length for all pages (`trail length = before + after + 1`).
Example when on page 4 the trail for the configuration above would look like this

<p align="center">
<img src="https://raw.githubusercontent.com/sverrirs/jekyll-paginate-v2/master/res/pagination-trails-p4.png" />
</p>

Different number of before and after trail links can be specified. Below is an example of how this yml config would look like when on the same page 4

``` yml
pagination:
trail:
before: 1
after: 3
```

<p align="center">
<img src="https://raw.githubusercontent.com/sverrirs/jekyll-paginate-v2/master/res/pagination-trails-p4-b1a3.png" />
</p>

## Detecting generated pagination pages

To identify the auto-generated pages that are created by the pagination logic when iterating through collections such as `site.pages` the `page.autogen` variable can be used like so
Expand Down
5 changes: 4 additions & 1 deletion examples/03-tags/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ pagination:
title: ':title | :num of :max'
limit: 0
sort_field: 'date'
sort_reverse: true
sort_reverse: true
trail:
before: 2
after: 2
13 changes: 13 additions & 0 deletions examples/03-tags/_layouts/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<style>
ul.pager { text-align: center; list-style: none; }
ul.pager li {display: inline;border: 1px solid black; padding: 10px; margin: 5px;}
.selected{ background-color: magenta; }
</style>

<div class="home">
Expand Down Expand Up @@ -32,12 +33,24 @@ <h2>
Showing buttons to move to the next and to the previous list of posts (pager buttons).
-->
{% if paginator.total_pages > 1 %}
{{page.url}}<br>
{{page.path}}<br>

<ul class="pager">
{% if paginator.previous_page %}
<li class="previous">
<a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">&larr; Newer Posts</a>
</li>
{% endif %}

{% if paginator.page_trail %}
{% for trail in paginator.page_trail %}
<li {% if page.url == trail.path %}class="selected"{% endif %}>
<a href="{{ trail.path | prepend: site.baseurl | replace: '//', '/' }}" title="{{trail.title}}">{{ trail.num }}</a>
</li>
{% endfor %}
{% endif %}

{% if paginator.next_page %}
<li class="next">
<a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Older Posts &rarr;</a>
Expand Down
4 changes: 4 additions & 0 deletions lib/jekyll-paginate-v2/generator/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ module PaginateV2::Generator
'sort_reverse' => false,
'sort_field' => 'date',
'limit' => 0, # Limit how many content objects to paginate (default: 0, means all)
'trail' => {
'before' => 0, # Limits how many links to show before the current page in the pagination trail (0, means off, default: 0)
'after' => 0, # Limits how many links to show after the current page in the pagination trail (0 means off, default: 0)
},
'debug' => false, # Turns on debug output for the gem
'legacy' => false # Internal value, do not use (will be removed after 2018-01-01)
}
Expand Down
36 changes: 35 additions & 1 deletion lib/jekyll-paginate-v2/generator/paginationModel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories,
#### BEFORE STARTING REMOVE THE TEMPLATE PAGE FROM THE SITE LIST!
@page_remove_lambda.call( template )

# list of all newly created pages
newpages = []

# Now for each pagination page create it and configure the ranges for the collection
# This .pager member is a built in thing in Jekyll and defines the paginator implementation
# Simpy override to use mine
Expand Down Expand Up @@ -284,7 +287,38 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories,

# Add the page to the site
@page_add_lambda.call( newpage )
end

# Store the page in an internal list for later referencing if we need to generate a pagination number path later on
newpages << newpage
end #each.do total_pages

# Now generate the pagination number path, e.g. so that the users can have a prev 1 2 3 4 5 next structure on their page
# simplest is to include all of the links to the pages preceeding the current one
# (e.g for page 1 you get the list 2, 3, 4.... and for page 2 you get the list 3,4,5...)
if( config['trail'] && !config['trail'].nil? && newpages.size.to_i > 1 )
trail_before = [config['trail']['before'].to_i, 0].max
trail_after = [config['trail']['after'].to_i, 0].max
trail_length = trail_before + trail_after + 1

if( trail_before > 0 || trail_after > 0 )
newpages.select do | npage |
idx_start = [ npage.pager.page - trail_before - 1, 0].max # Selecting the beginning of the trail
idx_end = [idx_start + trail_length, newpages.size.to_i].min # Selecting the end of the trail

# Always attempt to maintain the max total of <trail_length> pages in the trail (it will look better if the trail doesn't shrink)
if( idx_end - idx_start < trail_length )
# Attempt to pad the beginning if we have enough pages
idx_start = [idx_start - ( trail_length - (idx_end - idx_start) ), 0].max # Never go beyond the zero index
end

# Convert the newpages array into a two dimensional array that has [index, page_url] as items
#puts( "Trail created for page #{npage.pager.page} (idx_start:#{idx_start} idx_end:#{idx_end})")
npage.pager.page_trail = newpages[idx_start...idx_end].each_with_index.map {|ipage,idx| PageTrail.new(idx_start+idx+1, ipage.pager.page_path, ipage.data['title'])}
#puts( npage.pager.page_trail )
end #newpages.select
end #if trail_before / trail_after
end # if config['trail']

end # function paginate

end # class PaginationV2
Expand Down
33 changes: 31 additions & 2 deletions lib/jekyll-paginate-v2/generator/paginator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ module PaginateV2::Generator
#
class Paginator
attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
:previous_page, :previous_page_path, :next_page, :next_page_path, :page_path
:previous_page, :previous_page_path, :next_page, :next_page_path, :page_path, :page_trail

def page_trail
@page_trail
end

def page_trail=(page_array)
@page_trail = page_array
end

# Initialize a new Paginator.
#
Expand Down Expand Up @@ -45,11 +53,32 @@ def to_liquid
'previous_page' => previous_page,
'previous_page_path' => previous_page_path,
'next_page' => next_page,
'next_page_path' => next_page_path
'next_page_path' => next_page_path,
'page_trail' => page_trail
}
end

end # class Paginator

# Small utility class that handles individual pagination trails
# and makes them easier to work with in Liquid
class PageTrail
attr_reader :num, :path, :title

def initialize( num, path, title )
@num = num
@path = path
@title = title
end #func initialize

def to_liquid
{
'num' => num,
'path' => path+"index.html",
'title' => title
}
end
end #class PageTrail

end # module PaginateV2
end # module Jekyll
4 changes: 2 additions & 2 deletions lib/jekyll-paginate-v2/version.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module Jekyll
module PaginateV2
VERSION = "1.6.1"
VERSION = "1.7.0"
# When modifying remember to issue a new tag command in git before committing, then push the new tag
# git tag -a v1.6.1 -m "Gem v1.6.1"
# git tag -a v1.7.0 -m "Gem v1.7.0"
# git push origin --tags
end # module PaginateV2
end # module Jekyll
Binary file added res/pagination-trails-p3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/pagination-trails-p4-b1a3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/pagination-trails-p4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added res/pagination-trails.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit da74c50

Please sign in to comment.