jekyll-paginate-v2 1.5.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,9 +19,9 @@ module Jekyll
19
19
  #
20
20
  # Returns nothing.
21
21
  def generate(site)
22
-
22
+ #begin
23
23
  # Retrieve and merge the pagination configuration from the site yml file
24
- default_config = DEFAULT.merge(site.config['pagination'] || {})
24
+ default_config = Jekyll::Utils.deep_merge_hashes(DEFAULT, site.config['pagination'] || {})
25
25
 
26
26
  # Compatibility Note: (REMOVE AFTER 2018-01-01)
27
27
  # If the legacy paginate logic is configured then read those values and merge with config
@@ -51,7 +51,7 @@ module Jekyll
51
51
 
52
52
  # Handle deprecation of settings and features
53
53
  if( !default_config['title_suffix' ].nil? )
54
- Jekyll.logger.warn "Pagination:", "The 'title_suffix' configuration has been deprecated. Please use 'title'. See https://github.com/sverrirs/jekyll-paginate-v2#site-configuration"
54
+ Jekyll::Deprecator.deprecation_message "Pagination: The 'title_suffix' configuration has been deprecated. Please use 'title'. See https://github.com/sverrirs/jekyll-paginate-v2/blob/master/README-GENERATOR.md#site-configuration"
55
55
  end
56
56
 
57
57
  Jekyll.logger.debug "Pagination:","Starting"
@@ -92,12 +92,7 @@ module Jekyll
92
92
  ################ 2 ####################
93
93
  # Create the proc that constructs the real-life site page
94
94
  # This is necessary to decouple the code from the Jekyll site object
95
- page_create_lambda = lambda do | template_path |
96
- template_full_path = File.join(site.source, template_path)
97
- template_dir = File.dirname(template_path)
98
-
99
- # Create the Jekyll page entry for the page
100
- newpage = PaginationPage.new( site, site.source, template_dir, template_full_path)
95
+ page_add_lambda = lambda do | newpage |
101
96
  site.pages << newpage # Add the page to the site so that it is generated correctly
102
97
  return newpage # Return the site to the calling code
103
98
  end
@@ -125,15 +120,21 @@ module Jekyll
125
120
 
126
121
  ################ 4 ####################
127
122
  # Now create and call the model with the real-life page creation proc and site data
128
- model = PaginationModel.new(logging_lambda, page_create_lambda, page_remove_lambda, collection_by_name_lambda)
123
+ model = PaginationModel.new(logging_lambda, page_add_lambda, page_remove_lambda, collection_by_name_lambda)
129
124
  if( default_config['legacy'] ) #(REMOVE AFTER 2018-01-01)
125
+ Jekyll.logger.warn "Pagination:", "You are running jekyll-paginate backwards compatible pagination logic. Please ignore all earlier warnings displayed related to the old jekyll-paginate gem."
130
126
  all_posts = site.site_payload['site']['posts'].reject { |post| post['hidden'] }
131
127
  model.run_compatability(default_config, all_pages, site_title, all_posts) #(REMOVE AFTER 2018-01-01)
132
128
  else
133
- model.run(default_config, all_pages, site_title)
129
+ count = model.run(default_config, all_pages, site_title)
130
+ Jekyll.logger.info "Pagination:", "Complete, processed #{count} pagination page(s)"
134
131
  end
135
132
 
136
- end
133
+ #rescue => ex
134
+ # puts ex.backtrace
135
+ # raise
136
+ #end
137
+ end # function generate
137
138
  end # class PaginationGenerator
138
139
 
139
140
  end # module PaginateV2
@@ -1,284 +1,293 @@
1
- module Jekyll
2
- module PaginateV2::Generator
3
-
4
- #
5
- # The main model for the pagination, handles the orchestration of the pagination and calling all the necessary bits and bobs needed :)
6
- #
7
- class PaginationModel
8
-
9
- @debug = false # is debug output enabled?
10
- @logging_lambda = nil # The lambda to use for logging
11
- @page_create_lambda = nil # The lambda used to create pages and add them to the site
12
- @page_remove_lambda = nil # Lambda to remove a page from the site.pages collection
13
- @collection_by_name_lambda = nil # Lambda to get all documents/posts in a particular collection (by name)
14
-
15
- # ctor
16
- def initialize(logging_lambda, page_create_lambda, page_remove_lambda, collection_by_name_lambda)
17
- @logging_lambda = logging_lambda
18
- @page_create_lambda = page_create_lambda
19
- @page_remove_lambda = page_remove_lambda
20
- @collection_by_name_lambda = collection_by_name_lambda
21
- end
22
-
23
-
24
- def run(default_config, site_pages, site_title)
25
- # By default if pagination is enabled we attempt to find all index.html pages in the site
26
- templates = self.discover_paginate_templates(site_pages)
27
- if( templates.size.to_i <= 0 )
28
- @logging_lambda.call "Is enabled, but I couldn't find any pagination page. Skipping pagination. "+
29
- "Pages must have 'paginate: enabled: true' in their front-matter for pagination to work.", "warn"
30
- return
31
- end
32
-
33
- # Now for each template page generate the paginator for it
34
- for template in templates
35
- # All pages that should be paginated need to include the pagination config element
36
- if template.data['pagination'].is_a?(Hash)
37
- template_config = default_config.merge(template.data['pagination'])
38
-
39
- # Handling deprecation of configuration values
40
- self._fix_deprecated_config_features(template_config)
41
-
42
- @debug = template_config['debug'] # Is debugging enabled on the page level
43
-
44
- self._debug_print_config_info(template_config, template.path)
45
-
46
- # Only paginate the template if it is explicitly enabled
47
- # requiring this makes the logic simpler as I don't need to determine which index pages
48
- # were generated automatically and which weren't
49
- if( template_config['enabled'] )
50
- if !@debug
51
- @logging_lambda.call "found page: "+template.path
52
- end
53
-
54
- # Request all documents in all collections that the user has requested
55
- all_posts = self.get_docs_in_collections(template_config['collection'])
56
-
57
- # Create the necessary indexes for the posts
58
- all_categories = PaginationIndexer.index_posts_by(all_posts, 'categories')
59
- all_categories['posts'] = all_posts; # Populate a category for all posts (this is here for backward compatibility, do not use this as it will be decommissioned 2018-01-01)
60
- # (this is a default and must not be used in the category system)
61
- all_tags = PaginationIndexer.index_posts_by(all_posts, 'tags')
62
- all_locales = PaginationIndexer.index_posts_by(all_posts, 'locale')
63
-
64
- # TODO: NOTE!!! This whole request for posts and indexing results could be cached to improve performance, leaving like this for now during testing
65
-
66
- # Now construct the pagination data for this template page
67
- #self.paginate(site, template, template_config, all_posts, all_tags, all_categories, all_locales)
68
- self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales)
69
- end
70
- end
71
- end #for
72
- end # function run
73
-
74
- #
75
- # This function is here to retain the old compatability logic with the jekyll-paginate gem
76
- # no changes should be made to this function and it should be retired and deleted after 2018-01-01
77
- # (REMOVE AFTER 2018-01-01)
78
- #
79
- def run_compatability(legacy_config, site_pages, site_title, all_posts)
80
-
81
- # Decomissioning error
82
- if( date = Date.strptime("20180101","%Y%m%d") <= Date.today )
83
- raise ArgumentError.new("Legacy jekyll-paginate configuration compatibility mode has expired. Please upgrade to jekyll-paginate-v2 configuration.")
84
- end
85
-
86
- # Two month warning or general notification
87
- if( date = Date.strptime("20171101","%Y%m%d") <= Date.today )
88
- @logging_lambda.call "Legacy pagination logic will stop working on Jan 1st 2018, update your configs before that time.", "warn"
89
- else
90
- @logging_lambda.call "Detected legacy jekyll-paginate logic being run. "+
91
- "Please update your configs to use the new pagination logic. This compatibility function "+
92
- "will stop working after Jan 1st 2018 and your site build will throw an error."
93
- end
94
-
95
- if template = CompatibilityUtils.template_page(site_pages, legacy_config['legacy_source'], legacy_config['permalink'])
96
- CompatibilityUtils.paginate(legacy_config, all_posts, template, @page_create_lambda)
97
- else
98
- @logging_lambda.call "Legacy pagination is enabled, but I couldn't find " +
99
- "an index.html page to use as the pagination page. Skipping pagination.", "warn"
100
- end
101
- end # function run_compatability (REMOVE AFTER 2018-01-01)
102
-
103
- # Returns the combination of all documents in the collections that are specified
104
- # raw_collection_names can either be a list of collections separated by a ',' or ' ' or a single string
105
- def get_docs_in_collections(raw_collection_names)
106
- if raw_collection_names.is_a?(String)
107
- collection_names = raw_collection_names.split(/;|,|\s/)
108
- else
109
- collection_names = raw_collection_names
110
- end
111
-
112
- docs = []
113
- # Now for each of the collections get the docs
114
- for coll_name in collection_names
115
- # Request all the documents for the collection in question, and join it with the total collection
116
- docs += @collection_by_name_lambda.call(coll_name.downcase.strip)
117
- end
118
-
119
- return docs
120
- end
121
-
122
- def _fix_deprecated_config_features(config)
123
- keys_to_delete = []
124
-
125
- # As of v1.5.1 the title_suffix is deprecated and 'title' should be used
126
- # but only if title has not been defined already!
127
- if( !config['title_suffix'].nil? )
128
- if( config['title'].nil? )
129
- config['title'] = ":title" + config['title_suffix'].to_s # Migrate the old key to title
130
- end
131
- keys_to_delete << "title_suffix" # Always remove the depricated key if found
132
- end
133
-
134
- # Delete the depricated keys
135
- config.delete_if{ |k,| keys_to_delete.include? k }
136
- end
137
-
138
- def _debug_print_config_info(config, page_path)
139
- r = 20
140
- f = "Pagination: ".rjust(20)
141
- # Debug print the config
142
- if @debug
143
- puts f + "----------------------------"
144
- puts f + "Page: "+page_path.to_s
145
- puts f + " Active configuration"
146
- puts f + " Enabled: ".ljust(r) + config['enabled'].to_s
147
- puts f + " Items per page: ".ljust(r) + config['per_page'].to_s
148
- puts f + " Permalink: ".ljust(r) + config['permalink'].to_s
149
- puts f + " Title: ".ljust(r) + config['title'].to_s
150
- puts f + " Limit: ".ljust(r) + config['limit'].to_s
151
- puts f + " Sort by: ".ljust(r) + config['sort_field'].to_s
152
- puts f + " Sort reverse: ".ljust(r) + config['sort_reverse'].to_s
153
-
154
- puts f + " Active Filters"
155
- puts f + " Collection: ".ljust(r) + config['collection'].to_s
156
- puts f + " Category: ".ljust(r) + (config['category'].nil? || config['category'] == "posts" ? "[Not set]" : config['category'].to_s)
157
- puts f + " Tag: ".ljust(r) + (config['tag'].nil? ? "[Not set]" : config['tag'].to_s)
158
- puts f + " Locale: ".ljust(r) + (config['locale'].nil? ? "[Not set]" : config['locale'].to_s)
159
-
160
- if config['legacy']
161
- puts f + " Legacy Paginate Code Enabled"
162
- puts f + " Legacy Paginate: ".ljust(r) + config['per_page'].to_s
163
- puts f + " Legacy Source: ".ljust(r) + config['legacy_source'].to_s
164
- puts f + " Legacy Path: ".ljust(r) + config['paginate_path'].to_s
165
- end
166
- end
167
- end
168
-
169
- def _debug_print_filtering_info(filter_name, before_count, after_count)
170
- # Debug print the config
171
- if @debug
172
- puts "Pagination: ".rjust(20) + " Filtering by: "+filter_name.to_s.ljust(9) + " " + before_count.to_s.rjust(3) + " => " + after_count.to_s
173
- end
174
- end
175
-
176
- #
177
- # Rolls through all the pages passed in and finds all pages that have pagination enabled on them.
178
- # These pages will be used as templates
179
- #
180
- # site_pages - All pages in the site
181
- #
182
- def discover_paginate_templates(site_pages)
183
- candidates = []
184
- site_pages.select do |page|
185
- # If the page has the enabled config set, supports any type of file name html or md
186
- if page.data['pagination'].is_a?(Hash) && page.data['pagination']['enabled']
187
- candidates << page
188
- end
189
- end
190
- return candidates
191
- end # function discover_paginate_templates
192
-
193
- # Paginates the blog's posts. Renders the index.html file into paginated
194
- # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
195
- # site-wide data.
196
- #
197
- # site - The Site.
198
- # template - The index.html Page that requires pagination.
199
- # config - The configuration settings that should be used
200
- #
201
- def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales)
202
- # By default paginate on all posts in the site
203
- using_posts = all_posts
204
-
205
- # Now start filtering out any posts that the user doesn't want included in the pagination
206
- before = using_posts.size.to_i
207
- using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'category', using_posts, all_categories)
208
- self._debug_print_filtering_info('Category', before, using_posts.size.to_i)
209
- before = using_posts.size.to_i
210
- using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'tag', using_posts, all_tags)
211
- self._debug_print_filtering_info('Tag', before, using_posts.size.to_i)
212
- before = using_posts.size.to_i
213
- using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'locale', using_posts, all_locales)
214
- self._debug_print_filtering_info('Locale', before, using_posts.size.to_i)
215
-
216
- # Apply sorting to the posts if configured, any field for the post is available for sorting
217
- if config['sort_field']
218
- sort_field = config['sort_field'].to_s
219
- using_posts.sort!{ |a,b| Utils.sort_values(Utils.sort_get_post_data(a.data, sort_field), Utils.sort_get_post_data(b.data, sort_field)) }
220
- if config['sort_reverse']
221
- using_posts.reverse!
222
- end
223
- end
224
-
225
- # Calculate the max number of pagination-pages based on the configured per page value
226
- total_pages = Utils.calculate_number_of_pages(using_posts, config['per_page'])
227
-
228
- # If a upper limit is set on the number of total pagination pages then impose that now
229
- if config['limit'] && config['limit'].to_i > 0 && config['limit'].to_i < total_pages
230
- total_pages = config['limit'].to_i
231
- end
232
-
233
- # Now for each pagination page create it and configure the ranges for the collection
234
- # This .pager member is a built in thing in Jekyll and defines the paginator implementation
235
- # Simpy override to use mine
236
- (1..total_pages).each do |cur_page_nr|
237
- pager = Paginator.new( config['per_page'], config['permalink'], using_posts, cur_page_nr, total_pages, template.url, template.path )
238
-
239
- # External Proc call to create the actual page for us (this is passed in when the pagination is run)
240
- newpage = @page_create_lambda.call( template.path )
241
- newpage.pager = pager
242
-
243
- # Force the newly created files to live under the same dir as the template plus the permalink structure
244
- new_path = Utils.paginate_path(template.url, template.path, cur_page_nr, config['permalink'])
245
- newpage.dir = new_path
246
-
247
- # Update the permalink for the paginated pages as well if the template had one
248
- if( template.data['permalink'] )
249
- newpage.data['permalink'] = new_path
250
- end
251
-
252
- # Transfer the title across to the new page
253
- if( !template.data['title'] )
254
- tmp_title = site_title
255
- else
256
- tmp_title = template.data['title']
257
- end
258
- # If the user specified a title suffix to be added then let's add that to all the pages except the first
259
- if( cur_page_nr > 1 && config.has_key?('title') )
260
- newpage.data['title'] = "#{Utils.format_page_title(Utils.format_page_number(config['title'], cur_page_nr), tmp_title)}"
261
- else
262
- newpage.data['title'] = tmp_title
263
- end
264
-
265
-
266
- # Signals that this page is automatically generated by the pagination logic
267
- # (we don't do this for the first page as it is there to mask the one we removed)
268
- if cur_page_nr > 1
269
- newpage.data['autogen'] = "jekyll-paginate-v2"
270
- end
271
-
272
- # Only request that the template page be removed from the output once
273
- # We actually create a dummy page for this actual page in the Jekyll output
274
- # so we don't need the original page anymore
275
- if cur_page_nr == 1
276
- @page_remove_lambda.call( template )
277
- end
278
- end
279
- end # function paginate
280
-
281
- end # class PaginationV2
282
-
283
- end # module PaginateV2
1
+ module Jekyll
2
+ module PaginateV2::Generator
3
+
4
+ #
5
+ # The main model for the pagination, handles the orchestration of the pagination and calling all the necessary bits and bobs needed :)
6
+ #
7
+ class PaginationModel
8
+
9
+ @debug = false # is debug output enabled?
10
+ @logging_lambda = nil # The lambda to use for logging
11
+ @page_add_lambda = nil # The lambda used to create pages and add them to the site
12
+ @page_remove_lambda = nil # Lambda to remove a page from the site.pages collection
13
+ @collection_by_name_lambda = nil # Lambda to get all documents/posts in a particular collection (by name)
14
+
15
+ # ctor
16
+ def initialize(logging_lambda, page_add_lambda, page_remove_lambda, collection_by_name_lambda)
17
+ @logging_lambda = logging_lambda
18
+ @page_add_lambda = page_add_lambda
19
+ @page_remove_lambda = page_remove_lambda
20
+ @collection_by_name_lambda = collection_by_name_lambda
21
+ end
22
+
23
+
24
+ def run(default_config, site_pages, site_title)
25
+ # By default if pagination is enabled we attempt to find all index.html pages in the site
26
+ templates = self.discover_paginate_templates(site_pages)
27
+ if( templates.size.to_i <= 0 )
28
+ @logging_lambda.call "Is enabled, but I couldn't find any pagination page. Skipping pagination. "+
29
+ "Pages must have 'pagination: enabled: true' in their front-matter for pagination to work.", "warn"
30
+ return
31
+ end
32
+
33
+ # Now for each template page generate the paginator for it
34
+ for template in templates
35
+ # All pages that should be paginated need to include the pagination config element
36
+ if template.data['pagination'].is_a?(Hash)
37
+ template_config = Jekyll::Utils.deep_merge_hashes(default_config, template.data['pagination'] || {})
38
+
39
+ # Handling deprecation of configuration values
40
+ self._fix_deprecated_config_features(template_config)
41
+
42
+ @debug = template_config['debug'] # Is debugging enabled on the page level
43
+
44
+ self._debug_print_config_info(template_config, template.path)
45
+
46
+ # Only paginate the template if it is explicitly enabled
47
+ # requiring this makes the logic simpler as I don't need to determine which index pages
48
+ # were generated automatically and which weren't
49
+ if( template_config['enabled'] )
50
+ if !@debug
51
+ @logging_lambda.call "found page: "+template.path, 'debug'
52
+ end
53
+
54
+ # Request all documents in all collections that the user has requested
55
+ all_posts = self.get_docs_in_collections(template_config['collection'])
56
+
57
+ # Create the necessary indexes for the posts
58
+ all_categories = PaginationIndexer.index_posts_by(all_posts, 'categories')
59
+ all_categories['posts'] = all_posts; # Populate a category for all posts (this is here for backward compatibility, do not use this as it will be decommissioned 2018-01-01)
60
+ # (this is a default and must not be used in the category system)
61
+ all_tags = PaginationIndexer.index_posts_by(all_posts, 'tags')
62
+ all_locales = PaginationIndexer.index_posts_by(all_posts, 'locale')
63
+
64
+ # TODO: NOTE!!! This whole request for posts and indexing results could be cached to improve performance, leaving like this for now during testing
65
+
66
+ # Now construct the pagination data for this template page
67
+ self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales)
68
+ end
69
+ end
70
+ end #for
71
+
72
+ # Return the total number of templates found
73
+ return templates.size.to_i
74
+ end # function run
75
+
76
+ #
77
+ # This function is here to retain the old compatability logic with the jekyll-paginate gem
78
+ # no changes should be made to this function and it should be retired and deleted after 2018-01-01
79
+ # (REMOVE AFTER 2018-01-01)
80
+ #
81
+ def run_compatability(legacy_config, site_pages, site_title, all_posts)
82
+
83
+ # Decomissioning error
84
+ if( date = Date.strptime("20180101","%Y%m%d") <= Date.today )
85
+ raise ArgumentError.new("Legacy jekyll-paginate configuration compatibility mode has expired. Please upgrade to jekyll-paginate-v2 configuration.")
86
+ end
87
+
88
+ # Two month warning or general notification
89
+ if( date = Date.strptime("20171101","%Y%m%d") <= Date.today )
90
+ @logging_lambda.call "Legacy pagination logic will stop working on Jan 1st 2018, update your configs before that time.", "warn"
91
+ else
92
+ @logging_lambda.call "Detected legacy jekyll-paginate logic running. "+
93
+ "Please update your configs to use the jekyll-paginate-v2 logic. This compatibility function "+
94
+ "will stop working after Jan 1st 2018 and your site build will throw an error.", "warn"
95
+ end
96
+
97
+ if template = CompatibilityUtils.template_page(site_pages, legacy_config['legacy_source'], legacy_config['permalink'])
98
+ CompatibilityUtils.paginate(legacy_config, all_posts, template, @page_add_lambda)
99
+ else
100
+ @logging_lambda.call "Legacy pagination is enabled, but I couldn't find " +
101
+ "an index.html page to use as the pagination page. Skipping pagination.", "warn"
102
+ end
103
+ end # function run_compatability (REMOVE AFTER 2018-01-01)
104
+
105
+ # Returns the combination of all documents in the collections that are specified
106
+ # raw_collection_names can either be a list of collections separated by a ',' or ' ' or a single string
107
+ def get_docs_in_collections(raw_collection_names)
108
+ if raw_collection_names.is_a?(String)
109
+ collection_names = raw_collection_names.split(/;|,|\s/)
110
+ else
111
+ collection_names = raw_collection_names
112
+ end
113
+
114
+ docs = []
115
+ # Now for each of the collections get the docs
116
+ for coll_name in collection_names
117
+ # Request all the documents for the collection in question, and join it with the total collection
118
+ docs += @collection_by_name_lambda.call(coll_name.downcase.strip)
119
+ end
120
+
121
+ return docs
122
+ end
123
+
124
+ def _fix_deprecated_config_features(config)
125
+ keys_to_delete = []
126
+
127
+ # As of v1.5.1 the title_suffix is deprecated and 'title' should be used
128
+ # but only if title has not been defined already!
129
+ if( !config['title_suffix'].nil? )
130
+ if( config['title'].nil? )
131
+ config['title'] = ":title" + config['title_suffix'].to_s # Migrate the old key to title
132
+ end
133
+ keys_to_delete << "title_suffix" # Always remove the depricated key if found
134
+ end
135
+
136
+ # Delete the depricated keys
137
+ config.delete_if{ |k,| keys_to_delete.include? k }
138
+ end
139
+
140
+ def _debug_print_config_info(config, page_path)
141
+ r = 20
142
+ f = "Pagination: ".rjust(20)
143
+ # Debug print the config
144
+ if @debug
145
+ puts f + "----------------------------"
146
+ puts f + "Page: "+page_path.to_s
147
+ puts f + " Active configuration"
148
+ puts f + " Enabled: ".ljust(r) + config['enabled'].to_s
149
+ puts f + " Items per page: ".ljust(r) + config['per_page'].to_s
150
+ puts f + " Permalink: ".ljust(r) + config['permalink'].to_s
151
+ puts f + " Title: ".ljust(r) + config['title'].to_s
152
+ puts f + " Limit: ".ljust(r) + config['limit'].to_s
153
+ puts f + " Sort by: ".ljust(r) + config['sort_field'].to_s
154
+ puts f + " Sort reverse: ".ljust(r) + config['sort_reverse'].to_s
155
+
156
+ puts f + " Active Filters"
157
+ puts f + " Collection: ".ljust(r) + config['collection'].to_s
158
+ puts f + " Category: ".ljust(r) + (config['category'].nil? || config['category'] == "posts" ? "[Not set]" : config['category'].to_s)
159
+ puts f + " Tag: ".ljust(r) + (config['tag'].nil? ? "[Not set]" : config['tag'].to_s)
160
+ puts f + " Locale: ".ljust(r) + (config['locale'].nil? ? "[Not set]" : config['locale'].to_s)
161
+
162
+ if config['legacy']
163
+ puts f + " Legacy Paginate Code Enabled"
164
+ puts f + " Legacy Paginate: ".ljust(r) + config['per_page'].to_s
165
+ puts f + " Legacy Source: ".ljust(r) + config['legacy_source'].to_s
166
+ puts f + " Legacy Path: ".ljust(r) + config['paginate_path'].to_s
167
+ end
168
+ end
169
+ end
170
+
171
+ def _debug_print_filtering_info(filter_name, before_count, after_count)
172
+ # Debug print the config
173
+ if @debug
174
+ puts "Pagination: ".rjust(20) + " Filtering by: "+filter_name.to_s.ljust(9) + " " + before_count.to_s.rjust(3) + " => " + after_count.to_s
175
+ end
176
+ end
177
+
178
+ #
179
+ # Rolls through all the pages passed in and finds all pages that have pagination enabled on them.
180
+ # These pages will be used as templates
181
+ #
182
+ # site_pages - All pages in the site
183
+ #
184
+ def discover_paginate_templates(site_pages)
185
+ candidates = []
186
+ site_pages.select do |page|
187
+ # If the page has the enabled config set, supports any type of file name html or md
188
+ if page.data['pagination'].is_a?(Hash) && page.data['pagination']['enabled']
189
+ candidates << page
190
+ end
191
+ end
192
+ return candidates
193
+ end # function discover_paginate_templates
194
+
195
+ # Paginates the blog's posts. Renders the index.html file into paginated
196
+ # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
197
+ # site-wide data.
198
+ #
199
+ # site - The Site.
200
+ # template - The index.html Page that requires pagination.
201
+ # config - The configuration settings that should be used
202
+ #
203
+ def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales)
204
+ # By default paginate on all posts in the site
205
+ using_posts = all_posts
206
+
207
+ # Now start filtering out any posts that the user doesn't want included in the pagination
208
+ before = using_posts.size.to_i
209
+ using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'category', using_posts, all_categories)
210
+ self._debug_print_filtering_info('Category', before, using_posts.size.to_i)
211
+ before = using_posts.size.to_i
212
+ using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'tag', using_posts, all_tags)
213
+ self._debug_print_filtering_info('Tag', before, using_posts.size.to_i)
214
+ before = using_posts.size.to_i
215
+ using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'locale', using_posts, all_locales)
216
+ self._debug_print_filtering_info('Locale', before, using_posts.size.to_i)
217
+
218
+ # Apply sorting to the posts if configured, any field for the post is available for sorting
219
+ if config['sort_field']
220
+ sort_field = config['sort_field'].to_s
221
+ using_posts.sort!{ |a,b| Utils.sort_values(Utils.sort_get_post_data(a.data, sort_field), Utils.sort_get_post_data(b.data, sort_field)) }
222
+ if config['sort_reverse']
223
+ using_posts.reverse!
224
+ end
225
+ end
226
+
227
+ # Calculate the max number of pagination-pages based on the configured per page value
228
+ total_pages = Utils.calculate_number_of_pages(using_posts, config['per_page'])
229
+
230
+ # If a upper limit is set on the number of total pagination pages then impose that now
231
+ if config['limit'] && config['limit'].to_i > 0 && config['limit'].to_i < total_pages
232
+ total_pages = config['limit'].to_i
233
+ end
234
+
235
+ #### BEFORE STARTING REMOVE THE TEMPLATE PAGE FROM THE SITE LIST!
236
+ @page_remove_lambda.call( template )
237
+
238
+ # Now for each pagination page create it and configure the ranges for the collection
239
+ # This .pager member is a built in thing in Jekyll and defines the paginator implementation
240
+ # Simpy override to use mine
241
+ (1..total_pages).each do |cur_page_nr|
242
+
243
+ # 1. Create the in-memory page
244
+ # External Proc call to create the actual page for us (this is passed in when the pagination is run)
245
+ newpage = PaginationPage.new( template, true )
246
+
247
+ # 2. Create the url for the in-memory page (calc permalink etc), construct the title, set all page.data values needed
248
+ paginated_page_url = config['permalink']
249
+ first_index_page_url = ""
250
+ if template.data['permalink']
251
+ first_index_page_url = template.data['permalink']
252
+ else
253
+ first_index_page_url = template.dir
254
+ end
255
+ paginated_page_url = File.join(first_index_page_url, paginated_page_url)
256
+
257
+ # 3. Create the pager logic for this page, pass in the prev and next page numbers, assign pager to in-memory page
258
+ newpage.pager = Paginator.new( config['per_page'], first_index_page_url, paginated_page_url, using_posts, cur_page_nr, total_pages)
259
+
260
+ # Create the url for the new page, make sure we prepend any permalinks that are defined in the template page before
261
+ newpage.set_url(File.join(newpage.pager.page_path, 'index.html'))
262
+ if( template.data['permalink'] )
263
+ newpage.data['permalink'] = newpage.pager.page_path
264
+ end
265
+
266
+ # Transfer the title across to the new page
267
+ if( !template.data['title'] )
268
+ tmp_title = site_title
269
+ else
270
+ tmp_title = template.data['title']
271
+ end
272
+ # If the user specified a title suffix to be added then let's add that to all the pages except the first
273
+ if( cur_page_nr > 1 && config.has_key?('title') )
274
+ newpage.data['title'] = "#{Utils.format_page_title(config['title'], tmp_title, cur_page_nr, total_pages)}"
275
+ else
276
+ newpage.data['title'] = tmp_title
277
+ end
278
+
279
+ # Signals that this page is automatically generated by the pagination logic
280
+ # (we don't do this for the first page as it is there to mask the one we removed)
281
+ if cur_page_nr > 1
282
+ newpage.data['autogen'] = "jekyll-paginate-v2"
283
+ end
284
+
285
+ # Add the page to the site
286
+ @page_add_lambda.call( newpage )
287
+ end
288
+ end # function paginate
289
+
290
+ end # class PaginationV2
291
+
292
+ end # module PaginateV2
284
293
  end # module Jekyll