jekyll-pagination-task
An advanced pagination tool for jekyll
Apology
I must apologize to those who have downloaded 1.0.0
to 1.0.2
version of
this plugin. I should have tested it in more complicated situations before
publishing it.
Also I'd like to apologize for the irresponsible pushes to RubyGems. I am new to Ruby and got overenthusiastic to have my own gem published.
I really would like this plugin to be useful and hope everyone enjoys it.
Installation
First you must install jekyll-pagination-task. It can be done by
gem install jekyll-pagination-task
or download the source code and compile it locally:
git clone https://github.com/emiapwil/jekyll-pagination-task
cd jekyll-pagination-task
gem build jekyll-pagination-task.gemsepc
gem install jekyll-pagination-task-{VERSION}.gem
Of course, you can just download the code and put
lib/jekyll-pagination-task/pagination_task.rb
to the _plugins/
folder of
your jekyll site.
Configuration
Site Configuration
After the installation you can put the following line in the _plugins/ext.rb
to make jekyll aware of its presence. If the ruby source file is put in
_plugins
, however, you can skip this step.
require "jekyll-pagination-task"
Then it is also required to add the following lines in _config.yml
:
pagination_task:
page_per_pager: 7
format: /:dir/:name/:Num
filter_class: Jekyll::PaginationTask::DefaultPaginationFilter
post_only: true
The first line is crucial since it indicates that jekyll-pagination-task plugin will be enabled. The other three lines are all optional:
page_per_pager
: how many pages should be include in one pager. The default value is 7.format
: how the url of the generated pagers should look like. The default value is/:dir/:name/:Num
. There are currently 4 macros::dir
: it will be replaced by the path to the template page;:name
: it will be replaced by the basename of the template page;:num
: it will be replaced by the index of the generated page;:Num
: same as:num
expect that 1 is replaced by an empty string.
filter_class
: which class to use as the filter for pages. The default value is Jekyll::PaginationTask::DefaultPaginationFilter.post_only
: only paginate the posts, the default value istrue
. If set tofalse
, the pages will be paginated as well.
Page Configuration
Unlike jekyll-paginate, this plugin identify template pages
by checking whether the attribute paginate
is set to true
in a page. To make
things more flexible, some other optional attributes can be set as well. These
configurations are demonstrated in the following example:
---
paginate: true
page_per_pager: 8
pagination_format: /posts/:Num
filter_class: Jekyll::PaginationTask::DefaultPaginationFilter
pagination_filter:
- ['layout', 'is', 'post']
- ['category', 'all', ['test', 'ruby']]
---
paginate
: indicates that this page is a template.page_per_pager
: same aspage_per_pager
in_config.yml
.pagination_format
: same asformat
in_config.yml
.filter_class
: same asfilter_class
in_config.yml
.pagination_filter
: this is used to store parameters forJekyll::PaginationTask::DefaultPaginationFilter
, each element of it will have the form of[$ATTR, $RELATION, $PARAMETER]
. Then attribute$ATTR
of the template page will be checked against$A_LIST_OF_VALUES
and the pages that satisfy all these conditions will be set as the pager's posts (this is for compatibility with jekyll-paginate). There are currently 8 relations supported:all
: true if the attribute$ATTR
contains all values from$PARAMETER
and otherwise false;any
: true if the attribute$ATTR
contains any of the values from$PARAMETER
and otherwise false;only
: true if the attribute$ATTR
contains values only from$PARAMETER
and otherwise false;none
: true if the attribute$ATTR
contains no values from$PARAMETER
and otherwise false;is
: true if$ATTR
equals$PARAMETER
and false otherwiseis_not
: true if$ATTR
doesn't equal$PARAMETER
and false otherwisein
: true if$ATTR
is a member of$PARAMETER
not_in
: true if$ATTR
is not a member of$PARAMETER
It is notable that the types of $ATTR
and $PARAMETER
are also indicated in
these relationships and I think they can cover most cases. If the default
filter still fails to meet the needs, you can always develop your own filter
class and point to it by setting the filter_class
option.
Demonstration
Assuming the full name of the template page is demo/post.md
which selects 45
posts using the frontmatter above. The following files will be generated:
/demo/post/index.html
, /demo/post/2/index.html
, ..., and
/demo/post/6/index.html
.
If we have another file named demo/post7.md
which uses the same frontmatter
expect the page_per_pager
line, it will use the configuration in _config.yml
and 7 pages will be generated with prefix /demo/post7/
instead of
/demo/post/
.
If we modify the pagination_format
in this demo/post7.md
file to
/home/test/:Num
, then the pages will be generated in /home/test/
folder
rather than /demo/post7
.
Work Flow
Here is a quick introduction to the implementation of jekyll-pagination-task:
- selects pages with
paginate
set totrue
as templates - for each tempalte, construct the filter with site and the template
- selects pages that satisfies the filter
- create
PTPager
, which is derived fromJekyll::Pager
and can set up the correct url for generated pagination pages. Then the generatedpager
pages are appended to site.pages
Features not Supported yet
- Infinite
page_per_pager
. - Structed options in the frontmatter.
- Customized Sorter support. Currently the posts are not sorted.
BUGs
I'm new to Ruby and this package is not fully tested, so there might be many bugs...
Known Bugs
Unable to generate correct pages when the url
function of the template has been called earlier.
The reason is that Jekyll::Page will generate the url once url
is called and
store it in @url
which is not accessible thus not modifiable. One workaround
is to hack the Jekyll package and add the :url
to attr_accesssor
in
Jekyll::Page
and then add one more line in create_pager
just before it
returns:
instance.url = nil # reset the url
Update: the hack is not necessary now since most plugins are unlikely to
touch these template files and the problem occurred earlier is caused by a call
to dir
in calculating the pagination path within this plugin. It is fixed in
a recent commit.