From d3f7e61f1cd47515acc68a0b3408f0377f8c4f29 Mon Sep 17 00:00:00 2001 From: Cherryleafroad <13651622+cherryleafroad@users.noreply.github.com> Date: Thu, 31 Mar 2022 16:42:14 -0700 Subject: [PATCH] Rework autopaging implementation + allow custom filters for collections --- lib/jekyll-paginate-v2.rb | 12 +- lib/jekyll-paginate-v2/autopages/autoPages.rb | 62 +++------- lib/jekyll-paginate-v2/autopages/defaults.rb | 40 ------- .../autopages/pages/AutoPage.rb | 109 ++++++++++++++++++ .../autopages/pages/baseAutoPage.rb | 60 ---------- .../autopages/pages/categoryAutoPage.rb | 31 ----- .../autopages/pages/collectionAutoPage.rb | 31 ----- .../autopages/pages/tagAutoPage.rb | 31 ----- lib/jekyll-paginate-v2/autopages/utils.rb | 68 +---------- .../generator/paginationModel.rb | 50 ++++---- lib/jekyll-paginate-v2/generator/utils.rb | 2 +- 11 files changed, 165 insertions(+), 331 deletions(-) delete mode 100644 lib/jekyll-paginate-v2/autopages/defaults.rb create mode 100644 lib/jekyll-paginate-v2/autopages/pages/AutoPage.rb delete mode 100644 lib/jekyll-paginate-v2/autopages/pages/baseAutoPage.rb delete mode 100644 lib/jekyll-paginate-v2/autopages/pages/categoryAutoPage.rb delete mode 100644 lib/jekyll-paginate-v2/autopages/pages/collectionAutoPage.rb delete mode 100644 lib/jekyll-paginate-v2/autopages/pages/tagAutoPage.rb diff --git a/lib/jekyll-paginate-v2.rb b/lib/jekyll-paginate-v2.rb index 47a1158..9f9974d 100644 --- a/lib/jekyll-paginate-v2.rb +++ b/lib/jekyll-paginate-v2.rb @@ -1,5 +1,5 @@ # Jekyll::Paginate V2 is a gem built for Jekyll 3 that generates pagiatation for posts, collections, categories and tags. -# +# # It is based on https://github.com/jekyll/jekyll-paginate, the original Jekyll paginator # which was decommissioned in Jekyll 3 release onwards. This code is currently not officially # supported on Jekyll versions < 3.0 (although it might work) @@ -21,14 +21,10 @@ require "jekyll-paginate-v2/generator/paginationGenerator" # Files needed for the auto category and tag pages require "jekyll-paginate-v2/autopages/utils" -require "jekyll-paginate-v2/autopages/defaults" require "jekyll-paginate-v2/autopages/autoPages" -require "jekyll-paginate-v2/autopages/pages/baseAutoPage" -require "jekyll-paginate-v2/autopages/pages/categoryAutoPage" -require "jekyll-paginate-v2/autopages/pages/collectionAutoPage" -require "jekyll-paginate-v2/autopages/pages/tagAutoPage" +require "jekyll-paginate-v2/autopages/pages/AutoPage" -module Jekyll +module Jekyll module PaginateV2 end # module PaginateV2 -end # module Jekyll \ No newline at end of file +end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/autoPages.rb b/lib/jekyll-paginate-v2/autopages/autoPages.rb index e957302..caf3c44 100644 --- a/lib/jekyll-paginate-v2/autopages/autoPages.rb +++ b/lib/jekyll-paginate-v2/autopages/autoPages.rb @@ -5,67 +5,43 @@ module PaginateV2::AutoPages # This function is called right after the main generator is triggered by Jekyll # This code is adapted from Stephen Crosby's code https://github.com/stevecrozz def self.create_autopages(site) - # Get the configuration for the auto pages - autopage_config = Jekyll::Utils.deep_merge_hashes(DEFAULT, site.config['autopages'] || {}) + autopage_config = site.config['autopages'] || {} pagination_config = Jekyll::Utils.deep_merge_hashes(Jekyll::PaginateV2::Generator::DEFAULT, site.config['pagination'] || {}) + # Simply gather all documents across all pages/posts/collections that we have + # and store them under each collection name + coll_docs = Utils.collect_all_docs(site.collections) + # we don't use the posts collection + coll_docs.delete("posts") + coll_names = coll_docs.keys + # If disabled then don't do anything if !autopage_config['enabled'] || autopage_config['enabled'].nil? Jekyll.logger.info "AutoPages:","Disabled/Not configured in site.config." return end - autopages_log(autopage_config, 'tags', 'categories', 'collections') - - # TODO: Should I detect here and disable if we're running the legacy paginate code???! - - # Simply gather all documents across all pages/posts/collections that we have - # we could be generating quite a few empty pages but the logic is just vastly simpler than trying to - # figure out what tag/category belong to which collection. - posts_to_use = Utils.collect_all_docs(site.collections) + autopages_log(autopage_config, *coll_names) - ############################################### - # Generate the Tag pages if enabled - createtagpage_lambda = lambda do | autopage_tag_config, pagination_config, layout_name, tag, tag_original_name | - site.pages << TagAutoPage.new(site, site.dest, autopage_tag_config, pagination_config, layout_name, tag, tag_original_name) - end - autopage_create(autopage_config, pagination_config, posts_to_use, 'tags', 'tags', createtagpage_lambda) # Call the actual function - + coll_docs.each do |coll_name, coll_data| + createcolpage_lambda = lambda do |autopage_col_config, doc| + site.pages << AutoPage.new(site, autopage_col_config, pagination_config, coll_name, doc) + end - ############################################### - # Generate the category pages if enabled - createcatpage_lambda = lambda do | autopage_cat_config, pagination_config, layout_name, category, category_original_name | - site.pages << CategoryAutoPage.new(site, site.dest, autopage_cat_config, pagination_config, layout_name, category, category_original_name) - end - autopage_create(autopage_config, pagination_config,posts_to_use, 'categories', 'categories', createcatpage_lambda) # Call the actual function - - ############################################### - # Generate the Collection pages if enabled - createcolpage_lambda = lambda do | autopage_col_config, pagination_config, layout_name, coll_name, coll_original_name | - site.pages << CollectionAutoPage.new(site, site.dest, autopage_col_config, pagination_config, layout_name, coll_name, coll_original_name) + autopage_create(autopage_config, coll_name, coll_data, createcolpage_lambda) end - autopage_create(autopage_config, pagination_config,posts_to_use, 'collections', '__coll', createcolpage_lambda) # Call the actual function - end # create_autopages - # STATIC: this function actually performs the steps to generate the autopages. It uses a lambda function to delegate the creation of the individual # page types to the calling code (this way all features can reuse the logic). # - def self.autopage_create(autopage_config, pagination_config, posts_to_use, configkey_name, indexkey_name, createpage_lambda ) - if !autopage_config[configkey_name].nil? + def self.autopage_create(autopage_config, configkey_name, coll_data, createpage_lambda) + unless autopage_config[configkey_name].nil? ap_sub_config = autopage_config[configkey_name] - if ap_sub_config ['enabled'] - # Roll through all documents in the posts collection and extract the tags - index_keys = Utils.ap_index_posts_by(posts_to_use, indexkey_name) # Cannot use just the posts here, must use all things.. posts, collections... - - index_keys.each do |index_key, value| - # Iterate over each layout specified in the config - ap_sub_config ['layouts'].each do | layout_name | - # Use site.dest here as these pages are never created in the actual source but only inside the _site folder - createpage_lambda.call(ap_sub_config, pagination_config, layout_name, index_key, value[-1]) # the last item in the value array will be the display name - end + if ap_sub_config['enabled'] + coll_data.each do |doc| + createpage_lambda.call(ap_sub_config, doc) end end end diff --git a/lib/jekyll-paginate-v2/autopages/defaults.rb b/lib/jekyll-paginate-v2/autopages/defaults.rb deleted file mode 100644 index 9587243..0000000 --- a/lib/jekyll-paginate-v2/autopages/defaults.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Jekyll - module PaginateV2::AutoPages - - # The default configuration for the AutoPages - DEFAULT = { - 'enabled' => false, - 'tags' => { - 'layouts' => ['autopage_tags.html'], - 'title' => 'Posts tagged with :tag', - 'permalink' => '/tag/:tag', - 'enabled' => true, - 'slugify' => { - 'mode' => 'none', # [raw default pretty ascii latin], none gives back the same string - 'cased'=> false # If cased is true, all uppercase letters in the result string are replaced with their lowercase counterparts. - } - }, - 'categories' => { - 'layouts' => ['autopage_category.html'], - 'title' => 'Posts in category :cat', - 'permalink' => '/category/:cat', - 'enabled' => true, - 'slugify' => { - 'mode' => 'none', # [raw default pretty ascii latin], none gives back the same string - 'cased'=> false # If cased is true, all uppercase letters in the result string are replaced with their lowercase counterparts. - } - }, - 'collections' => { - 'layouts' => ['autopage_collection.html'], - 'title' => 'Posts in collection :coll', - 'permalink' => '/collection/:coll', - 'enabled' => true, - 'slugify' => { - 'mode' => 'none', # [raw default pretty ascii latin], none gives back the same string - 'cased'=> false # If cased is true, all uppercase letters in the result string are replaced with their lowercase counterparts. - } - } - } - - end # module PaginateV2::AutoPages -end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/pages/AutoPage.rb b/lib/jekyll-paginate-v2/autopages/pages/AutoPage.rb new file mode 100644 index 0000000..840614a --- /dev/null +++ b/lib/jekyll-paginate-v2/autopages/pages/AutoPage.rb @@ -0,0 +1,109 @@ +module Jekyll + module PaginateV2::AutoPages + + class AutoPage < Jekyll::Page + def initialize(site, autopage_config, pagination_config, coll_name, doc) + @site = site + @base = site.dest + @name = 'index.html' + + layout_dir = '_layouts' + + # use layout in document priority, or specify one for it in the autopage config section + # you need to have at least one of these specified. the autopage layout will be a fallback if none are sepcified + layout_name = doc['layout'] || autopage_config['layout'] + layout_name += '.html' + + if coll_name.eql?('categories') + index_key = 'category' + elsif coll_name.eql?('tags') + index_key = 'tag' + else + index_key = autopage_config['indexkey'].nil? ? coll_name : autopage_config['indexkey'] + end + + # used to do the pagination matching + # defined in frontmatter like, author: Cherryleafroad + # which matches the same in posts + item = doc[index_key] + + # Path is only used by the convertible module and accessed below when calling read_yaml + # Handling themes stored in a gem + @path = if site.in_theme_dir(site.source) == site.source # we're in a theme + site.in_theme_dir(site.source, layout_dir, layout_name) + else + site.in_source_dir(site.source, layout_dir, layout_name) + end + + self.process(@name) # Creates the base name and extension + self.read_yaml(File.join(site.source, layout_dir), layout_name) + + # Merge the config with any config that might already be defined in the layout + pagination_layout_config = Jekyll::Utils.deep_merge_hashes(pagination_config, self.data['pagination'] || {}) + + # Read any possible autopage overrides in the layout page + autopage_layout_config = Jekyll::Utils.deep_merge_hashes(autopage_config, self.data['autopages'] || {}) + + # Construct the title + # as usual, you have 3 different options for title + # you can use cased to get upper or lower case on the key if using ap config title + item_cased = autopage_config['cased'] ? item : item.downcase + ap_title = autopage_config['title']&.gsub(":#{index_key}", item_cased) + page_title = ap_title || autopage_layout_config['title'] || doc['title'] + + # NOTE: Should we set this before calling read_yaml as that function validates the permalink structure + # use doc permalink if available + # Get permalink structure + # ap permalink setting overrides document setting + # It MUST be a directory notation NOT a file ending + ap_perma = autopage_config['permalink']&.gsub(":#{index_key}", item_cased) + permalink = ap_perma || doc.url.to_s + self.data['permalink'] = permalink + @url = File.join(permalink, @name) + @dir = permalink + + # set up pagination + if coll_name.eql?('categories') or coll_name.eql?('tags') + pagination_layout_config[index_key] = doc[index_key] + else + # user definable different collections, or default + pagination_layout_config['collection'] = autopage_config['collection'] || 'posts' + pagination_layout_config[index_key] = doc[index_key] + pagination_layout_config['filter_coll_by'] = index_key + end + + # use ap config layout or doc layout. ap overrides doc layout + self.data['layout'] = autopage_config['layout'] || doc.data['layout'] + # use the docs title first if available + self.data['title'] = page_title + # inject pagination variable + self.data['pagination'] = pagination_layout_config # Store the pagination configuration + + # inject the rest of the frontmatter data into the page as if it was originating from the original page + ignore_keys = %w[layout title permalink autopages] + # include all data unless it's a disallowed key + doc.data.each do |key, value| + self.data[key] = value unless ignore_keys.include?(key) + end + + unless doc.content.nil? + # run renderer on document to render out data to get the rendered content + doc.renderer.run + # set content separately since it's not part of data + self.data['content'] = doc.content + end + + # Add the auto page flag in there to be able to detect the page (necessary when figuring out where to load it from) + # TODO: Need to re-think this variable!!! + self.data['autopage'] = {'layout_path' => File.join( layout_dir, layout_name ), 'display_name' => item } + + data.default_proc = proc do |_, key| + site.frontmatter_defaults.find(File.join(layout_dir, layout_name), type, key) + end + + # Trigger a page event + #Jekyll::Hooks.trigger :pages, :post_init, self + end #function initialize + end #class BaseAutoPage + end # module PaginateV2 +end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/pages/baseAutoPage.rb b/lib/jekyll-paginate-v2/autopages/pages/baseAutoPage.rb deleted file mode 100644 index 912da48..0000000 --- a/lib/jekyll-paginate-v2/autopages/pages/baseAutoPage.rb +++ /dev/null @@ -1,60 +0,0 @@ -module Jekyll - module PaginateV2::AutoPages - - class BaseAutoPage < Jekyll::Page - def initialize(site, base, autopage_config, pagination_config, layout_name, set_autopage_data_lambda, get_autopage_permalink_lambda, get_autopage_title_lambda, display_name) - @site = site - @base = base - @name = 'index.html' - - layout_dir = '_layouts' - - # Path is only used by the convertible module and accessed below when calling read_yaml - # Handling themes stored in a gem - @path = if site.in_theme_dir(site.source) == site.source # we're in a theme - site.in_theme_dir(site.source, layout_dir, layout_name) - else - site.in_source_dir(site.source, layout_dir, layout_name) - end - - self.process(@name) # Creates the base name and extension - self.read_yaml(File.join(site.source, layout_dir), layout_name) - - # Merge the config with any config that might already be defined in the layout - pagination_layout_config = Jekyll::Utils.deep_merge_hashes( pagination_config, self.data['pagination'] || {} ) - - # Read any possible autopage overrides in the layout page - autopage_layout_config = Jekyll::Utils.deep_merge_hashes( autopage_config, self.data['autopages'] || {} ) - - # Now set the page specific pagination data - set_autopage_data_lambda.call(pagination_layout_config) - - # Get permalink structure - permalink_formatted = get_autopage_permalink_lambda.call(autopage_layout_config['permalink']) - - # Construct the title - page_title = autopage_layout_config['title'] - - # NOTE: Should we set this before calling read_yaml as that function validates the permalink structure - self.data['permalink'] = permalink_formatted - @url = File.join(permalink_formatted, @name) - @dir = permalink_formatted - - self.data['layout'] = File.basename(layout_name, File.extname(layout_name)) - self.data['title'] = get_autopage_title_lambda.call( page_title ) - self.data['pagination'] = pagination_layout_config # Store the pagination configuration - - # Add the auto page flag in there to be able to detect the page (necessary when figuring out where to load it from) - # TODO: Need to re-think this variable!!! - self.data['autopage'] = {"layout_path" => File.join( layout_dir, layout_name ), 'display_name' => display_name.to_s } - - data.default_proc = proc do |_, key| - site.frontmatter_defaults.find(File.join(layout_dir, layout_name), type, key) - end - - # Trigger a page event - #Jekyll::Hooks.trigger :pages, :post_init, self - end #function initialize - end #class BaseAutoPage - end # module PaginateV2 -end # module Jekyll \ No newline at end of file diff --git a/lib/jekyll-paginate-v2/autopages/pages/categoryAutoPage.rb b/lib/jekyll-paginate-v2/autopages/pages/categoryAutoPage.rb deleted file mode 100644 index 4358edc..0000000 --- a/lib/jekyll-paginate-v2/autopages/pages/categoryAutoPage.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Jekyll - module PaginateV2::AutoPages - - class CategoryAutoPage < BaseAutoPage - def initialize(site, base, autopage_config, pagination_config, layout_name, category, category_name) - - # Do we have a slugify configuration available - slugify_config = autopage_config.is_a?(Hash) && autopage_config.has_key?('slugify') ? autopage_config['slugify'] : nil - - # Construc the lambda function to set the config values - # this function received the pagination config hash and manipulates it - set_autopage_data_lambda = lambda do | in_config | - in_config['category'] = category - end - - get_autopage_permalink_lambda = lambda do |permalink_pattern| - return Utils.format_cat_macro(permalink_pattern, category, slugify_config) - end - - get_autopage_title_lambda = lambda do |title_pattern| - return Utils.format_cat_macro(title_pattern, category, slugify_config) - end - - # Call the super constuctor with our custom lambda - super(site, base, autopage_config, pagination_config, layout_name, set_autopage_data_lambda, get_autopage_permalink_lambda, get_autopage_title_lambda, category_name) - - end #function initialize - - end #class CategoryAutoPage - end # module PaginateV2 -end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/pages/collectionAutoPage.rb b/lib/jekyll-paginate-v2/autopages/pages/collectionAutoPage.rb deleted file mode 100644 index 8a17a4b..0000000 --- a/lib/jekyll-paginate-v2/autopages/pages/collectionAutoPage.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Jekyll - module PaginateV2::AutoPages - - class CollectionAutoPage < BaseAutoPage - def initialize(site, base, autopage_config, pagination_config, layout_name, collection, collection_name) - - # Do we have a slugify configuration available - slugify_config = autopage_config.is_a?(Hash) && autopage_config.has_key?('slugify') ? autopage_config['slugify'] : nil - - # Construc the lambda function to set the config values - # this function received the pagination config hash and manipulates it - set_autopage_data_lambda = lambda do | in_config | - in_config['collection'] = collection - end - - get_autopage_permalink_lambda = lambda do |permalink_pattern| - return Utils.format_coll_macro(permalink_pattern, collection, slugify_config) - end - - get_autopage_title_lambda = lambda do |title_pattern| - return Utils.format_coll_macro(title_pattern, collection, slugify_config) - end - - # Call the super constuctor with our custom lambda - super(site, base, autopage_config, pagination_config, layout_name, set_autopage_data_lambda, get_autopage_permalink_lambda, get_autopage_title_lambda, collection_name) - - end #function initialize - - end #class CollectionAutoPage - end # module PaginateV2 -end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/pages/tagAutoPage.rb b/lib/jekyll-paginate-v2/autopages/pages/tagAutoPage.rb deleted file mode 100644 index 4f69e22..0000000 --- a/lib/jekyll-paginate-v2/autopages/pages/tagAutoPage.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Jekyll - module PaginateV2::AutoPages - - class TagAutoPage < BaseAutoPage - def initialize(site, base, autopage_config, pagination_config, layout_name, tag, tag_name) - - # Do we have a slugify configuration available - slugify_config = autopage_config.is_a?(Hash) && autopage_config.has_key?('slugify') ? autopage_config['slugify'] : nil - - # Construc the lambda function to set the config values, - # this function received the pagination config hash and manipulates it - set_autopage_data_lambda = lambda do | config | - config['tag'] = tag - end - - get_autopage_permalink_lambda = lambda do |permalink_pattern| - return Utils.format_tag_macro(permalink_pattern, tag, slugify_config) - end - - get_autopage_title_lambda = lambda do |title_pattern| - return Utils.format_tag_macro(title_pattern, tag, slugify_config) - end - - # Call the super constuctor with our custom lambda - super(site, base, autopage_config, pagination_config, layout_name, set_autopage_data_lambda, get_autopage_permalink_lambda, get_autopage_title_lambda, tag_name) - - end #function initialize - - end #class TagAutoPage - end # module PaginateV2 -end # module Jekyll diff --git a/lib/jekyll-paginate-v2/autopages/utils.rb b/lib/jekyll-paginate-v2/autopages/utils.rb index 3881da2..097c94a 100644 --- a/lib/jekyll-paginate-v2/autopages/utils.rb +++ b/lib/jekyll-paginate-v2/autopages/utils.rb @@ -2,78 +2,18 @@ module Jekyll module PaginateV2::AutoPages class Utils - - # Static: returns a fully formatted string with the tag macro (:tag) replaced - # - def self.format_tag_macro(toFormat, tag, slugify_config=nil) - slugify_mode = slugify_config.has_key?('mode') ? slugify_config['mode'] : nil - slugify_cased = slugify_config.has_key?('cased') ? slugify_config['cased'] : false - return toFormat.sub(':tag', Jekyll::Utils.slugify(tag.to_s, mode:slugify_mode, cased:slugify_cased)) - end #function format_tag_macro - - # Static: returns a fully formatted string with the category macro (:cat) replaced - # - def self.format_cat_macro(toFormat, category, slugify_config=nil) - slugify_mode = slugify_config.has_key?('mode') ? slugify_config['mode'] : nil - slugify_cased = slugify_config.has_key?('cased') ? slugify_config['cased'] : false - return toFormat.sub(':cat', Jekyll::Utils.slugify(category.to_s, mode:slugify_mode, cased:slugify_cased)) - end #function format_cat_macro - - # Static: returns a fully formatted string with the collection macro (:coll) replaced - # - def self.format_coll_macro(toFormat, collection, slugify_config=nil) - slugify_mode = slugify_config.has_key?('mode') ? slugify_config['mode'] : nil - slugify_cased = slugify_config.has_key?('cased') ? slugify_config['cased'] : false - return toFormat.sub(':coll', Jekyll::Utils.slugify(collection.to_s, mode:slugify_mode, cased:slugify_cased)) - end #function format_coll_macro - # Static: returns all documents from all collections defined in the hash of collections passed in - # excludes all pagination pages though + # excludes all non-pagination pages though def self.collect_all_docs(site_collections) - coll = [] + coll = {} site_collections.each do |coll_name, coll_data| - if !coll_data.nil? - coll += coll_data.docs.select { |doc| !doc.data.has_key?('pagination') }.each{ |doc| doc.data['__coll'] = coll_name } # Exclude all pagination pages and then for every page store it's collection name + unless coll_data.nil? + coll[coll_name] = coll_data.docs.select { |doc| !doc.data.has_key?('pagination') } # Exclude all non-pagination pages end end return coll end - def self.ap_index_posts_by(all_posts, index_key) - return nil if all_posts.nil? - return all_posts if index_key.nil? - index = {} - all_posts.each do |post| - next if post.data.nil? - next if !post.data.has_key?(index_key) - next if post.data[index_key].nil? - next if post.data[index_key].size <= 0 - next if post.data[index_key].to_s.strip.length == 0 - - # Only tags and categories come as premade arrays, locale does not, so convert any data - # elements that are strings into arrays - post_data = post.data[index_key] - if post_data.is_a?(String) - post_data = post_data.split(/;|,|\s/) - end - - post_data.each do |key| - key = key.strip - # If the key is a delimetered list of values - # (meaning the user didn't use an array but a string with commas) - key.split(/;|,/).each do |raw_k_split| - k_split = raw_k_split.to_s.downcase.strip #Clean whitespace and junk - if !index.has_key?(k_split) - # Need to store the original key value here so that I can present it to the users as a page variable they can use (unmodified, e.g. tags not being 'sci-fi' but "Sci-Fi") - # Also, only interested in storing all the keys not the pages in this case - index[k_split.to_s] = [k_split.to_s, raw_k_split.to_s] - end - end - end - end - return index - end # function index_posts_by - end # class Utils end # module PaginateV2 diff --git a/lib/jekyll-paginate-v2/generator/paginationModel.rb b/lib/jekyll-paginate-v2/generator/paginationModel.rb index ac0a8c3..dd26248 100644 --- a/lib/jekyll-paginate-v2/generator/paginationModel.rb +++ b/lib/jekyll-paginate-v2/generator/paginationModel.rb @@ -42,21 +42,22 @@ def run(default_config, site_pages, site_title) @debug = template_config['debug'] # Is debugging enabled on the page level self._debug_print_config_info(template_config, template.path) - + # Only paginate the template if it is explicitly enabled - # requiring this makes the logic simpler as I don't need to determine which index pages + # requiring this makes the logic simpler as I don't need to determine which index pages # were generated automatically and which weren't if( template_config['enabled'] ) if !@debug @logging_lambda.call "found page: "+template.path, 'debug' end - # Request all documents in all collections that the user has requested + # Request all documents in all collections that the user has requested all_posts = self.get_docs_in_collections(template_config['collection']) + all_filtered_collection = PaginationIndexer.index_posts_by(all_posts, template_config['filter_coll_by']) if template_config['filter_coll_by'] # Create the necessary indexes for the posts all_categories = PaginationIndexer.index_posts_by(all_posts, 'categories') - 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) + 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) # (this is a default and must not be used in the category system) all_tags = PaginationIndexer.index_posts_by(all_posts, 'tags') all_locales = PaginationIndexer.index_posts_by(all_posts, 'locale') @@ -64,7 +65,7 @@ def run(default_config, site_pages, site_title) # TODO: NOTE!!! This whole request for posts and indexing results could be cached to improve performance, leaving like this for now during testing # Now construct the pagination data for this template page - self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales) + self.paginate(template, template_config, site_title, all_posts, all_tags, all_categories, all_locales, all_filtered_collection) end end end #for @@ -114,7 +115,7 @@ def get_docs_in_collections(raw_collection_names) docs = [] # Now for each of the collections get the docs collection_names.each do |coll_name| - # Request all the documents for the collection in question, and join it with the total collection + # Request all the documents for the collection in question, and join it with the total collection docs += @collection_by_name_lambda.call(coll_name.downcase.strip) end @@ -127,7 +128,7 @@ def get_docs_in_collections(raw_collection_names) def _fix_deprecated_config_features(config) keys_to_delete = [] - # As of v1.5.1 the title_suffix is deprecated and 'title' should be used + # As of v1.5.1 the title_suffix is deprecated and 'title' should be used # but only if title has not been defined already! if( !config['title_suffix'].nil? ) if( config['title'].nil? ) @@ -155,7 +156,7 @@ def _debug_print_config_info(config, page_path) puts f + " Limit: ".ljust(r) + config['limit'].to_s puts f + " Sort by: ".ljust(r) + config['sort_field'].to_s puts f + " Sort reverse: ".ljust(r) + config['sort_reverse'].to_s - + puts f + " Active Filters" puts f + " Collection: ".ljust(r) + config['collection'].to_s puts f + " Offset: ".ljust(r) + config['offset'].to_s @@ -163,8 +164,9 @@ def _debug_print_config_info(config, page_path) puts f + " Category: ".ljust(r) + (config['category'].nil? || config['category'] == "posts" ? "[Not set]" : config['category'].to_s) puts f + " Tag: ".ljust(r) + (config['tag'].nil? ? "[Not set]" : config['tag'].to_s) puts f + " Locale: ".ljust(r) + (config['locale'].nil? ? "[Not set]" : config['locale'].to_s) + puts f + " Filter Coll By: ".ljust(r) + (config['filter_coll_by'].nil? ? "[Not Set]" : config['filter_coll_by'].to_s) - if config['legacy'] + if config['legacy'] puts f + " Legacy Paginate Code Enabled" puts f + " Legacy Paginate: ".ljust(r) + config['per_page'].to_s puts f + " Legacy Source: ".ljust(r) + config['legacy_source'].to_s @@ -176,10 +178,10 @@ def _debug_print_config_info(config, page_path) def _debug_print_filtering_info(filter_name, before_count, after_count) # Debug print the config if @debug - puts "Pagination: ".rjust(20) + " Filtering by: "+filter_name.to_s.ljust(9) + " " + before_count.to_s.rjust(3) + " => " + after_count.to_s + puts "Pagination: ".rjust(20) + " Filtering by: "+filter_name.to_s.ljust(9) + " " + before_count.to_s.rjust(3) + " => " + after_count.to_s end end - + # # Rolls through all the pages passed in and finds all pages that have pagination enabled on them. # These pages will be used as templates @@ -196,7 +198,7 @@ def discover_paginate_templates(site_pages) end return candidates end # function discover_paginate_templates - + # Paginates the blog's posts. Renders the index.html file into paginated # directories, e.g.: page2/index.html, page3/index.html, etc and adds more # site-wide data. @@ -205,7 +207,7 @@ def discover_paginate_templates(site_pages) # template - The index.html Page that requires pagination. # config - The configuration settings that should be used # - def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales) + def paginate(template, config, site_title, all_posts, all_tags, all_categories, all_locales, all_filtered_collection) # By default paginate on all posts in the site using_posts = all_posts @@ -221,13 +223,17 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, before = using_posts.size.to_i using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, 'locale', using_posts, all_locales, should_union) self._debug_print_filtering_info('Locale', before, using_posts.size.to_i) - + if config['filter_coll_by'] + using_posts = PaginationIndexer.read_config_value_and_filter_posts(config, config['filter_coll_by'], using_posts, all_filtered_collection, should_union) + self._debug_print_filtering_info(config['filter_coll_by'].capitalize, before, using_posts.size.to_i) + end + # Apply sorting to the posts if configured, any field for the post is available for sorting if config['sort_field'] sort_field = config['sort_field'].to_s - # There is an issue in Jekyll related to lazy initialized member variables that causes iterators to - # break when accessing an uninitialized value during iteration. This happens for document.rb when the <=> compaison function + # There is an issue in Jekyll related to lazy initialized member variables that causes iterators to + # break when accessing an uninitialized value during iteration. This happens for document.rb when the <=> compaison function # is called (as this function calls the 'date' field which for drafts are not initialized.) # So to unblock this common issue for the date field I simply iterate once over every document and initialize the .date field explicitly if @debug @@ -255,10 +261,10 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, using_posts.reverse! end end - + # Calculate the max number of pagination-pages based on the configured per page value total_pages = Utils.calculate_number_of_pages(using_posts, config['per_page']) - + # If a upper limit is set on the number of total pagination pages then impose that now if config['limit'] && config['limit'].to_i > 0 && config['limit'].to_i < total_pages total_pages = config['limit'].to_i @@ -266,7 +272,7 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, #### BEFORE STARTING REMOVE THE TEMPLATE PAGE FROM THE SITE LIST! @page_remove_lambda.call( template ) - + # list of all newly created pages newpages = [] @@ -296,7 +302,7 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, first_index_page_url = Utils.ensure_trailing_slash(template.dir) end paginated_page_url = File.join(first_index_page_url, paginated_page_url) - + # 3. Create the pager logic for this page, pass in the prev and next page numbers, assign pager to in-memory page newpage.pager = Paginator.new( config['per_page'], first_index_page_url, paginated_page_url, using_posts, cur_page_nr, total_pages, indexPageName, indexPageExt) @@ -333,7 +339,7 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, if cur_page_nr > 1 newpage.data['autogen'] = "jekyll-paginate-v2" end - + # Add the page to the site @page_add_lambda.call( newpage ) @@ -358,7 +364,7 @@ def paginate(template, config, site_title, all_posts, all_tags, all_categories, if( idx_end - idx_start < trail_length ) # Attempt to pad the beginning if we have enough pages idx_start = [idx_start - ( trail_length - (idx_end - idx_start) ), 0].max # Never go beyond the zero index - end + end # Convert the newpages array into a two dimensional array that has [index, page_url] as items #puts( "Trail created for page #{npage.pager.page} (idx_start:#{idx_start} idx_end:#{idx_end})") diff --git a/lib/jekyll-paginate-v2/generator/utils.rb b/lib/jekyll-paginate-v2/generator/utils.rb index 176c345..3ea472f 100644 --- a/lib/jekyll-paginate-v2/generator/utils.rb +++ b/lib/jekyll-paginate-v2/generator/utils.rb @@ -129,7 +129,7 @@ def self.ensure_full_path(url, default_index, default_ext) if( url.end_with?('/')) return url + default_index + default_ext elsif !url.include?('.') - return url + default_index + return url + default_ext end # Default return url