Skip to content

Commit

Permalink
Rework autopaging implementation + allow custom filters for collections
Browse files Browse the repository at this point in the history
  • Loading branch information
MolotovCherry committed Apr 2, 2022
1 parent e4e1d01 commit d3f7e61
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 331 deletions.
12 changes: 4 additions & 8 deletions lib/jekyll-paginate-v2.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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
end # module Jekyll
62 changes: 19 additions & 43 deletions lib/jekyll-paginate-v2/autopages/autoPages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 0 additions & 40 deletions lib/jekyll-paginate-v2/autopages/defaults.rb

This file was deleted.

109 changes: 109 additions & 0 deletions lib/jekyll-paginate-v2/autopages/pages/AutoPage.rb
Original file line number Diff line number Diff line change
@@ -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
60 changes: 0 additions & 60 deletions lib/jekyll-paginate-v2/autopages/pages/baseAutoPage.rb

This file was deleted.

31 changes: 0 additions & 31 deletions lib/jekyll-paginate-v2/autopages/pages/categoryAutoPage.rb

This file was deleted.

31 changes: 0 additions & 31 deletions lib/jekyll-paginate-v2/autopages/pages/collectionAutoPage.rb

This file was deleted.

Loading

0 comments on commit d3f7e61

Please sign in to comment.