jekyll-paginate-v2 1.0.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cd4827a1c9dd80de07ba232d75d61c573b52eeaf
4
+ data.tar.gz: a6238314308d5a386f8fab3f2b28f730b51ab8a7
5
+ SHA512:
6
+ metadata.gz: 917b6eadca4c14048091ee608c8a284ba17ed3d5a8430c8723828b5cfda7918a64658dbbf7fccd53783ea25253a6e3edaf6432bce4c878c34d6a81884e151466
7
+ data.tar.gz: 72686ab7df0df3a8d2686f4c8141645df09c82248c547215f1fc2a5bbe4f4db40e19f2a672d8869abfac8a6408f36d0ce16aa983cc35736b35c50596ec93bc36
@@ -0,0 +1,16 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ spec/dest
16
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jekyll-paginate-v2.gemspec
4
+ gemspec
5
+
6
+ if ENV["JEKYLL_VERSION"]
7
+ gem "jekyll", "~> #{ENV["JEKYLL_VERSION"]}"
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sverrir Sigmundarson
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,248 @@
1
+ # Jekyll::Paginate V2
2
+
3
+ Pagination plugin built specially for Jekyll 3 and newer.
4
+
5
+ Enhanced replacement for the previously built-in [jekyll-paginate gem](https://github.com/jekyll/jekyll-paginate).
6
+
7
+ The code was based on the original design of [jekyll-paginate](https://github.com/jekyll/jekyll-paginate) and features were mostly drawn from discussions from the issues pages (especially https://github.com/jekyll/jekyll-paginate/issues/27) and some from the excellent [Octopress::Paginate code](https://github.com/octopress/paginate).
8
+
9
+ Thanks everybody :heart:
10
+
11
+ ## Features
12
+
13
+ In addition to all the features offered by the older [jekyll-paginate gem](https://github.com/jekyll/jekyll-paginate) this new pagination plugin features include
14
+
15
+ 1. Works with any type of file ending (HTML, Markdown, etc) as long as the file has front-matter and the minimum page level pagination meta (see [page-configuration](#page-configuration)).
16
+ 2. Paginated files can have any file name (not just index.html).
17
+ 3. Supports category, tag and locale filtering.
18
+ 4. Supports any combination of category, tag and locale filtering (e.g. _all posts in the 'ruby' category written for 'en\_US'_ or _all posts in 'car' and 'cycle' category tagged with 'cool' written for 'fr\_FR'_)
19
+ 5. Sorting of posts by any field. Decending or Ascending.
20
+ 6. Optional limits of number of pagenated pages (e.g. _only produce 15 pages_)
21
+ 7. Fully customizable permalink format. E.g `/page:num/` or `/page/:num/` or `/:num/` or really anything you want.
22
+ 8. Optional title suffix for paginated pages (e.g. _Index - Page 2_)
23
+
24
+ All this while being fully backwards compatible with the old [jekyll-paginate](https://github.com/jekyll/jekyll-paginate) gem (requires minimal additional front-matter, see [page-configuration](#page-configuration)).
25
+
26
+ ## Installation
27
+
28
+ Currently this plugin is in develpment mode and is not yet distributed as a gem (mostly because I don't know how).
29
+
30
+ To install, simply copy the `lib\jekyll-paginate-v2.rb` file into the `_plugins` folder under your Jekyll site root.
31
+ > If the _plugins folder does not exist simply create it.
32
+
33
+ Then add the necessary [Site YML](#site-configuration) and [Page](#page-configuration) configuration elements.
34
+
35
+ Run `jekyll serve` and you should see the pagination plugin debug messages printed during site generation:
36
+
37
+ ``` bash
38
+ Generating...
39
+ Pagination: found template: pictures/bestof.md
40
+ Pagination: found template: puffins/list.html
41
+ Pagination: found template: index.html
42
+ ```
43
+
44
+ ## Current state
45
+
46
+ Currently this code is in dire need of feedback, code review and testing.
47
+
48
+ I also would welcome guidance on how to write automated tests for this code so that I can publish it as a Gem.
49
+
50
+ Come to think of it, I currently have no idea on how to publish a Gem... :/
51
+
52
+ > Don't worry too much about the current structure, this is just the first iteration.
53
+ > The code is currently a single file `jekyll-paginate-v2.rb` only because it makes it faster to develop and debug. As soon as I and hopefully other people test and green-light the logic I intend to break this code into separate files and distribute as a gem.
54
+
55
+ ## Contributing
56
+
57
+ 1. Fork it ( https://github.com/sverrirs/jekyll-paginate-v2/fork )
58
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
59
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
60
+ 4. Push to the branch (`git push origin my-new-feature`)
61
+ 5. Create new Pull Request
62
+
63
+ ## Site configuration
64
+
65
+ The plugin can be configured in the site's `_config.yml` file by including the `pagination` configuration element
66
+
67
+ ``` yml
68
+ ############################################################
69
+ # Site configuration for the Jekyll 3 Pagination Plugin
70
+ # The values here represent the defaults if nothing is set
71
+ pagination:
72
+
73
+ # Site-wide kill switch, disabled here it doesn't run at all
74
+ enabled: true
75
+
76
+ # How many objects per paginated page, used to be `paginate` (default: 0, means all)
77
+ per_page: 10
78
+
79
+ # The permalink structure for the paginated pages (this can be any level deep)
80
+ permalink: '/page/:num/'
81
+
82
+ # Optional additional suffix for the title of the paginated pages (the prefix is inherited from the template page)
83
+ title_suffix: ' - page :num'
84
+
85
+ # Limit how many pagenated pages to create (default: 0, means all)
86
+ limit: 0
87
+
88
+ # Optional, defines the field that the posts should be sorted on (omit to default to 'date')
89
+ sort_field: 'date'
90
+
91
+ # Optional, sorts the posts in reverse order (omit to default decending or sort_reverse: true)
92
+ sort_reverse: true
93
+
94
+ # The default category to use, just leave this as 'posts' to get a backwards-compatible behavior (all posts)
95
+ category: 'posts'
96
+
97
+ # Optional, the default tag to use, omit to disable
98
+ tag: 'cool'
99
+
100
+ # Optional, the default locale to use, omit to disable (depends on a field 'locale' to be specified in the posts,
101
+ # 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 )
102
+ locale: 'en_US'
103
+
104
+ ############################################################
105
+ ```
106
+
107
+ ## Page configuration
108
+
109
+ To enable pagination on a page (i.e. make that page a template for pagination) then simply include the minimal pagination configuration in the page front-matter:
110
+
111
+ ``` yml
112
+ pagination:
113
+ enabled: true
114
+ ```
115
+
116
+ Then you can use the normal `paginator.posts` logic to iterate through the posts.
117
+
118
+ ``` html
119
+ {% for post in paginator.posts %}
120
+ <h1>{{ post.title }}</h1>
121
+ {% endfor %}
122
+ ```
123
+
124
+ And to display pagination links, simply
125
+
126
+ ``` html
127
+ {% if paginator.total_pages > 1 %}
128
+ <ul class="pager">
129
+ {% if paginator.previous_page %}
130
+ <li class="previous">
131
+ <a href="{{ paginator.previous_page_path | prepend: site.baseurl | replace: '//', '/' }}">Newer Posts</a>
132
+ </li>
133
+ {% endif %}
134
+ {% if paginator.next_page %}
135
+ <li class="next">
136
+ <a href="{{ paginator.next_page_path | prepend: site.baseurl | replace: '//', '/' }}">Older Posts</a>
137
+ </li>
138
+ {% endif %}
139
+ </ul>
140
+ {% endif %}
141
+ ```
142
+
143
+ The code is fully backwards compatible and you will have access to all the normal paginator variables defined in the [official jekyll documentation](https://jekyllrb.com/docs/pagination/#liquid-attributes-available).
144
+
145
+ Neat!
146
+
147
+ ## Paginate categories, tags, locales
148
+
149
+ Enabling pagination for specific categories, tags or locales is as simple as adding values to the pagination template front-matter and corresponding values in the posts.
150
+
151
+ ### Filtering categories
152
+
153
+ Filter single category 'software'
154
+
155
+ ``` yml
156
+ pagination:
157
+ enabled: true
158
+ category: software
159
+ ```
160
+
161
+ Filter multiple categories (lists only posts belonging to all categories)
162
+
163
+ ``` yml
164
+ pagination:
165
+ enabled: true
166
+ category: software, ruby
167
+ ```
168
+
169
+ > To define categories you can either specify them in the front-matter or through the [directory structure](http://jekyllrb.com/docs/variables/#page-variables) of your jekyll site (Categories are derived from the directory structure above the \_posts directory). You can actually use both approaches to assign your pages to multiple categories.
170
+
171
+ ### Filtering tags
172
+
173
+ Filter on a single tag
174
+
175
+ ``` yml
176
+ pagination:
177
+ enabled: true
178
+ tag: cool
179
+ ```
180
+
181
+ Filter on multiple tags
182
+
183
+ ``` yml
184
+ pagination:
185
+ enabled: true
186
+ tag: cool, life
187
+ ```
188
+
189
+ ### Filtering locales
190
+
191
+ In the case your site offers multiple languages you can include a `locale` item in your post front matter. The paginator can then use this value to filter on
192
+
193
+ The category page front-matter would look like this
194
+
195
+ ``` yml
196
+ pagination:
197
+ enabled: true
198
+ locale: en_US
199
+ ```
200
+
201
+ Then for the relevant posts, include the `locale` variable in their front-matter
202
+
203
+ ``` yml
204
+ locale: en_US
205
+ ```
206
+
207
+ ## Paginate on combination of filters
208
+
209
+ Including only posts from categories 'ruby' and 'software' written in English
210
+
211
+ ``` yml
212
+ pagination:
213
+ enabled: true
214
+ category: software, ruby
215
+ locale: en_US, en_GB, en_WW
216
+ ```
217
+
218
+ Only showing posts tagged with 'cool' and in category 'cars'
219
+
220
+ ``` yml
221
+ pagination:
222
+ enabled: true
223
+ category: cars
224
+ tag: cool
225
+ ```
226
+
227
+ ... and so on and so on
228
+
229
+ ## Configuration overrides
230
+
231
+ All of the configuration elements from the `_config.yml` file can be overwritten in the pagination template pages. E.g. if you want one category page to have different permalink structure simply override the item like so
232
+
233
+ ``` yml
234
+ pagination:
235
+ enabled: true
236
+ category: cars
237
+ permalink: '/cars/:num/'
238
+ ```
239
+
240
+ Overriding sorting to sort by the post title in ascending order for another paginated template could be done like so
241
+
242
+ ``` yml
243
+ pagination:
244
+ enabled: true
245
+ category: ruby
246
+ sort_field: 'title'
247
+ sort_reverse: false
248
+ ```
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jekyll-paginate-v2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jekyll-paginate-v2"
8
+ spec.version = Jekyll::PaginateV2::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.date = '2016-11-18'
11
+ spec.authors = ["Sverrir Sigmundarson"]
12
+ spec.email = ["jekyll@sverrirs.com"]
13
+ spec.homepage = "https://github.com/sverrirs/jekyll-paginate-v2"
14
+ spec.license = "MIT"
15
+
16
+ spec.summary = %q{Pagination Generator for Jekyll 3}
17
+ spec.description = %q{An enhanced in-place replacement for the previously built-in jekyll-paginate gem offering full backwards compatability as well as a slew of new frequently requested features}
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ #spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ #spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "jekyll", ">= 3.0"
25
+ spec.add_development_dependency "bundler", "~> 1.5"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
+ end
@@ -0,0 +1,21 @@
1
+ # Jekyll::Paginate V2 is a gem built for Jekyll 3 that generates pagiatation for posts, categories and tags.
2
+ #
3
+ # It is based on https://github.com/jekyll/jekyll-paginate, the original Jekyll paginator
4
+ # which was decommissioned in Jekyll 3 release onwards. This code is currently not officially
5
+ # supported on Jekyll versions < 3.0 (although it might work)
6
+ #
7
+ # Author: Sverrir Sigmundarson
8
+ # Site: https://github.com/sverrirs/jekyll-paginate-v2
9
+ # Distributed Under The MIT License (MIT) as described in the LICENSE file
10
+ # - https://opensource.org/licenses/MIT
11
+
12
+ require "jekyll-paginate-v2/version"
13
+ require "jekyll-paginate-v2/defaults"
14
+ require "jekyll-paginate-v2/utils"
15
+ require "jekyll-paginate-v2/paginator"
16
+ require "jekyll-paginate-v2/pagination"
17
+
18
+ module Jekyll
19
+ module PaginateV2
20
+ end # module PaginateV2
21
+ end # module Jekyll
@@ -0,0 +1,18 @@
1
+ module Jekyll
2
+ module PaginateV2
3
+
4
+ # The default configuration for the Paginator
5
+ DEFAULT = {
6
+ 'enabled' => false,
7
+ 'collection' => 'posts',
8
+ 'per_page' => 10,
9
+ 'permalink' => '/page:num/', # Supports :num as customizable elements
10
+ 'title_suffix' => ' - page :num', # Supports :num as customizable elements
11
+ 'page_num' => 1,
12
+ 'sort_reverse' => false,
13
+ 'sort_field' => 'date',
14
+ 'limit' => 0 # Limit how many content objects to paginate (default: 0, means all)
15
+ }
16
+
17
+ end # module PaginateV2
18
+ end # module Jekyll
@@ -0,0 +1,252 @@
1
+ module Jekyll
2
+ module PaginateV2
3
+
4
+ class PaginationV2 < Generator
5
+ # This generator is safe from arbitrary code execution.
6
+ safe true
7
+
8
+ # This generator should be passive with regard to its execution
9
+ priority :lowest
10
+
11
+ # Generate paginated pages if necessary (Default entry point)
12
+ # site - The Site.
13
+ #
14
+ # Returns nothing.
15
+ def generate(site)
16
+
17
+ # Retrieve and merge the folate configuration from the site yml file
18
+ default_config = DEFAULT.merge(site.config['pagination'] || {})
19
+
20
+ # If disabled then simply quit
21
+ if !default_config['enabled']
22
+ Jekyll.logger.info "Pagination:","disabled in site.config."
23
+ return
24
+ end
25
+
26
+ Jekyll.logger.debug "Pagination:","Starting"
27
+
28
+ # By default if pagination is enabled we attempt to find all index.html pages in the site
29
+ templates = self.discover_paginate_templates(site)
30
+ if( templates.size.to_i <= 0 )
31
+ Jekyll.logger.warn "Pagination:","is enabled, but I couldn't find " +
32
+ "any index.html page to use as the pagination template. Skipping pagination."
33
+ return
34
+ end
35
+
36
+ # Get all posts that will be generated (excluding hidden posts such as drafts)
37
+ all_posts = site.site_payload['site']['posts'].reject { |post| post['hidden'] }
38
+
39
+ # Create the necessary indexes for the posts
40
+ all_categories = self.index_posts_by(all_posts, 'categories')
41
+ all_categories['posts'] = all_posts; # Popuplate a category for all posts
42
+ # (this is a default and must not be used in the category system)
43
+ all_tags = self.index_posts_by(all_posts, 'tags')
44
+ all_locales = self.index_posts_by(all_posts, 'locale')
45
+
46
+ # Now for each template page generate the paginator for it
47
+ for template in templates
48
+
49
+ # All pages that should be paginated need to include the pagination config element
50
+ if template.data['pagination'].is_a?(Hash)
51
+ template_config = default_config.merge(template.data['pagination'])
52
+
53
+ # Only paginate the template if it is explicitly enabled
54
+ # requiring this makes the logic simpler as I don't need to determine which index pages
55
+ # were generated automatically and which weren't
56
+ if( template_config['enabled'] )
57
+ Jekyll.logger.info "Pagination:","found template: "+template.path
58
+ # Now construct the pagination data for this template page
59
+ self.paginate(site, template, template_config, all_posts, all_tags, all_categories, all_locales)
60
+ end
61
+ end
62
+ end #for
63
+
64
+ end # function generate
65
+
66
+ #
67
+ # Rolls through the entire site and finds all index.html pages available
68
+ #
69
+ # site - The Site.
70
+ #
71
+ def discover_paginate_templates(site)
72
+ candidates = []
73
+ site.pages.select do |page|
74
+ # If the page has the enabled config set, supports any type of file name html or md
75
+ if page.data['pagination'].is_a?(Hash) && page.data['pagination']['enabled']
76
+ candidates << page
77
+ end
78
+ end
79
+ return candidates
80
+ end # function discover_paginate_templates
81
+
82
+ #
83
+ # Create a hash index for all post based on a key in the post.data table
84
+ #
85
+ def index_posts_by(all_posts, index_key)
86
+ return nil if all_posts.nil?
87
+ return all_posts if index_key.nil?
88
+ index = {}
89
+ for post in all_posts
90
+ next if post.data.nil?
91
+ next if !post.data.has_key?(index_key)
92
+ next if post.data[index_key].nil?
93
+ next if post.data[index_key].size <= 0
94
+ next if post.data[index_key].to_s.strip.length == 0
95
+
96
+ # Only tags and categories come as premade arrays, locale does not, so convert any data
97
+ # elements that are strings into arrays
98
+ post_data = post.data[index_key]
99
+ if post_data.is_a?(String)
100
+ post_data = post_data.split(/;|,|\s/)
101
+ end
102
+
103
+ for key in post_data
104
+ key = key.downcase.strip
105
+ # If the key is a delimetered list of values
106
+ # (meaning the user didn't use an array but a string with commas)
107
+ for k_split in key.split(/;|,/)
108
+ k_split = k_split.downcase.strip #Clean whitespace and junk
109
+ if !index.has_key?(k_split)
110
+ index[k_split.to_s] = []
111
+ end
112
+ index[k_split.to_s] << post
113
+ end
114
+ end
115
+ end
116
+ return index
117
+ end # function index_posts_by
118
+
119
+ #
120
+ # Creates an intersection (only returns common elements)
121
+ # between multiple arrays
122
+ #
123
+ def intersect_arrays(first, *rest)
124
+ return nil if first.nil?
125
+ return nil if rest.nil?
126
+
127
+ intersect = first
128
+ rest.each do |item|
129
+ return [] if item.nil?
130
+ intersect = intersect & item
131
+ end
132
+ return intersect
133
+ end #function intersect_arrays
134
+
135
+ #
136
+ # Filters posts based on a keyed source_posts hash of indexed posts and performs a intersection of
137
+ # the two sets. Returns only posts that are common between all collections
138
+ #
139
+ def read_config_value_and_filter_posts(config, config_key, posts, source_posts)
140
+ return nil if posts.nil?
141
+ return nil if source_posts.nil? # If the source is empty then simply don't do anything
142
+ return posts if config.nil?
143
+ return posts if !config.has_key?(config_key)
144
+ return posts if config[config_key].nil?
145
+
146
+ # Get the filter values from the config (this is the cat/tag/locale values that should be filtered on)
147
+ config_value = config[config_key]
148
+
149
+ # If we're dealing with a delimitered string instead of an array then let's be forgiving
150
+ if( config_value.is_a?(String))
151
+ config_value = config_value.split(/;|,/)
152
+ end
153
+
154
+ # Now for all filter values for the config key, let's remove all items from the posts that
155
+ # aren't common for all collections that the user wants to filter on
156
+ for key in config_value
157
+ key = key.downcase.strip
158
+ posts = self.intersect_arrays(posts, source_posts[key])
159
+ end
160
+
161
+ # The fully filtered final post list
162
+ return posts
163
+ end #function read_config_value_and_filter_posts
164
+
165
+ #
166
+ # Sorting routine used for ordering posts by custom fields.
167
+ # Handles Strings separately as we want a case-insenstive sorting
168
+ #
169
+ def _sort_posts(a, b)
170
+ if a.is_a?(String)
171
+ return a.downcase <=> b.downcase
172
+ end
173
+
174
+ # By default use the built in sorting for the data type
175
+ return a <=> b
176
+ end
177
+
178
+ # Paginates the blog's posts. Renders the index.html file into paginated
179
+ # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
180
+ # site-wide data.
181
+ #
182
+ # site - The Site.
183
+ # template - The index.html Page that requires pagination.
184
+ # config - The configuration settings that should be used
185
+ #
186
+ def paginate(site, template, config, all_posts, all_tags, all_categories, all_locales)
187
+
188
+ # By default paginate on all posts in the site
189
+ using_posts = all_posts
190
+
191
+ # Now start filtering out any posts that the user doesn't want included in the pagination
192
+ using_posts = self.read_config_value_and_filter_posts(config, 'category', using_posts, all_categories)
193
+ using_posts = self.read_config_value_and_filter_posts(config, 'tag', using_posts, all_tags)
194
+ using_posts = self.read_config_value_and_filter_posts(config, 'locale', using_posts, all_locales)
195
+
196
+ # Apply sorting to the posts if configured, any field for the post is available for sorting
197
+ if config['sort_field']
198
+ sort_field = config['sort_field'].to_s
199
+ using_posts.sort!{ |a,b| self._sort_posts(a.data[sort_field], b.data[sort_field]) }
200
+
201
+ if config['sort_reverse']
202
+ using_posts.reverse!
203
+ end
204
+ end
205
+
206
+ # Calculate the max number of pagination-pages based on the configured per page value
207
+ total_pages = self.calculate_number_of_pages(using_posts, config['per_page'])
208
+
209
+ # If a upper limit is set on the number of total pagination pages then impose that now
210
+ if config['limit'] && config['limit'].to_i > 0 && config['limit'].to_i < total_pages
211
+ total_pages = config['limit'].to_i
212
+ end
213
+
214
+ # Now for each pagination page create it and configure the ranges for the collection
215
+ # This .pager member is a built in thing in Jekyll and defines the paginator implementation
216
+ # Simpy override to use mine
217
+ (1..total_pages).each do |cur_page_nr|
218
+ pager = PaginatorV2.new( config, using_posts, cur_page_nr, total_pages, template )
219
+ if( cur_page_nr > 1)
220
+ newpage = Page.new( site, site.source, template.dir, template.name)
221
+ newpage.pager = pager
222
+ newpage.dir = Utils.paginate_path(template, cur_page_nr, config)
223
+ if( config.has_key?('title_suffix'))
224
+ if( !template.data['title'] )
225
+ tmp_title = site.config['title']
226
+ else
227
+ tmp_title = template.data['title']
228
+ end
229
+
230
+ newpage.data['title'] = "#{tmp_title}#{Utils.format_page_number(config['title_suffix'], cur_page_nr)}"
231
+ end
232
+ site.pages << newpage
233
+ else
234
+ template.pager = pager
235
+ end
236
+ end
237
+ end # function paginate
238
+
239
+ # Calculate the number of pages.
240
+ #
241
+ # all_posts - The Array of all Posts.
242
+ # per_page - The Integer of entries per page.
243
+ #
244
+ # Returns the Integer number of pages.
245
+ def calculate_number_of_pages(all_posts, per_page)
246
+ (all_posts.size.to_f / per_page.to_i).ceil
247
+ end
248
+
249
+ end # class PaginationV2
250
+
251
+ end # module PaginateV2
252
+ end # module Jekyll
@@ -0,0 +1,58 @@
1
+ module Jekyll
2
+ module PaginateV2
3
+
4
+ #
5
+ # Handles the preparation of all the posts based on the current page index
6
+ #
7
+ class PaginatorV2
8
+ attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
9
+ :previous_page, :previous_page_path, :next_page, :next_page_path
10
+
11
+ # Initialize a new Paginator.
12
+ #
13
+ # site - the Jekyll::Site object
14
+ # page_nr - The Integer page number.
15
+ # all_posts - The Array of all the site's Posts.
16
+ # num_pages - The Integer number of pages or nil if you'd like the number
17
+ # of pages calculated.
18
+ def initialize(config, posts, cur_page_nr, num_pages, template )
19
+ @page = cur_page_nr
20
+ @per_page = config['per_page'].to_i
21
+ @total_pages = num_pages
22
+
23
+ if @page > @total_pages
24
+ raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
25
+ end
26
+
27
+ init = (@page - 1) * @per_page
28
+ offset = (init + @per_page - 1) >= posts.size ? posts.size : (init + @per_page - 1)
29
+
30
+ @total_posts = posts.size
31
+ @posts = posts[init..offset]
32
+ @previous_page = @page != 1 ? @page - 1 : nil
33
+ @previous_page_path = Utils.paginate_path(template, @previous_page, config)
34
+ @next_page = @page != @total_pages ? @page + 1 : nil
35
+ @next_page_path = Utils.paginate_path(template, @next_page, config)
36
+ end
37
+
38
+ # Convert this Paginator's data to a Hash suitable for use by Liquid.
39
+ #
40
+ # Returns the Hash representation of this Paginator.
41
+ def to_liquid
42
+ {
43
+ 'per_page' => per_page,
44
+ 'posts' => posts,
45
+ 'total_posts' => total_posts,
46
+ 'total_pages' => total_pages,
47
+ 'page' => page,
48
+ 'previous_page' => previous_page,
49
+ 'previous_page_path' => previous_page_path,
50
+ 'next_page' => next_page,
51
+ 'next_page_path' => next_page_path
52
+ }
53
+ end
54
+
55
+ end # class PaginatorV2
56
+
57
+ end # module PaginateV2
58
+ end # module Jekyll
@@ -0,0 +1,58 @@
1
+ module Jekyll
2
+ module PaginateV2
3
+
4
+ #
5
+ # Static utility functions that are used in the code and
6
+ # don't belong in once place in particular
7
+ #
8
+ class Utils
9
+
10
+ # Static: Return the pagination path of the page
11
+ #
12
+ # site - the Jekyll::Site object
13
+ # cur_page_nr - the pagination page number
14
+ # config - the current configuration in use
15
+ #
16
+ # Returns the pagination path as a string
17
+ def self.paginate_path(template, cur_page_nr, config)
18
+ return nil if cur_page_nr.nil?
19
+ return template.url if cur_page_nr <= 1
20
+ format = config['permalink']
21
+ if format.include?(":num")
22
+ format = Utils.format_page_number(format, cur_page_nr)
23
+ else
24
+ raise ArgumentError.new("Invalid pagination path: '#{format}'. It must include ':num'.")
25
+ end
26
+ Utils.ensure_leading_slash(format)
27
+ end #function paginate_path
28
+
29
+ # Static: returns a fully formatted string with the current page number if configured
30
+ #
31
+ def self.format_page_number(toFormat, cur_page_nr)
32
+ return toFormat.sub(':num', cur_page_nr.to_s)
33
+ end #function format_page_number
34
+
35
+ # Static: Return a String version of the input which has a leading slash.
36
+ # If the input already has a forward slash in position zero, it will be
37
+ # returned unchanged.
38
+ #
39
+ # path - a String path
40
+ #
41
+ # Returns the path with a leading slash
42
+ def self.ensure_leading_slash(path)
43
+ path[0..0] == "/" ? path : "/#{path}"
44
+ end
45
+
46
+ # Static: Return a String version of the input without a leading slash.
47
+ #
48
+ # path - a String path
49
+ #
50
+ # Returns the input without the leading slash
51
+ def self.remove_leading_slash(path)
52
+ path[0..0] == "/" ? path[1..-1] : path
53
+ end
54
+
55
+ end
56
+
57
+ end # module PaginateV2
58
+ end # module Jekyll
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module PaginateV2
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-paginate-v2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Sverrir Sigmundarson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: An enhanced in-place replacement for the previously built-in jekyll-paginate
70
+ gem offering full backwards compatability as well as a slew of new frequently requested
71
+ features
72
+ email:
73
+ - jekyll@sverrirs.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.md
82
+ - jekyll-paginate-v2.gemspec
83
+ - lib/jekyll-paginate-v2.rb
84
+ - lib/jekyll-paginate-v2/defaults.rb
85
+ - lib/jekyll-paginate-v2/pagination.rb
86
+ - lib/jekyll-paginate-v2/paginator.rb
87
+ - lib/jekyll-paginate-v2/utils.rb
88
+ - lib/jekyll-paginate-v2/version.rb
89
+ homepage: https://github.com/sverrirs/jekyll-paginate-v2
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.4.8
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Pagination Generator for Jekyll 3
113
+ test_files: []