jekyll-auto-authors 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 793a2713c64a6ae7a275644ee7ee7220bfab67449be05787ac5e0d9ffbba2106
4
+ data.tar.gz: 5a7686a785ed8f884b13b09b07bef2fb55e027b64c5187bf2ce25bc1690a4bab
5
+ SHA512:
6
+ metadata.gz: 10e376f3581c57032f8e8873bc6714c8eb8a5e709367f58a3d1d26444cf7d87e41c447c04f4076c78ecd614d5dd6aed6a0b9d3a27da0f5c6e9411110fe6a83e8
7
+ data.tar.gz: e1fb701aa1878fa917aa5d029954f0276d51dfd9d7d59f06d9db9f39d5b722d38aa4fa8bda55747981bf57b8ffbd34a5f3ac02e6ea4c6c5ca32191cad6e8f807
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem"s dependencies in jekyll-paginate-authors.gemspec
4
+ gemspec
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "jekyll-auto-authors/version"
5
+ require "date"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "jekyll-auto-authors"
9
+ spec.version = Jekyll::AutoAuthors::VERSION
10
+ spec.platform = Gem::Platform::RUBY
11
+ spec.required_ruby_version = ">= 2.0.0" # Same as Jekyll
12
+ spec.date = DateTime.now.strftime("%Y-%m-%d")
13
+ spec.authors = ["Gourav Khunger"]
14
+ spec.email = ["gouravkhunger18@gmail.com"]
15
+ spec.homepage = "https://github.com/gouravkhunger/jekyll-auto-authors"
16
+ spec.license = "MIT"
17
+
18
+ spec.summary = "Seamless multiple authors support for jekyll powered publications"
19
+ spec.description = "A plugin to seamlessly support multiple authors with paginated posts inside a jekyll powered publication blog. Extends jekyll-paginate-v2 for Autopages and Pagination."
20
+
21
+ spec.files = Dir["*.gemspec", "Gemfile", "lib/**/*"]
22
+ spec.require_paths = ["lib"]
23
+
24
+ # Dependencies
25
+ spec.add_runtime_dependency "jekyll", ">= 3.0.0"
26
+ spec.add_runtime_dependency "jekyll-paginate-v2", ">= 3.0.0"
27
+ spec.add_development_dependency "bundler", ">= 2.0.0"
28
+ end
@@ -0,0 +1,35 @@
1
+ module Jekyll
2
+ module AutoAuthors
3
+
4
+ class AuthorAutoPage < PaginateV2::AutoPages::BaseAutoPage
5
+ def initialize(site, base, autopage_config, pagination_config, layout_name, author, author_name)
6
+
7
+ # Get the slugify configuration if available.
8
+ slugify_config = autopage_config.is_a?(Hash) && autopage_config.has_key?("slugify") ? autopage_config["slugify"] : nil
9
+
10
+ # Construct the lambda function to set the config values this
11
+ # function receives the pagination config hash and manipulates it.
12
+ set_autopage_data_lambda = lambda do | in_config |
13
+ author_data = YAML::load(File.read(autopage_config["data"]))
14
+ in_config["author"] = author
15
+ in_config["author_data"] = author_data[author_name]
16
+ end
17
+
18
+ # Lambdas to return formatted permalink and title.
19
+ get_autopage_permalink_lambda = lambda do |permalink_pattern|
20
+ return Utils.format_author_macro(permalink_pattern, author, slugify_config)
21
+ end
22
+
23
+ get_autopage_title_lambda = lambda do |title_pattern|
24
+ return Utils.format_author_macro(title_pattern, author, slugify_config)
25
+ end
26
+
27
+ # Call the super constuctor from the base generator with our custom lambda.
28
+ super(site, base, autopage_config, pagination_config, layout_name, set_autopage_data_lambda, get_autopage_permalink_lambda, get_autopage_title_lambda, author_name)
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module Jekyll
2
+ module AutoAuthors
3
+
4
+ # Default configurations for the plugin.
5
+ DEFAULT = {
6
+ "enabled" => false, # Enable or disable the plugin.
7
+
8
+ "data" => "_data/authors.yml", # The data file inside _data/ folder that contains author information.
9
+ "layouts" => ["authors.html"], # The layout file inside _layouts/ folder to use for the author pages.
10
+
11
+ "title" => "Posts by :author", # :author is replaced by author name.
12
+ "permalink" => "/author/:author", # :author is customizable elements
13
+
14
+ "slugify" => {
15
+ "mode" => "none", # [raw, default, pretty, ascii or latin], none gives back the same string.
16
+ "cased" => false, # If cased is true, all uppercase letters in the result string are replaced with their lowercase counterparts.
17
+ }
18
+ }
19
+
20
+ end
21
+ end
@@ -0,0 +1,262 @@
1
+ module Jekyll
2
+ module AutoAuthors
3
+
4
+ # The entrypoint for the plugin, auto called by Jekyll based on priorities.
5
+ # :lowest - after all the plugins are done with their thing.
6
+ class AuthorPageGenerator < Generator
7
+ safe true
8
+ priority :lowest
9
+
10
+ def generate(site)
11
+ # load the configs for jekyll-paginate-v2.
12
+ autopage_config = Jekyll::Utils.deep_merge_hashes(PaginateV2::AutoPages::DEFAULT, site.config["autopages"] || {})
13
+ pagination_config = Jekyll::Utils.deep_merge_hashes(PaginateV2::Generator::DEFAULT, site.config["pagination"] || {})
14
+
15
+ # load the configs for jekyll-auto-authors (this plugin).
16
+ authors_config = Jekyll::Utils.deep_merge_hashes(DEFAULT, site.config["autopages"]["authors"] || {})
17
+
18
+ # Do nothing if autopages / author config is disabled.
19
+ if (
20
+ autopage_config["enabled"].nil? ||
21
+ !autopage_config["enabled"] ||
22
+ authors_config["enabled"].nil? ||
23
+ !authors_config["enabled"]
24
+ )
25
+ Jekyll.logger.info "Author Pages:", "Disabled / Not configured properly."
26
+ return
27
+ end
28
+
29
+ Jekyll.logger.info "Author Pages:", "Generating..."
30
+
31
+ # Lambda that created the author page for a given author.
32
+ # will be passed to PaginateV2::Autopages for processing.
33
+ createauthorpage_lambda = lambda do | autopage_author_config, pagination_config, layout_name, author, author_original_name |
34
+ author_data = YAML::load(File.read(autopage_author_config["data"]))[author_original_name]
35
+
36
+ if author_data.nil?
37
+ Jekyll.logger.warn "Author Pages:", "Author data for "#{author_original_name}" not found. Skipping author page..."
38
+ return
39
+ end
40
+
41
+ site.pages << AuthorAutoPage.new(site, site.dest, autopage_author_config, pagination_config, layout_name, author, author_original_name)
42
+ end
43
+
44
+ posts_to_use = []
45
+ site.collections.each do |coll_name, coll_data|
46
+ if !coll_data.nil?
47
+ # Exclude all pagination pages, as they are not posts.
48
+ # Then for every page store it"s collection name.
49
+
50
+ posts_to_use += coll_data.docs.select { |doc| !doc.data.has_key?("pagination") }.each{ |doc| doc.data["__coll"] = coll_name }
51
+ end
52
+ end
53
+
54
+ # Pass the config to PaginateV2::AutoPages for processing.
55
+ # autopage_create() indexes the posts into hashes by author (5th parameter here).
56
+ # then checkes if configs are enabled and if so, calls the lambda to generate the author page.
57
+ PaginateV2::AutoPages.autopage_create(
58
+ autopage_config, pagination_config, posts_to_use, "authors", "author", createauthorpage_lambda
59
+ )
60
+
61
+ # Now auto pages for authors have been created, we can generate the pagination logic.
62
+
63
+ # Further logic is mostly similar as PaginateV2::Generator::PaginationModel#paginate(), but we need
64
+ # to override the default pagination logic to include author pages too, so it isn"t called directly.
65
+
66
+ # Generate lambda for adding/deleting pages to the site.
67
+ page_add_lambda = lambda do | newpage |
68
+ site.pages << newpage
69
+ return newpage
70
+ end
71
+
72
+ page_remove_lambda = lambda do | page_to_remove |
73
+ site.pages.delete_if {|page| page == page_to_remove }
74
+ end
75
+
76
+ # Logs formatted messages, defined similar to the one in PaginateV2::Generator::PaginationModel.
77
+ logging_lambda = lambda do | message, type = "info" |
78
+ if type == "debug"
79
+ Jekyll.logger.debug "Author Pages:","#{message}"
80
+ elsif type == "error"
81
+ Jekyll.logger.error "Author Pages:", "#{message}"
82
+ elsif type == "warn"
83
+ Jekyll.logger.warn "Author Pages:", "#{message}"
84
+ else
85
+ Jekyll.logger.info "Author Pages:", "#{message}"
86
+ end
87
+ end
88
+
89
+ # Create an instance of pagination model. We will use some functions from this instance while
90
+ # defining some logic of our own, for overriding the default pagination to include author pages too.
91
+ pagination_model = Jekyll::PaginateV2::Generator::PaginationModel.new(
92
+ logging_lambda, page_add_lambda, page_remove_lambda, nil
93
+ )
94
+
95
+ # get posts which have pagination enabled. Ignore hidden posts.
96
+ all_posts = site.collections["posts"].docs.select { |doc| !doc.data.has_key?("pagination") }
97
+ all_posts = all_posts.reject { |doc| doc["hidden"] }
98
+
99
+ # The Indexer is responsible for generating the hash for posts indexed by by author.
100
+ # The structure is: {"author1" => {<posts>}, "author2" => {<posts>}, ...}
101
+ posts_by_authors = Jekyll::PaginateV2::Generator::PaginationIndexer.index_posts_by(all_posts, "author")
102
+
103
+ # This gets all the pages where pagination is enabled. This also includes Autopages too,
104
+ # as pagination data is assigned to them while generation (PaginateV2::AutoPages::BaseAutoPage line 45).
105
+ templates = pagination_model.discover_paginate_templates(site.pages)
106
+
107
+ templates.each do |template|
108
+ if template.data["pagination"].is_a?(Hash)
109
+
110
+ # For each template get the config, skip if paginatio is disabled, or it"s not an author page.
111
+ config = Jekyll::Utils.deep_merge_hashes(pagination_config, template.data["pagination"] || {})
112
+ next if !config["enabled"]
113
+ next if template.data["pagination"]["author"].nil?
114
+
115
+ # Filter posts with bad configs.
116
+ pagination_posts = PaginateV2::Generator::PaginationIndexer.read_config_value_and_filter_posts(
117
+ config, "author", all_posts, posts_by_authors
118
+ )
119
+
120
+ # Apply sorting to the posts if configured, any field for the post is available for sorting.
121
+ if config["sort_field"]
122
+ sort_field = config["sort_field"].to_s
123
+
124
+ pagination_posts.each do |post|
125
+ if post.respond_to?("date")
126
+ tmp_date = post.date
127
+ if( !tmp_date || tmp_date.nil? )
128
+ post.date = File.mtime(post.path)
129
+ end
130
+ end
131
+ end
132
+
133
+ pagination_posts.sort!{ |a,b|
134
+ PaginateV2::Generator::Utils.sort_values(
135
+ PaginateV2::Generator::Utils.sort_get_post_data(a.data, sort_field), PaginateV2::Generator::Utils.sort_get_post_data(b.data, sort_field)
136
+ )
137
+ }
138
+
139
+ # Remove the first x entries. Defined by "offset" in the config.
140
+ offset_post_count = [0, config["offset"].to_i].max
141
+ pagination_posts.pop(offset_post_count)
142
+
143
+ if config["sort_reverse"]
144
+ pagination_posts.reverse!
145
+ end
146
+ end
147
+
148
+ # Calculate number of total pages.
149
+ total_pages = (pagination_posts.size.to_f / config["per_page"].to_i).ceil
150
+
151
+ # If a upper limit is set on the number of total pagination pages then impose that now.
152
+ if config["limit"] && config["limit"].to_i > 0 && config["limit"].to_i < total_pages
153
+ total_pages = config["limit"].to_i
154
+ end
155
+
156
+ # Remove the template page from the site, index pages will be generated in the next steps.
157
+ page_remove_lambda.call(template)
158
+
159
+ # Store List of all newly created pages, used in creating pagination trails later.
160
+ newpages = []
161
+
162
+ # Consider the default index page name and extension.
163
+ indexPageName = config["indexpage"].nil? ? "" : config["indexpage"].split(".")[0]
164
+ indexPageExt = config["extension"].nil? ? "" : Jekyll::PaginateV2::Generator::Utils.ensure_leading_dot(config["extension"])
165
+ indexPageWithExt = indexPageName + indexPageExt
166
+
167
+ total_pages = 1 if total_pages.zero?
168
+
169
+ (1..total_pages).each do |cur_page_nr|
170
+ # Create a new page for each page number.
171
+ newpage = Jekyll::PaginateV2::Generator::PaginationPage.new( template, cur_page_nr, total_pages, indexPageWithExt )
172
+
173
+ # Create the permalink for the in-memory page, construct title, set all page.data values needed.
174
+ paginated_page_url = config["permalink"]
175
+ first_index_page_url = ""
176
+ if template.data["permalink"]
177
+ first_index_page_url = Jekyll::PaginateV2::Generator::Utils.ensure_trailing_slash(template.data["permalink"])
178
+ else
179
+ first_index_page_url = Jekyll::PaginateV2::Generator::Utils.ensure_trailing_slash(template.dir)
180
+ end
181
+ paginated_page_url = File.join(first_index_page_url, paginated_page_url)
182
+
183
+ # Create the pager logic for this page, pass in the prev and next page numbers, assign pager to in-memory page.
184
+ newpage.pager = PaginateV2::Generator::Paginator.new( config["per_page"], first_index_page_url, paginated_page_url, pagination_posts, cur_page_nr, total_pages, indexPageName, indexPageExt)
185
+
186
+ # Create the url for the new page, make sure to prepend any permalinks that are defined in the template page before.
187
+ if newpage.pager.page_path.end_with? "/"
188
+ newpage.set_url(File.join(newpage.pager.page_path, indexPageWithExt))
189
+ elsif newpage.pager.page_path.end_with? indexPageExt
190
+ # Support for direct .html files.
191
+ newpage.set_url(newpage.pager.page_path)
192
+ else
193
+ # Support for extensionless permalinks.
194
+ newpage.set_url(newpage.pager.page_path + indexPageExt)
195
+ end
196
+
197
+ if( template.data["permalink"] )
198
+ newpage.data["permalink"] = newpage.pager.page_path
199
+ end
200
+
201
+ # Transfer the title across to the new page.
202
+ if( !template.data["title"] )
203
+ tmp_title = site.title
204
+ else
205
+ tmp_title = template.data["title"]
206
+ end
207
+
208
+ # If the user specified a title suffix to be added then add that to all the pages except the first.
209
+ if( cur_page_nr > 1 && config.has_key?("title") )
210
+ newpage.data["title"] = "#{Jekyll::PaginateV2::Generator::Utils.format_page_title(config["title"], tmp_title, cur_page_nr, total_pages)}"
211
+ else
212
+ newpage.data["title"] = tmp_title
213
+ end
214
+
215
+ # Signals that this page is automatically generated by the pagination logic.
216
+ # We don"t do this for the first page as it is there to mask the one we removed.
217
+ if cur_page_nr > 1
218
+ newpage.data["autogen"] = "jekyll-paginate-v2"
219
+ end
220
+
221
+ # Add the page to the site.
222
+ page_add_lambda.call( newpage )
223
+
224
+ # Store the page to the internal list.
225
+ newpages << newpage
226
+ end
227
+
228
+ # Now generate the pagination number path, so that the users can have a prev 1 2 3 4 5 next structure on their page
229
+ # simplest is to include all of the links to the pages preceeding the current one
230
+ # (e.g for page 1 you get the list 2, 3, 4.... and for page 2 you get the list 3,4,5...)
231
+ if( config["trail"] && !config["trail"].nil? && newpages.size.to_i > 1 )
232
+ trail_before = [config["trail"]["before"].to_i, 0].max
233
+ trail_after = [config["trail"]["after"].to_i, 0].max
234
+ trail_length = trail_before + trail_after + 1
235
+
236
+ if( trail_before > 0 || trail_after > 0 )
237
+ newpages.select do | npage |
238
+ idx_start = [ npage.pager.page - trail_before - 1, 0].max # Selecting the beginning of the trail
239
+ idx_end = [idx_start + trail_length, newpages.size.to_i].min # Selecting the end of the trail
240
+
241
+ # Always attempt to maintain the max total of <trail_length> pages in the trail (it will look better if the trail doesn"t shrink).
242
+ if( idx_end - idx_start < trail_length )
243
+ # Attempt to pad the beginning if we have enough pages.
244
+ idx_start = [idx_start - ( trail_length - (idx_end - idx_start) ), 0].max
245
+ # Never go beyond the zero index.
246
+ end
247
+
248
+ # Convert the newpages array into a two dimensional array that has [index, page_url] as items.
249
+ npage.pager.page_trail = newpages[idx_start...idx_end].each_with_index.map {|ipage,idx| Jekyll::PaginateV2::Generator::PageTrail.new(idx_start+idx+1, ipage.pager.page_path, ipage.data["title"])}
250
+
251
+ end
252
+ end
253
+ end
254
+
255
+ end
256
+ end
257
+
258
+ end
259
+ end
260
+
261
+ end
262
+ end
@@ -0,0 +1,15 @@
1
+ module Jekyll
2
+ module AutoAuthors
3
+
4
+ class Utils
5
+
6
+ def self.format_author_macro(toFormat, author, slugify_config=nil)
7
+ slugify_mode = slugify_config.has_key?("mode") ? slugify_config["mode"] : nil
8
+ slugify_cased = slugify_config.has_key?("cased") ? slugify_config["cased"] : false
9
+ return toFormat.sub(":author", Jekyll::Utils.slugify(author.to_s, mode:slugify_mode, cased:slugify_cased))
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module AutoAuthors
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ require "jekyll-auto-authors/version"
2
+ require "jekyll-auto-authors/main"
3
+
4
+ # Author pages generation logic.
5
+ require "jekyll-auto-authors/utils"
6
+ require "jekyll-auto-authors/defaults"
7
+ require "jekyll-auto-authors/authorAutoPage"
8
+
9
+ module Jekyll
10
+ module AutoAuthors
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-auto-authors
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gourav Khunger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: jekyll-paginate-v2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.0
55
+ description: A plugin to seamlessly support multiple authors with paginated posts
56
+ inside a jekyll powered publication blog. Extends jekyll-paginate-v2 for Autopages
57
+ and Pagination.
58
+ email:
59
+ - gouravkhunger18@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - Gemfile
65
+ - jekyll-auto-authors.gemspec
66
+ - lib/jekyll-auto-authors.rb
67
+ - lib/jekyll-auto-authors/authorAutoPage.rb
68
+ - lib/jekyll-auto-authors/defaults.rb
69
+ - lib/jekyll-auto-authors/main.rb
70
+ - lib/jekyll-auto-authors/utils.rb
71
+ - lib/jekyll-auto-authors/version.rb
72
+ homepage: https://github.com/gouravkhunger/jekyll-auto-authors
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.0.0
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.3.3
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Seamless multiple authors support for jekyll powered publications
95
+ test_files: []