jekyll-pagination-task 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []