jekyll-pagination-task 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGFlMGFkN2M3ZTk5OTc0OWYwNmY1NzIxZWZiYjQ1NTE1OWEyOTlmYg==
5
+ data.tar.gz: !binary |-
6
+ OTE5NWM0M2IyN2IzMWI5N2FlYWUxMGE4OWI3NGVhZjI2YjIzZmU2ZQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MGE2M2YzMmJiYzE1ZWQyNWEyMjFjMDM3MGUwZTdiOTcxZTQ3YmMxYTQzOTQz
10
+ N2NiOWU1YjJiYzUyYjllZmMzMDlhYjk3MzhjNDBlOWRjNmNmNGQ4ZWVhYmIz
11
+ MDUyMGQyZmE3YWQwNzI1OTljM2JkMTYyMTQ2MTE3ZTA0MmZiOTU=
12
+ data.tar.gz: !binary |-
13
+ Y2RhMDYzZDk3YTY2NGM0MzlkZThjYjExNDFiYmZkOGY1MGJlNmJjYWJhNWIw
14
+ YzE5NDdhYzRmODIxZmEwNzY2Yjk3OWIyMGJkMGFlNmY5MjFjOTBmYWVhZjI5
15
+ ZGU3MGE4NWZmYmE4ZDc5YmUwZWU1NmY5YmIzMzNiZmE3MDJiZWE=
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ *.swp
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,183 @@
1
+ jekyll-pagination-task
2
+ ======================
3
+
4
+ An advanced pagination tool for jekyll
5
+
6
+ # Apology
7
+
8
+ I must apologize to those who have downloaded `1.0.0` to `1.0.2` version of
9
+ this plugin. I should have tested it in more complicated situations before
10
+ publishing it.
11
+
12
+ Also I'd like to apologize for the irresponsible pushes to [RubyGems][rubygem].
13
+ I am new to Ruby and got overenthusiastic to have my own gem published.
14
+
15
+ [rubygem]: http://rubygems.org/
16
+
17
+ I really would like this plugin to be useful and hope everyone enjoys it.
18
+
19
+ # Installation
20
+
21
+ First you must install jekyll-pagination-task. It can be done by
22
+
23
+ ~~~
24
+ gem install jekyll-pagination-task
25
+ ~~~
26
+
27
+ or download the source code and compile it locally:
28
+
29
+ ~~~
30
+ git clone https://github.com/emiapwil/jekyll-pagination-task
31
+ cd jekyll-pagination-task
32
+ gem build jekyll-pagination-task.gemsepc
33
+ gem install jekyll-pagination-task-{VERSION}.gem
34
+ ~~~
35
+
36
+ Of course, you can just download the code and put
37
+ `lib/jekyll-pagination-task/pagination_task.rb` to the `_plugins/` folder of
38
+ your jekyll site.
39
+
40
+ # Configuration
41
+
42
+ ## Site Configuration
43
+
44
+ After the installation you can put the following line in the `_plugins/ext.rb`
45
+ to make jekyll aware of its presence. If the ruby source file is put in
46
+ `_plugins`, however, you can skip this step.
47
+
48
+ ~~~
49
+ require "jekyll-pagination-task"
50
+ ~~~
51
+
52
+ Then it is also required to add the following lines in `_config.yml`:
53
+
54
+ ~~~
55
+ pagination_task:
56
+ page_per_pager: 7
57
+ format: /:dir/:name/:Num
58
+ filter_class: Jekyll::PaginationTask::DefaultPaginationFilter
59
+ post_only: true
60
+ ~~~
61
+
62
+ The first line is crucial since it indicates that jekyll-pagination-task plugin
63
+ will be enabled. The other three lines are all optional:
64
+
65
+ - `page_per_pager`: how many pages should be include in one pager. The default
66
+ value is 7.
67
+ - `format`: how the url of the generated pagers should look like. The default
68
+ value is `/:dir/:name/:Num`. There are currently 4 macros:
69
+ - `:dir`: it will be replaced by the path to the *template* page;
70
+ - `:name`: it will be replaced by the basename of the *template* page;
71
+ - `:num`: it will be replaced by the index of the generated page;
72
+ - `:Num`: same as `:num` expect that 1 is replaced by an empty string.
73
+ - `filter_class`: which class to use as the filter for pages. The default value
74
+ is Jekyll::PaginationTask::DefaultPaginationFilter.
75
+ - `post_only`: only paginate the posts, the default value is `true`. If set to
76
+ `false`, the pages will be paginated as well.
77
+
78
+ ## Page Configuration
79
+
80
+ Unlike [jekyll-paginate][jekyll-paginate], this plugin identify *template* pages
81
+ by checking whether the attribute `paginate` is set to `true` in a page. To make
82
+ things more flexible, some other optional attributes can be set as well. These
83
+ configurations are demonstrated in the following example:
84
+
85
+ [jekyll-paginate]: https://github.com/jekyll/jekyll-paginate
86
+
87
+ ~~~
88
+ ---
89
+ paginate: true
90
+ page_per_pager: 8
91
+ pagination_format: /posts/:Num
92
+ filter_class: Jekyll::PaginationTask::DefaultPaginationFilter
93
+ pagination_filter:
94
+ - ['layout', 'is', 'post']
95
+ - ['category', 'all', ['test', 'ruby']]
96
+ ---
97
+ ~~~
98
+
99
+ - `paginate`: indicates that this page is a *template*.
100
+ - `page_per_pager`: same as `page_per_pager` in `_config.yml`.
101
+ - `pagination_format`: same as `format` in `_config.yml`.
102
+ - `filter_class`: same as `filter_class` in `_config.yml`.
103
+ - `pagination_filter`: this is used to store parameters for
104
+ `Jekyll::PaginationTask::DefaultPaginationFilter`, each element of it will
105
+ have the form of `[$ATTR, $RELATION, $PARAMETER]`. Then attribute
106
+ `$ATTR` of the *template* page will be checked against `$A_LIST_OF_VALUES` and
107
+ the pages that satisfy all these conditions will be set as the pager's *posts*
108
+ (this is for compatibility with jekyll-paginate). There are currently 8
109
+ relations supported:
110
+ - `all`: *true* if the attribute `$ATTR` contains all values from `$PARAMETER`
111
+ and otherwise *false*;
112
+ - `any`: *true* if the attribute `$ATTR` contains any of the values from
113
+ `$PARAMETER` and otherwise *false*;
114
+ - `only`: *true* if the attribute `$ATTR` contains values only from
115
+ `$PARAMETER` and otherwise *false*;
116
+ - `none`: *true* if the attribute `$ATTR` contains no values from
117
+ `$PARAMETER` and otherwise *false*;
118
+ - `is`: *true* if `$ATTR` equals `$PARAMETER` and *false* otherwise
119
+ - `is_not`: *true* if `$ATTR` doesn't equal `$PARAMETER` and *false* otherwise
120
+ - `in`: *true* if `$ATTR` is a member of `$PARAMETER`
121
+ - `not_in`: *true* if `$ATTR` is not a member of `$PARAMETER`
122
+
123
+ It is notable that the types of `$ATTR` and `$PARAMETER` are also indicated in
124
+ these relationships and I think they can cover most cases. If the default
125
+ filter still fails to meet the needs, you can always develop your own filter
126
+ class and point to it by setting the `filter_class` option.
127
+
128
+ # Demonstration
129
+
130
+ Assuming the full name of the *template* page is `demo/post.md` which selects 45
131
+ posts using the frontmatter above. The following files will be generated:
132
+ `/demo/post/index.html`, `/demo/post/2/index.html`, ..., and
133
+ `/demo/post/6/index.html`.
134
+
135
+ If we have another file named `demo/post7.md` which uses the same frontmatter
136
+ expect the `page_per_pager` line, it will use the configuration in `_config.yml`
137
+ and 7 pages will be generated with prefix `/demo/post7/` instead of
138
+ `/demo/post/`.
139
+
140
+ If we modify the `pagination_format` in this `demo/post7.md` file to
141
+ `/home/test/:Num`, then the pages will be generated in `/home/test/` folder
142
+ rather than `/demo/post7`.
143
+
144
+ # Work Flow
145
+
146
+ Here is a quick introduction to the implementation of jekyll-pagination-task:
147
+
148
+ - selects pages with `paginate` set to `true` as *templates*
149
+ - for each *tempalte*, construct the *filter* with *site* and the *template*
150
+ - selects pages that satisfies the filter
151
+ - create `PTPager`, which is derived from `Jekyll::Pager` and can set up the
152
+ correct url for generated pagination pages. Then the generated `pager` pages
153
+ are appended to site.pages
154
+
155
+ # Features not Supported yet
156
+
157
+ - Infinite `page_per_pager`.
158
+ - Structed options in the frontmatter.
159
+ - Customized *Sorter* support. Currently the posts are not sorted.
160
+
161
+ # BUGs
162
+
163
+ I'm new to Ruby and this package is not fully tested, so there might be many
164
+ bugs...
165
+
166
+ ## Known Bugs
167
+
168
+ ### **Unable to generate correct pages when the `url` function of the template has been called earlier**.
169
+
170
+ The reason is that Jekyll::Page will generate the url once `url` is called and
171
+ store it in `@url` which is not accessible thus not modifiable. One workaround
172
+ is to hack the Jekyll package and add the `:url` to `attr_accesssor` in
173
+ `Jekyll::Page` and then add one more line in `create_pager` just before it
174
+ returns:
175
+
176
+ ~~~
177
+ instance.url = nil # reset the url
178
+ ~~~
179
+
180
+ **Update**: the hack is not necessary now since most plugins are unlikely to
181
+ touch these template files and the problem occurred earlier is caused by a call
182
+ to `dir` in calculating the pagination path within this plugin. It is fixed in
183
+ a recent commit.
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'jekyll-pagination-task'
7
+ spec.version = '1.0.3'
8
+ spec.license = 'MIT'
9
+ spec.date = '2014-12-10'
10
+
11
+ spec.summary = 'An advanced paginator for Jekyll'
12
+ spec.description = <<-DESC
13
+ Jekyll Pagination Task allows you to create paginated pages by
14
+ defining filters on attributes of all Jekyll pages.'
15
+ DESC
16
+
17
+ spec.author = ['Kai Gao']
18
+ spec.email = 'emiapwil@gmail.com'
19
+ spec.homepage = 'http://github.com/emiapwil/jekyll-pagination-task'
20
+
21
+ spec.files = `git ls-files`.split($/)
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'jekyll-paginate', '~> 1.1.0'
25
+ end
@@ -0,0 +1 @@
1
+ require "jekyll-pagination-task/pagination_task"
@@ -0,0 +1,224 @@
1
+ module Jekyll
2
+ module PaginationTask
3
+
4
+ class PaginationFilter
5
+ def initialize(site, pager) end
6
+
7
+ def satisfy?(page)
8
+ false
9
+ end
10
+ end
11
+
12
+ class DefaultPaginationFilter < PaginationFilter
13
+
14
+ def initialize(site, pager)
15
+ @filters = []
16
+ conditions = pager["pagination_filter"] || []
17
+ conditions.each do |condition|
18
+ name = condition[0]
19
+ relation = condition[1]
20
+ if !respond_to?("check_#{relation}")
21
+ Jekyll.logger.warn "Decteced unsupported action " + attr_action
22
+ + " in pager file " + pager.url
23
+
24
+ next
25
+ end
26
+ parameters = condition[2]
27
+ @filters << { "name" => name, "relation" => relation, "parameters" => parameters }
28
+ end
29
+ end
30
+
31
+ def check_all(parameters, attr)
32
+ return false if attr.nil?
33
+ parameters.each { |parameter| return false if !attr.include?(parameter) }
34
+ true
35
+ end
36
+
37
+ def check_any(parameters, attr)
38
+ return false if attr.nil?
39
+ parameters.each { |parameter| return true if attr.include?(parameter) }
40
+ false
41
+ end
42
+
43
+ def check_only(parameters, attr)
44
+ return true if attr.nil?
45
+ attr.each { |attribute| return false if !parameters.include?(attribute) }
46
+ true
47
+ end
48
+
49
+ def check_none(parameters, attr)
50
+ return true if attr.nil?
51
+ parameters.each { |parameter| return false if attr.include?(parameter) }
52
+ true
53
+ end
54
+
55
+ def check_is(parameters, attr)
56
+ parameters === attr
57
+ end
58
+
59
+ def check_is_not(parameters, attr)
60
+ parameters != attr
61
+ end
62
+
63
+ def check_in(parameters, attr)
64
+ parameters.include?(attr)
65
+ end
66
+
67
+ def check_not_in(parameters, attr)
68
+ !parameters.include?(attr)
69
+ end
70
+
71
+ def satisfy?(page)
72
+ @filters.each do |filter|
73
+ relation = filter["relation"]
74
+ parameters = filter["parameters"]
75
+ attr = page[filter["name"]]
76
+ checker = method("check_#{relation}")
77
+ return false if !checker.call(parameters, attr)
78
+ end
79
+ true
80
+ end
81
+ end
82
+
83
+ class PaginationTask < Generator
84
+ # This generator is safe from arbitrary code execution.
85
+ safe true
86
+
87
+ # This generator should be passive with regard to its execution
88
+ priority :lowest
89
+
90
+ # Determine if pagination task is enabled
91
+ #
92
+ # site - the Jekyll::Site object
93
+ #
94
+ # Returns true if pagination_task is enabled, false otherwise
95
+ def self.enabled?(site)
96
+ !site.config['pagination_task'].nil? && (site.pages.size > 0)
97
+ end
98
+
99
+ # Generate paginated pages if necessary.
100
+ #
101
+ # site - The Site.
102
+ #
103
+ # Returns nothing.
104
+ def generate(site)
105
+ if PaginationTask.enabled?(site)
106
+ if pagers = candidate_pagers(site)
107
+ pagers.each { |pager| site.pages.delete(pager) }
108
+ pagers.each { |pager| paginate(site, pager) }
109
+ end
110
+ end
111
+ end
112
+
113
+ # Get the filter
114
+ #
115
+ # site - the Jekyll::Site object
116
+ #
117
+ # return - the instance of the filter
118
+ def get_filter(site, pager)
119
+ page_filter_class = pager['filter_class']
120
+ site_filter_class = site.config['pagination_task']['filter_class']
121
+ class_name = page_filter_class || site_filter_class
122
+
123
+ if class_name.nil? || !Object.const_defined?(class_name)
124
+ DefaultPaginationFilter.new(site, pager)
125
+ else
126
+ Object.const_get(class_name).new(site, pager)
127
+ end
128
+ end
129
+
130
+ def create_pager(site, template, pager)
131
+ instance = template.dup
132
+ instance.basename = "index"
133
+ instance.dir = PTPager.paginate_path(site, template, pager.page)
134
+ instance.pager = pager
135
+ instance.data['paginated'] = true
136
+
137
+ instance
138
+ end
139
+
140
+ # Paginates the blog's pages.
141
+ #
142
+ # site - The Site.
143
+ # template - The pager template that defines a pagination.
144
+ #
145
+ def paginate(site, template)
146
+ post_only = site.config['pagination_task']['post_only'] || true
147
+ all_pages = []
148
+ if !YAML.load(post_only.to_s)
149
+ Jekyll.logger.info 'here'
150
+ all_pages += site.pages.select{ | page | !page['paginated'] }
151
+ end
152
+ all_pages += site.posts
153
+ filter = get_filter(site, template)
154
+
155
+ if filter.nil?
156
+ Jekyll.logger.warn "Failed to create filter for page " + pager.url
157
+ return
158
+ end
159
+ all_pages = all_pages.select{ | page | filter.satisfy?(page) }
160
+
161
+ page_per_pager = template['page_per_pager']
162
+ page_per_pager = page_per_pager || site.config['pagination_task']['page_per_pager']
163
+ page_per_pager = page_per_pager || 7
164
+
165
+ npages = Paginate::Pager.calculate_pages(all_pages, page_per_pager.to_i)
166
+ (1..npages).each do |num_page|
167
+ pager = PTPager.new(site, template, num_page, all_pages, page_per_pager.to_i)
168
+ site.pages << create_pager(site, template, pager)
169
+ end
170
+ end
171
+
172
+ # Public: Find the Jekyll::Page which will act as the pager template
173
+ #
174
+ # site - the Jekyll::Site object
175
+ #
176
+ # Returns the Jekyll::Page which will act as the pager template
177
+ def candidate_pagers(site)
178
+ site.pages.select { |page| (page['paginate'] || false ) === true }
179
+ end
180
+ end
181
+ end
182
+
183
+ class PTPager < Paginate::Pager
184
+
185
+ # Get the path for the generated pagers
186
+ #
187
+ # site - the Jekyll::Site object
188
+ # pager - the template for the pager
189
+ def self.paginate_path(site, pager, page_num)
190
+ return nil if page_num.nil?
191
+ format = pager['pagination_format']
192
+ format = format || site.config['pagination_task']['format']
193
+ format = format || '/:dir/:name/:Num'
194
+ dir = remove_leading_slash(pager.dup.dir)
195
+ name = File.basename(pager.name, File.extname(pager.name))
196
+ format = format.sub(':dir', dir)
197
+ format = format.sub(':name', name)
198
+ format = format.sub(':num', page_num.to_s)
199
+ format = page_num > 1 ? format.sub(':Num', page_num.to_s) : format.sub(':Num', '')
200
+ ensure_leading_slash(format)
201
+ end
202
+
203
+ # Initialize a new PTPager.
204
+ #
205
+ # site - the Jekyll::Site object
206
+ # pager - the pager template page
207
+ # current - The Integer page number.
208
+ # all_posts - The Array of all the site's Posts.
209
+ # num_pages - The Integer number of pages or nil if you'd like the number
210
+ # of pages calculated.
211
+ def initialize(site, pager, current, all_posts, per_page)
212
+ super(site, current, all_posts, Paginate::Pager.calculate_pages(all_posts, per_page))
213
+
214
+ @per_page = per_page
215
+ init = (@page - 1) * @per_page
216
+ offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
217
+
218
+ @posts = all_posts[init..offset]
219
+
220
+ @previous_page_path = PTPager.paginate_path(site, pager, @previous_page)
221
+ @next_page_path = PTPager.paginate_path(site, pager, @next_page)
222
+ end
223
+ end
224
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-pagination-task
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Kai Gao
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll-paginate
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.0
27
+ description: ! " Jekyll Pagination Task allows you to create paginated pages by\n
28
+ \ defining filters on attributes of all Jekyll pages.'\n"
29
+ email: emiapwil@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - LICENSE
36
+ - README.md
37
+ - jekyll-pagination-task.gemspec
38
+ - lib/jekyll-pagination-task.rb
39
+ - lib/jekyll-pagination-task/pagination_task.rb
40
+ homepage: http://github.com/emiapwil/jekyll-pagination-task
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.0.14
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: An advanced paginator for Jekyll
64
+ test_files: []