jekyll-paginate-v2 1.5.0 → 1.5.1
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.
- checksums.yaml +4 -4
- data/README.md +41 -43
- data/Rakefile +2 -2
- data/jekyll-paginate-v2.gemspec +3 -1
- data/lib/jekyll-paginate-v2.rb +12 -8
- data/lib/jekyll-paginate-v2/autopages/autoTagPages.rb +66 -0
- data/lib/jekyll-paginate-v2/autopages/defaults.rb +26 -0
- data/lib/jekyll-paginate-v2/autopages/utils.rb +21 -0
- data/lib/jekyll-paginate-v2/{compatibilityUtils.rb → generator/compatibilityUtils.rb} +4 -2
- data/lib/jekyll-paginate-v2/{defaults.rb → generator/defaults.rb} +3 -2
- data/lib/jekyll-paginate-v2/{paginationGenerator.rb → generator/paginationGenerator.rb} +14 -9
- data/lib/jekyll-paginate-v2/generator/paginationIndexer.rb +93 -0
- data/lib/jekyll-paginate-v2/{paginationModel.rb → generator/paginationModel.rb} +99 -120
- data/lib/jekyll-paginate-v2/{paginationPage.rb → generator/paginationPage.rb} +1 -1
- data/lib/jekyll-paginate-v2/{paginator.rb → generator/paginator.rb} +1 -1
- data/lib/jekyll-paginate-v2/{utils.rb → generator/utils.rb} +11 -4
- data/lib/jekyll-paginate-v2/version.rb +4 -4
- data/spec/{defaults_spec.rb → generator/defaults_spec.rb} +5 -3
- data/spec/generator/paginationPage_spec.rb +12 -0
- data/spec/{paginator_spec.rb → generator/paginator_spec.rb} +21 -18
- data/spec/generator/utils_spec.rb +90 -0
- data/spec/spec_helper.rb +8 -30
- metadata +41 -87
- data/examples/01-typicalblog/Gemfile +0 -28
- data/examples/01-typicalblog/README.md +0 -91
- data/examples/01-typicalblog/_config.yml +0 -51
- data/examples/01-typicalblog/_includes/header.html +0 -31
- data/examples/01-typicalblog/_layouts/home.html +0 -52
- data/examples/01-typicalblog/_posts/2016-11-20-geography-of-minneapolis.md +0 -29
- data/examples/01-typicalblog/_posts/2016-11-21-sailing-summer-olympics-1988.md +0 -15
- data/examples/01-typicalblog/_posts/2016-11-22-rotary-engine.md +0 -27
- data/examples/01-typicalblog/_posts/2016-11-23-luft-fahrzeug-gesellschaft.md +0 -27
- data/examples/01-typicalblog/_posts/2016-11-24-narcisse-snake-pits.md +0 -18
- data/examples/01-typicalblog/_posts/2016-11-25-tele7jours.md +0 -43
- data/examples/01-typicalblog/_posts/2016-11-26-columbia-river.md +0 -41
- data/examples/01-typicalblog/_posts/2016-11-27-welcome-to-jekyll-paginate-v2.md +0 -33
- data/examples/01-typicalblog/about.md +0 -15
- data/examples/01-typicalblog/index.html +0 -8
- data/examples/02-category/Gemfile +0 -28
- data/examples/02-category/README.md +0 -119
- data/examples/02-category/_config.yml +0 -47
- data/examples/02-category/_includes/header.html +0 -31
- data/examples/02-category/_layouts/home.html +0 -52
- data/examples/02-category/_posts/2016-10-27-welcome-to-jekyll-paginate-v2.md +0 -32
- data/examples/02-category/about.md +0 -15
- data/examples/02-category/cars/_posts/2016-10-18-Porsche-918-Spyder.md +0 -13
- data/examples/02-category/cars/_posts/2016-10-19-Porsche-964.md +0 -12
- data/examples/02-category/cars/_posts/2016-10-20-porsche-911-gt3.md +0 -13
- data/examples/02-category/cars/_posts/2016-10-21-porsche-911.md +0 -13
- data/examples/02-category/cars/_posts/2016-10-22-porsche-962.md +0 -18
- data/examples/02-category/cars/_posts/2016-10-23-Toyota-GT-One.md +0 -20
- data/examples/02-category/cars/_posts/2016-10-24-Mercedes-Benz-CLK-GTR.md +0 -40
- data/examples/02-category/cars/_posts/2016-10-25-rolls-royce-silver-ghost.md +0 -31
- data/examples/02-category/categories/byname.md +0 -11
- data/examples/02-category/categories/porsche.md +0 -10
- data/examples/02-category/index.md +0 -13
- data/examples/02-category/toyota/index.md +0 -7
- data/examples/03-tags/Gemfile +0 -28
- data/examples/03-tags/README.md +0 -67
- data/examples/03-tags/_biography/all/born-to-run.md +0 -26
- data/examples/03-tags/_biography/all/forty-autumns.md +0 -26
- data/examples/03-tags/_biography/all/life-in-questions-a.md +0 -27
- data/examples/03-tags/_biography/all/not-dead-yet.md +0 -24
- data/examples/03-tags/_biography/all/princess-diarist-the.md +0 -26
- data/examples/03-tags/_biography/all/when-breath-becomes-air.md +0 -24
- data/examples/03-tags/_biography/biography-musicians.md +0 -13
- data/examples/03-tags/_biography/index.md +0 -12
- data/examples/03-tags/_config.yml +0 -57
- data/examples/03-tags/_fantasy/all/harry-potter-deathly-hallows.md +0 -24
- data/examples/03-tags/_fantasy/all/harry-potter-philosophers-stone.md +0 -24
- data/examples/03-tags/_fantasy/all/mistborn-trilogy.md +0 -24
- data/examples/03-tags/_fantasy/all/ready-player-one.md +0 -24
- data/examples/03-tags/_fantasy/all/sword-of-destiny.md +0 -24
- data/examples/03-tags/_fantasy/all/terry-pratchet-diary-2017.md +0 -24
- data/examples/03-tags/_includes/header.html +0 -31
- data/examples/03-tags/_layouts/home.html +0 -51
- data/examples/03-tags/_layouts/post.html +0 -20
- data/examples/03-tags/_romance/all/breath-of-snow-and-ashes-a.md +0 -25
- data/examples/03-tags/_romance/all/dressmaker-the.md +0 -24
- data/examples/03-tags/_romance/all/fiery-cross-the.md +0 -26
- data/examples/03-tags/_romance/all/it-ends-with-us.md +0 -28
- data/examples/03-tags/_romance/all/outlander-novel.md +0 -34
- data/examples/03-tags/_romance/all/virgins-outlander-short-story.md +0 -26
- data/examples/03-tags/_romance/romance-historical.md +0 -14
- data/examples/03-tags/blog/_posts/2016-09-30-welcome-to-jekyll-paginate-v2.md +0 -32
- data/examples/03-tags/byisbn.md +0 -14
- data/examples/03-tags/index.md +0 -19
- data/examples/03-tags/tags/contemporary.md +0 -11
- data/examples/03-tags/tags/fantasy.md +0 -13
- data/examples/03-tags/tags/sci-fi.md +0 -16
- data/examples/README.md +0 -23
- data/examples/img/01-example-screenshot-main.png +0 -0
- data/examples/img/02-example-screenshot-main.png +0 -0
- data/examples/img/03-example-screenshot-main.png +0 -0
- data/spec/utils_spec.rb +0 -65
@@ -0,0 +1,93 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module PaginateV2::Generator
|
3
|
+
|
4
|
+
#
|
5
|
+
# Performs indexing of the posts or collection documents
|
6
|
+
# as well as filtering said collections when requested by the defined filters.
|
7
|
+
class PaginationIndexer
|
8
|
+
#
|
9
|
+
# Create a hash index for all post based on a key in the post.data table
|
10
|
+
#
|
11
|
+
def self.index_posts_by(all_posts, index_key)
|
12
|
+
return nil if all_posts.nil?
|
13
|
+
return all_posts if index_key.nil?
|
14
|
+
index = {}
|
15
|
+
for post in all_posts
|
16
|
+
next if post.data.nil?
|
17
|
+
next if !post.data.has_key?(index_key)
|
18
|
+
next if post.data[index_key].nil?
|
19
|
+
next if post.data[index_key].size <= 0
|
20
|
+
next if post.data[index_key].to_s.strip.length == 0
|
21
|
+
|
22
|
+
# Only tags and categories come as premade arrays, locale does not, so convert any data
|
23
|
+
# elements that are strings into arrays
|
24
|
+
post_data = post.data[index_key]
|
25
|
+
if post_data.is_a?(String)
|
26
|
+
post_data = post_data.split(/;|,|\s/)
|
27
|
+
end
|
28
|
+
|
29
|
+
for key in post_data
|
30
|
+
key = key.downcase.strip
|
31
|
+
# If the key is a delimetered list of values
|
32
|
+
# (meaning the user didn't use an array but a string with commas)
|
33
|
+
for k_split in key.split(/;|,/)
|
34
|
+
k_split = k_split.downcase.strip #Clean whitespace and junk
|
35
|
+
if !index.has_key?(k_split)
|
36
|
+
index[k_split.to_s] = []
|
37
|
+
end
|
38
|
+
index[k_split.to_s] << post
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
return index
|
43
|
+
end # function index_posts_by
|
44
|
+
|
45
|
+
#
|
46
|
+
# Creates an intersection (only returns common elements)
|
47
|
+
# between multiple arrays
|
48
|
+
#
|
49
|
+
def self.intersect_arrays(first, *rest)
|
50
|
+
return nil if first.nil?
|
51
|
+
return nil if rest.nil?
|
52
|
+
|
53
|
+
intersect = first
|
54
|
+
rest.each do |item|
|
55
|
+
return [] if item.nil?
|
56
|
+
intersect = intersect & item
|
57
|
+
end
|
58
|
+
return intersect
|
59
|
+
end #function intersect_arrays
|
60
|
+
|
61
|
+
#
|
62
|
+
# Filters posts based on a keyed source_posts hash of indexed posts and performs a intersection of
|
63
|
+
# the two sets. Returns only posts that are common between all collections
|
64
|
+
#
|
65
|
+
def self.read_config_value_and_filter_posts(config, config_key, posts, source_posts)
|
66
|
+
return nil if posts.nil?
|
67
|
+
return nil if source_posts.nil? # If the source is empty then simply don't do anything
|
68
|
+
return posts if config.nil?
|
69
|
+
return posts if !config.has_key?(config_key)
|
70
|
+
return posts if config[config_key].nil?
|
71
|
+
|
72
|
+
# Get the filter values from the config (this is the cat/tag/locale values that should be filtered on)
|
73
|
+
config_value = config[config_key]
|
74
|
+
|
75
|
+
# If we're dealing with a delimitered string instead of an array then let's be forgiving
|
76
|
+
if( config_value.is_a?(String))
|
77
|
+
config_value = config_value.split(/;|,/)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Now for all filter values for the config key, let's remove all items from the posts that
|
81
|
+
# aren't common for all collections that the user wants to filter on
|
82
|
+
for key in config_value
|
83
|
+
key = key.downcase.strip
|
84
|
+
posts = PaginationIndexer.intersect_arrays(posts, source_posts[key])
|
85
|
+
end
|
86
|
+
|
87
|
+
# The fully filtered final post list
|
88
|
+
return posts
|
89
|
+
end #function read_config_value_and_filter_posts
|
90
|
+
end #class PaginationIndexer
|
91
|
+
|
92
|
+
end #module PaginateV2
|
93
|
+
end #module Jekyll
|
@@ -1,13 +1,31 @@
|
|
1
1
|
module Jekyll
|
2
|
-
module PaginateV2
|
2
|
+
module PaginateV2::Generator
|
3
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
|
+
#
|
4
7
|
class PaginationModel
|
5
8
|
|
6
|
-
|
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)
|
7
25
|
# By default if pagination is enabled we attempt to find all index.html pages in the site
|
8
26
|
templates = self.discover_paginate_templates(site_pages)
|
9
27
|
if( templates.size.to_i <= 0 )
|
10
|
-
logging_lambda.call "Is enabled, but I couldn't find any pagination page. Skipping pagination. "+
|
28
|
+
@logging_lambda.call "Is enabled, but I couldn't find any pagination page. Skipping pagination. "+
|
11
29
|
"Pages must have 'paginate: enabled: true' in their front-matter for pagination to work.", "warn"
|
12
30
|
return
|
13
31
|
end
|
@@ -17,28 +35,37 @@ module Jekyll
|
|
17
35
|
# All pages that should be paginated need to include the pagination config element
|
18
36
|
if template.data['pagination'].is_a?(Hash)
|
19
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)
|
20
45
|
|
21
46
|
# Only paginate the template if it is explicitly enabled
|
22
47
|
# requiring this makes the logic simpler as I don't need to determine which index pages
|
23
48
|
# were generated automatically and which weren't
|
24
49
|
if( template_config['enabled'] )
|
25
|
-
|
50
|
+
if !@debug
|
51
|
+
@logging_lambda.call "found page: "+template.path
|
52
|
+
end
|
26
53
|
|
27
54
|
# Request all documents in all collections that the user has requested
|
28
|
-
all_posts = self.get_docs_in_collections(template_config['collection']
|
55
|
+
all_posts = self.get_docs_in_collections(template_config['collection'])
|
29
56
|
|
30
57
|
# Create the necessary indexes for the posts
|
31
|
-
all_categories =
|
58
|
+
all_categories = PaginationIndexer.index_posts_by(all_posts, 'categories')
|
32
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)
|
33
60
|
# (this is a default and must not be used in the category system)
|
34
|
-
all_tags =
|
35
|
-
all_locales =
|
61
|
+
all_tags = PaginationIndexer.index_posts_by(all_posts, 'tags')
|
62
|
+
all_locales = PaginationIndexer.index_posts_by(all_posts, 'locale')
|
36
63
|
|
37
64
|
# TODO: NOTE!!! This whole request for posts and indexing results could be cached to improve performance, leaving like this for now during testing
|
38
65
|
|
39
66
|
# Now construct the pagination data for this template page
|
40
67
|
#self.paginate(site, template, template_config, all_posts, all_tags, all_categories, all_locales)
|
41
|
-
self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales
|
68
|
+
self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales)
|
42
69
|
end
|
43
70
|
end
|
44
71
|
end #for
|
@@ -49,7 +76,7 @@ module Jekyll
|
|
49
76
|
# no changes should be made to this function and it should be retired and deleted after 2018-01-01
|
50
77
|
# (REMOVE AFTER 2018-01-01)
|
51
78
|
#
|
52
|
-
def run_compatability(legacy_config, site_pages, site_title, all_posts
|
79
|
+
def run_compatability(legacy_config, site_pages, site_title, all_posts)
|
53
80
|
|
54
81
|
# Decomissioning error
|
55
82
|
if( date = Date.strptime("20180101","%Y%m%d") <= Date.today )
|
@@ -58,24 +85,24 @@ module Jekyll
|
|
58
85
|
|
59
86
|
# Two month warning or general notification
|
60
87
|
if( date = Date.strptime("20171101","%Y%m%d") <= Date.today )
|
61
|
-
logging_lambda.call "Legacy pagination logic will stop working on Jan 1st 2018, update your configs before that time.", "warn"
|
88
|
+
@logging_lambda.call "Legacy pagination logic will stop working on Jan 1st 2018, update your configs before that time.", "warn"
|
62
89
|
else
|
63
|
-
logging_lambda.call "Detected legacy jekyll-paginate logic being run. "+
|
90
|
+
@logging_lambda.call "Detected legacy jekyll-paginate logic being run. "+
|
64
91
|
"Please update your configs to use the new pagination logic. This compatibility function "+
|
65
92
|
"will stop working after Jan 1st 2018 and your site build will throw an error."
|
66
93
|
end
|
67
94
|
|
68
95
|
if template = CompatibilityUtils.template_page(site_pages, legacy_config['legacy_source'], legacy_config['permalink'])
|
69
|
-
CompatibilityUtils.paginate(legacy_config, all_posts, template, page_create_lambda
|
96
|
+
CompatibilityUtils.paginate(legacy_config, all_posts, template, @page_create_lambda)
|
70
97
|
else
|
71
|
-
logging_lambda.call "Legacy pagination is enabled, but I couldn't find " +
|
98
|
+
@logging_lambda.call "Legacy pagination is enabled, but I couldn't find " +
|
72
99
|
"an index.html page to use as the pagination page. Skipping pagination.", "warn"
|
73
100
|
end
|
74
101
|
end # function run_compatability (REMOVE AFTER 2018-01-01)
|
75
102
|
|
76
103
|
# Returns the combination of all documents in the collections that are specified
|
77
104
|
# raw_collection_names can either be a list of collections separated by a ',' or ' ' or a single string
|
78
|
-
def get_docs_in_collections(raw_collection_names
|
105
|
+
def get_docs_in_collections(raw_collection_names)
|
79
106
|
if raw_collection_names.is_a?(String)
|
80
107
|
collection_names = raw_collection_names.split(/;|,|\s/)
|
81
108
|
else
|
@@ -86,11 +113,58 @@ module Jekyll
|
|
86
113
|
# Now for each of the collections get the docs
|
87
114
|
for coll_name in collection_names
|
88
115
|
# Request all the documents for the collection in question, and join it with the total collection
|
89
|
-
docs += collection_by_name_lambda.call(coll_name.downcase.strip)
|
116
|
+
docs += @collection_by_name_lambda.call(coll_name.downcase.strip)
|
90
117
|
end
|
91
118
|
|
92
119
|
return docs
|
93
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
|
94
168
|
|
95
169
|
#
|
96
170
|
# Rolls through all the pages passed in and finds all pages that have pagination enabled on them.
|
@@ -108,89 +182,6 @@ module Jekyll
|
|
108
182
|
end
|
109
183
|
return candidates
|
110
184
|
end # function discover_paginate_templates
|
111
|
-
|
112
|
-
#
|
113
|
-
# Create a hash index for all post based on a key in the post.data table
|
114
|
-
#
|
115
|
-
def index_posts_by(all_posts, index_key)
|
116
|
-
return nil if all_posts.nil?
|
117
|
-
return all_posts if index_key.nil?
|
118
|
-
index = {}
|
119
|
-
for post in all_posts
|
120
|
-
next if post.data.nil?
|
121
|
-
next if !post.data.has_key?(index_key)
|
122
|
-
next if post.data[index_key].nil?
|
123
|
-
next if post.data[index_key].size <= 0
|
124
|
-
next if post.data[index_key].to_s.strip.length == 0
|
125
|
-
|
126
|
-
# Only tags and categories come as premade arrays, locale does not, so convert any data
|
127
|
-
# elements that are strings into arrays
|
128
|
-
post_data = post.data[index_key]
|
129
|
-
if post_data.is_a?(String)
|
130
|
-
post_data = post_data.split(/;|,|\s/)
|
131
|
-
end
|
132
|
-
|
133
|
-
for key in post_data
|
134
|
-
key = key.downcase.strip
|
135
|
-
# If the key is a delimetered list of values
|
136
|
-
# (meaning the user didn't use an array but a string with commas)
|
137
|
-
for k_split in key.split(/;|,/)
|
138
|
-
k_split = k_split.downcase.strip #Clean whitespace and junk
|
139
|
-
if !index.has_key?(k_split)
|
140
|
-
index[k_split.to_s] = []
|
141
|
-
end
|
142
|
-
index[k_split.to_s] << post
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
return index
|
147
|
-
end # function index_posts_by
|
148
|
-
|
149
|
-
#
|
150
|
-
# Creates an intersection (only returns common elements)
|
151
|
-
# between multiple arrays
|
152
|
-
#
|
153
|
-
def intersect_arrays(first, *rest)
|
154
|
-
return nil if first.nil?
|
155
|
-
return nil if rest.nil?
|
156
|
-
|
157
|
-
intersect = first
|
158
|
-
rest.each do |item|
|
159
|
-
return [] if item.nil?
|
160
|
-
intersect = intersect & item
|
161
|
-
end
|
162
|
-
return intersect
|
163
|
-
end #function intersect_arrays
|
164
|
-
|
165
|
-
#
|
166
|
-
# Filters posts based on a keyed source_posts hash of indexed posts and performs a intersection of
|
167
|
-
# the two sets. Returns only posts that are common between all collections
|
168
|
-
#
|
169
|
-
def read_config_value_and_filter_posts(config, config_key, posts, source_posts)
|
170
|
-
return nil if posts.nil?
|
171
|
-
return nil if source_posts.nil? # If the source is empty then simply don't do anything
|
172
|
-
return posts if config.nil?
|
173
|
-
return posts if !config.has_key?(config_key)
|
174
|
-
return posts if config[config_key].nil?
|
175
|
-
|
176
|
-
# Get the filter values from the config (this is the cat/tag/locale values that should be filtered on)
|
177
|
-
config_value = config[config_key]
|
178
|
-
|
179
|
-
# If we're dealing with a delimitered string instead of an array then let's be forgiving
|
180
|
-
if( config_value.is_a?(String))
|
181
|
-
config_value = config_value.split(/;|,/)
|
182
|
-
end
|
183
|
-
|
184
|
-
# Now for all filter values for the config key, let's remove all items from the posts that
|
185
|
-
# aren't common for all collections that the user wants to filter on
|
186
|
-
for key in config_value
|
187
|
-
key = key.downcase.strip
|
188
|
-
posts = self.intersect_arrays(posts, source_posts[key])
|
189
|
-
end
|
190
|
-
|
191
|
-
# The fully filtered final post list
|
192
|
-
return posts
|
193
|
-
end #function read_config_value_and_filter_posts
|
194
185
|
|
195
186
|
# Paginates the blog's posts. Renders the index.html file into paginated
|
196
187
|
# directories, e.g.: page2/index.html, page3/index.html, etc and adds more
|
@@ -200,19 +191,19 @@ module Jekyll
|
|
200
191
|
# template - The index.html Page that requires pagination.
|
201
192
|
# config - The configuration settings that should be used
|
202
193
|
#
|
203
|
-
def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales
|
194
|
+
def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales)
|
204
195
|
# By default paginate on all posts in the site
|
205
196
|
using_posts = all_posts
|
206
197
|
|
207
198
|
# Now start filtering out any posts that the user doesn't want included in the pagination
|
208
|
-
using_posts =
|
209
|
-
using_posts =
|
210
|
-
using_posts =
|
199
|
+
using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'category', using_posts, all_categories)
|
200
|
+
using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'tag', using_posts, all_tags)
|
201
|
+
using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'locale', using_posts, all_locales)
|
211
202
|
|
212
203
|
# Apply sorting to the posts if configured, any field for the post is available for sorting
|
213
204
|
if config['sort_field']
|
214
205
|
sort_field = config['sort_field'].to_s
|
215
|
-
using_posts.sort!{ |a,b| Utils.sort_values(Utils.sort_get_post_data(a, sort_field), Utils.sort_get_post_data(b, sort_field)) }
|
206
|
+
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)) }
|
216
207
|
if config['sort_reverse']
|
217
208
|
using_posts.reverse!
|
218
209
|
end
|
@@ -230,18 +221,10 @@ module Jekyll
|
|
230
221
|
# This .pager member is a built in thing in Jekyll and defines the paginator implementation
|
231
222
|
# Simpy override to use mine
|
232
223
|
(1..total_pages).each do |cur_page_nr|
|
233
|
-
logging_lambda.call "-------------------------------", 'debug'
|
234
|
-
logging_lambda.call "Template.name: "+ template.name, 'debug'
|
235
|
-
logging_lambda.call "Template.url: "+ template.url, 'debug'
|
236
|
-
logging_lambda.call "Template.dir: "+ template.dir, 'debug'
|
237
|
-
logging_lambda.call "Template.basename: "+ template.basename, 'debug'
|
238
|
-
logging_lambda.call "Template.path: "+ template.path, 'debug'
|
239
|
-
logging_lambda.call "Template.ext: "+ template.ext, 'debug'
|
240
|
-
|
241
224
|
pager = Paginator.new( config['per_page'], config['permalink'], using_posts, cur_page_nr, total_pages, template.url, template.path )
|
242
225
|
|
243
226
|
# External Proc call to create the actual page for us (this is passed in when the pagination is run)
|
244
|
-
newpage = page_create_lambda.call( template.path )
|
227
|
+
newpage = @page_create_lambda.call( template.path )
|
245
228
|
newpage.pager = pager
|
246
229
|
|
247
230
|
# Force the newly created files to live under the same dir as the template plus the permalink structure
|
@@ -260,8 +243,8 @@ module Jekyll
|
|
260
243
|
tmp_title = template.data['title']
|
261
244
|
end
|
262
245
|
# If the user specified a title suffix to be added then let's add that to all the pages except the first
|
263
|
-
if( cur_page_nr > 1 && config.has_key?('
|
264
|
-
newpage.data['title'] = "#{
|
246
|
+
if( cur_page_nr > 1 && config.has_key?('title') )
|
247
|
+
newpage.data['title'] = "#{Utils.format_page_title(Utils.format_page_number(config['title'], cur_page_nr), tmp_title)}"
|
265
248
|
else
|
266
249
|
newpage.data['title'] = tmp_title
|
267
250
|
end
|
@@ -273,15 +256,11 @@ module Jekyll
|
|
273
256
|
newpage.data['autogen'] = "jekyll-paginate-v2"
|
274
257
|
end
|
275
258
|
|
276
|
-
logging_lambda.call "newpage.name: "+ newpage.name, 'debug'
|
277
|
-
logging_lambda.call "newpage.url: "+ newpage.url, 'debug'
|
278
|
-
logging_lambda.call "newpage.dir: "+ newpage.dir, 'debug'
|
279
|
-
|
280
259
|
# Only request that the template page be removed from the output once
|
281
260
|
# We actually create a dummy page for this actual page in the Jekyll output
|
282
261
|
# so we don't need the original page anymore
|
283
262
|
if cur_page_nr == 1
|
284
|
-
page_remove_lambda.call( template )
|
263
|
+
@page_remove_lambda.call( template )
|
285
264
|
end
|
286
265
|
end
|
287
266
|
end # function paginate
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Jekyll
|
2
|
-
module PaginateV2
|
2
|
+
module PaginateV2::Generator
|
3
3
|
|
4
4
|
#
|
5
5
|
# Static utility functions that are used in the code and
|
@@ -36,7 +36,8 @@ module Jekyll
|
|
36
36
|
# If the template url is not just root "/" then pre-pend the template_url path to it
|
37
37
|
template_dir = File.dirname(template_path)
|
38
38
|
if( template_dir != "" && template_dir != "/" )
|
39
|
-
|
39
|
+
template_url_noext = File.join(File.dirname(template_url), File.basename(template_url, '.*'))
|
40
|
+
permalink_format = File.join(template_url_noext, permalink_format)
|
40
41
|
end
|
41
42
|
|
42
43
|
Utils.ensure_leading_slash(permalink_format)
|
@@ -47,6 +48,12 @@ module Jekyll
|
|
47
48
|
def self.format_page_number(toFormat, cur_page_nr)
|
48
49
|
return toFormat.sub(':num', cur_page_nr.to_s)
|
49
50
|
end #function format_page_number
|
51
|
+
|
52
|
+
# Static: returns a fully formatted string with the :title variable replaced
|
53
|
+
#
|
54
|
+
def self.format_page_title(toFormat, title)
|
55
|
+
return toFormat.sub(':title', title.to_s)
|
56
|
+
end #function format_page_title
|
50
57
|
|
51
58
|
# Static: Return a String version of the input which has a leading slash.
|
52
59
|
# If the input already has a forward slash in position zero, it will be
|
@@ -84,11 +91,11 @@ module Jekyll
|
|
84
91
|
# Retrieves the given sort field from the given post
|
85
92
|
# the sort_field variable can be a hierarchical value on the form "parent_field:child_field" repeated as many times as needed
|
86
93
|
# only the leaf child_field will be retrieved
|
87
|
-
def self.sort_get_post_data(
|
94
|
+
def self.sort_get_post_data(post_data, sort_field)
|
88
95
|
|
89
96
|
# Begin by splitting up the sort_field by (;,:.)
|
90
97
|
sort_split = sort_field.split(":")
|
91
|
-
sort_value =
|
98
|
+
sort_value = post_data
|
92
99
|
|
93
100
|
for r_key in sort_split
|
94
101
|
key = r_key.downcase.strip # Remove any erronious whitespace and convert to lower case
|