jekyll-auto-authors 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []