jekyll-archives-dir-category 0.1.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: 39b0ef05fc29929a7c57609d539ec8fcf34c73c04e2cef76826c1df4525099ea
4
+ data.tar.gz: 4e0e5f70afcf09c9ac93f8b8b22c7261c50b02afeb78a56010cffe41725f3b62
5
+ SHA512:
6
+ metadata.gz: a5696cb3138e9e9334409b162893f6f986297e150efdaf4c0c7d6562960304862f233aea9b340a548029f10e7cbdd3097235bebb6cdeee92e7454cd7509981cf
7
+ data.tar.gz: 23f7a4bc8a87c7acb4043149ab94af2a23e74ed48dc2c86950164278584c58e58cdc022c7df427b2b5b073858ebded565c78e609dcff63fb86a45ef6a0b696e9
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Archives
5
+ class Archive < Jekyll::Page
6
+ attr_accessor :posts, :type, :slug
7
+
8
+ # Attributes for Liquid templates
9
+ ATTRIBUTES_FOR_LIQUID = %w(
10
+ posts
11
+ type
12
+ title
13
+ date
14
+ name
15
+ path
16
+ url
17
+ permalink
18
+ ).freeze
19
+
20
+ # Initialize a new Archive page
21
+ #
22
+ # site - The Site object.
23
+ # title - The name of the tag/category or a Hash of the year/month/day in case of date.
24
+ # e.g. { :year => 2014, :month => 08 } or "my-category" or "my-tag".
25
+ # type - The type of archive. Can be one of "year", "month", "day", "category", or "tag"
26
+ # posts - The array of posts that belong in this archive.
27
+ def initialize(site, title, type, posts)
28
+ @site = site
29
+ @posts = posts
30
+ @type = type
31
+ @title = title
32
+ @config = site.config["jekyll-archives-dir-category"]
33
+ @slug = slugify_string_title
34
+
35
+ # Use ".html" for file extension and url for path
36
+ @ext = File.extname(relative_path)
37
+ @path = relative_path
38
+ @name = File.basename(relative_path, @ext)
39
+
40
+ # printf("slug:%s\n", @slug)
41
+ # printf("template:%s\n", template)
42
+ # printf("url_placeholder:%s\n", url_placeholders)
43
+ # printf("url:%s\n", url)
44
+ # printf("path:%s\n", relative_path)
45
+ @data = {
46
+ "layout" => layout,
47
+ }
48
+ @content = ""
49
+ end
50
+
51
+ # The template of the permalink.
52
+ #
53
+ # Returns the template String.
54
+ def template
55
+ @config.dig("permalinks", type)
56
+ end
57
+
58
+ # The layout to use for rendering
59
+ #
60
+ # Returns the layout as a String
61
+ def layout
62
+ @config.dig("layouts", type) || @config["layout"]
63
+ end
64
+
65
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
66
+ # desired placeholder replacements. For details see "url.rb".
67
+ def url_placeholders
68
+ if @title.is_a? Hash
69
+ @title.merge(:type => @type)
70
+ else
71
+ { :name => @slug, :type => @type }
72
+ end
73
+ end
74
+
75
+ # The generated relative url of this page. e.g. /about.html.
76
+ #
77
+ # Returns the String url.
78
+ def url
79
+ @url ||= URL.new(
80
+ :template => template,
81
+ :placeholders => url_placeholders,
82
+ :permalink => nil,
83
+ ).to_s
84
+ rescue ArgumentError
85
+ raise ArgumentError, "Template \"#{template}\" provided is invalid."
86
+ end
87
+
88
+ def permalink
89
+ data&.is_a?(Hash) && data["permalink"]
90
+ end
91
+
92
+ # Produce a title object suitable for Liquid based on type of archive.
93
+ #
94
+ # Returns a String (for tag and category archives) and nil for
95
+ # date-based archives.
96
+ def title
97
+ @title if @title.is_a? String
98
+ end
99
+
100
+ # Produce a date object if a date-based archive
101
+ #
102
+ # Returns a Date.
103
+ def date
104
+ return unless @title.is_a?(Hash)
105
+
106
+ @date ||= begin
107
+ args = @title.values.map(&:to_i)
108
+ Date.new(*args)
109
+ end
110
+ end
111
+
112
+ # Obtain the write path relative to the destination directory
113
+ #
114
+ # Returns the destination relative path String.
115
+ def relative_path
116
+ @relative_path ||= begin
117
+ path = URL.unescape_path(url).gsub(%r!^/!, "")
118
+ path = File.join(path, "index.html") if url.end_with?("/")
119
+ path
120
+ end
121
+ end
122
+
123
+ # Returns the object as a debug String.
124
+ def inspect
125
+ "#<Jekyll:Archive @type=#{@type} @title=#{@title} @data=#{@data.inspect}>"
126
+ end
127
+
128
+ private
129
+
130
+ # Generate slug if @title attribute is a string.
131
+ #
132
+ # Note: mode other than those expected by Jekyll returns the given string after
133
+ # downcasing it.
134
+ def slugify_string_title
135
+ return unless title.is_a?(String)
136
+
137
+ title
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Archives
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,284 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ module Jekyll
6
+ module Archives
7
+ # Internal requires
8
+ autoload :Archive, "jekyll-archives-dir-category/archive"
9
+ autoload :VERSION, "jekyll-archives-dir-category/version"
10
+
11
+ class Archives < Jekyll::Generator
12
+ safe true
13
+
14
+ DEFAULTS = {
15
+ "layout" => "archive",
16
+ "enabled" => [],
17
+ "permalinks" => {
18
+ "year" => "/:year/",
19
+ "month" => "/:year/:month/",
20
+ "day" => "/:year/:month/:day/",
21
+ "tag" => "/tag/:name/",
22
+ "category" => "/category/:name/",
23
+ },
24
+ }.freeze
25
+
26
+ def initialize(config = {})
27
+ archives_config = config.fetch("jekyll-archives-dir-category", {})
28
+ printf("Init function of archives\n")
29
+
30
+ if archives_config.is_a?(Hash)
31
+ @config = Utils.deep_merge_hashes(DEFAULTS, archives_config)
32
+ else
33
+ @config = nil
34
+ Jekyll.logger.warn "Archives:", "Expected a hash but got #{archives_config.inspect}"
35
+ Jekyll.logger.warn "", "Archives will not be generated for this site."
36
+ end
37
+ @enabled = @config && @config["enabled"]
38
+ end
39
+
40
+ def generate(site)
41
+ return if @config.nil?
42
+
43
+ @site = site
44
+ @posts = site.posts
45
+ @archives = []
46
+
47
+ @site.config["jekyll-archives-dir-category"] = @config
48
+
49
+ # reset category info for all posts
50
+ reset_posts_category(site)
51
+
52
+ read
53
+ @site.pages.concat(@archives)
54
+
55
+ @site.config["archives"] = @archives
56
+ end
57
+
58
+ # get a category name from '_category.yml'
59
+ # return the category name from path if '_category.yml' not exist
60
+ def get_category_name(path)
61
+ catname = ""
62
+
63
+ curdir = path
64
+ while !curdir.eql?("_posts")
65
+ catpath = curdir + "/_category.yml"
66
+ n = File.basename(curdir)
67
+ if File.exists?(catpath)
68
+ category_info = YAML.load_file(catpath)
69
+ n = category_info["name"] if !category_info["name"].nil?
70
+ end
71
+ catname = n + "/" + catname
72
+ curdir = File.dirname(curdir)
73
+ end
74
+ return catname.slice(0..-2)
75
+ end
76
+
77
+ # Reset category info for all posts
78
+ # Add categories info to site.data["category-info"]
79
+ #
80
+ # the category's href is the path from '_posts' to the file name
81
+ # the category's name is the info in '_category.yml' file
82
+ def reset_posts_category(site)
83
+ post_paths = []
84
+ for p in site.posts.docs
85
+ path = File.dirname(p.path)
86
+ pos = path.index("_posts/")
87
+ path = path[pos..-1]
88
+ post_paths << path
89
+
90
+ c = path[7..-1]
91
+ cn = get_category_name(path)
92
+ p.data["category"] = c
93
+ p.data["categories"] = [c]
94
+ p.data["category-name"] = cn
95
+ p.data["update-time"] = File.mtime(p.path)
96
+ # printf(" category:%s\n", c)
97
+ # printf(" category name:%s\n\n", cn)
98
+ end
99
+ # printf("paths:%s\n", post_paths)
100
+ info = get_category_info("_posts", post_paths)
101
+ category_info = []
102
+ for c in info["subs"]
103
+ category_info << c
104
+ end
105
+ site.data["category-info"] = category_info
106
+ end
107
+
108
+ # the category info from '_category.yml' file
109
+ # this is a recursive function
110
+ def get_category_info(dir_path, paths)
111
+ dir = Dir.new(dir_path)
112
+ info = {
113
+ "href" => dir_path.slice(7..-1),
114
+ "name" => File.basename(dir_path),
115
+ "priority" => 0,
116
+ "subs" => [],
117
+ }
118
+
119
+ if paths.find { |a| a.include?(dir_path) }.nil?
120
+ return nil
121
+ end
122
+
123
+ info_path = dir_path + "/_category.yml"
124
+ if File.exists?(info_path)
125
+ category_info = YAML.load_file(info_path)
126
+ info["name"] = category_info["name"] if !category_info["name"].nil?
127
+ info["priority"] = category_info["priority"] if !category_info["priority"].nil?
128
+ end
129
+ if info["href"].nil?
130
+ info["count"] = 0
131
+ else
132
+ info["count"] = @posts.docs.count { |a|
133
+ a.data["category"].start_with? info["href"]
134
+ }
135
+ end
136
+
137
+ dir.children.each do |file_name|
138
+ file_path = File.join(dir_path, file_name)
139
+ if File.directory?(file_path)
140
+ subinfo = get_category_info(file_path, paths)
141
+ if !subinfo.nil?
142
+ info["subs"] << subinfo
143
+ end
144
+ end
145
+ end
146
+ info["subs"] = info["subs"].sort_by { |a| a["priority"] }
147
+ return info
148
+ end
149
+
150
+ # DEBUG: print category info
151
+ def print_category(c, indent)
152
+ printf("%sname:%s\n", " " * indent, c["name"])
153
+ printf("%shref:%s\n", " " * indent, c["href"])
154
+ printf("%spriority:%s\n\n", " " * indent, c["priority"])
155
+
156
+ for cs in c["subs"]
157
+ if !cs.nil?
158
+ print_category(cs, indent + 4)
159
+ end
160
+ end
161
+ end
162
+
163
+ # DEBUG: print category info
164
+ def dump_category_info(site)
165
+ printf("====================================================\n")
166
+ printf("info:%s\n", site.data["category-info"])
167
+ printf("====================================================\n")
168
+
169
+ for c in site.data["category-info"]
170
+ if !c.nil?
171
+ print_category(c, 1)
172
+ end
173
+ end
174
+ end
175
+
176
+ # Read archive data from posts
177
+ def read
178
+ read_tags
179
+ read_categories
180
+ read_dates
181
+ end
182
+
183
+ def read_tags
184
+ if enabled? "tags"
185
+ tags.each do |title, posts|
186
+ @archives << Archive.new(@site, title, "tag", posts)
187
+ end
188
+ end
189
+ end
190
+
191
+ def read_categories
192
+ if enabled? "categories"
193
+ cats = []
194
+ @site.categories.each { |title, posts_not_used|
195
+ cat = ""
196
+ title.split("/").each { |item|
197
+ if cat == ""
198
+ cat = item
199
+ else
200
+ cat = cat + "/" + item
201
+ end
202
+ cats << cat
203
+ }
204
+ }
205
+ cats = cats.uniq
206
+ for c in cats
207
+ tmp_posts = []
208
+ for post in @site.posts.docs
209
+ # printf("message in plugin\n")
210
+ if post.data["category"] && post.data["category"].start_with?(c)
211
+ tmp_posts << post
212
+ end
213
+ end
214
+ # printf("category:%s post count:%d\n", title, tmp_posts.size)
215
+ @archives << Archive.new(@site, c, "category", tmp_posts)
216
+ end
217
+ end
218
+ end
219
+
220
+ def read_dates
221
+ years.each do |year, y_posts|
222
+ append_enabled_date_type({ :year => year }, "year", y_posts)
223
+ months(y_posts).each do |month, m_posts|
224
+ append_enabled_date_type({ :year => year, :month => month }, "month", m_posts)
225
+ days(m_posts).each do |day, d_posts|
226
+ append_enabled_date_type({ :year => year, :month => month, :day => day }, "day", d_posts)
227
+ end
228
+ end
229
+ end
230
+ end
231
+
232
+ # Checks if archive type is enabled in config
233
+ def enabled?(archive)
234
+ @enabled == true || @enabled == "all" || (@enabled.is_a?(Array) && @enabled.include?(archive))
235
+ end
236
+
237
+ def tags
238
+ @site.tags
239
+ end
240
+
241
+ def categories
242
+ @site.categories
243
+ end
244
+
245
+ # Custom `post_attr_hash` method for years
246
+ def years
247
+ date_attr_hash(@posts.docs, "%Y")
248
+ end
249
+
250
+ # Custom `post_attr_hash` method for months
251
+ def months(year_posts)
252
+ date_attr_hash(year_posts, "%m")
253
+ end
254
+
255
+ # Custom `post_attr_hash` method for days
256
+ def days(month_posts)
257
+ date_attr_hash(month_posts, "%d")
258
+ end
259
+
260
+ private
261
+
262
+ # Initialize a new Archive page and append to base array if the associated date `type`
263
+ # has been enabled by configuration.
264
+ #
265
+ # meta - A Hash of the year / month / day as applicable for date.
266
+ # type - The type of date archive.
267
+ # posts - The array of posts that belong in the date archive.
268
+ def append_enabled_date_type(meta, type, posts)
269
+ @archives << Archive.new(@site, meta, type, posts) if enabled?(type)
270
+ end
271
+
272
+ # Custom `post_attr_hash` for date type archives.
273
+ #
274
+ # posts - Array of posts to be considered for archiving.
275
+ # id - String used to format post date via `Time.strptime` e.g. %Y, %m, etc.
276
+ def date_attr_hash(posts, id)
277
+ hash = Hash.new { |hsh, key| hsh[key] = [] }
278
+ posts.each { |post| hash[post.date.strftime(id)] << post }
279
+ hash.each_value { |posts| posts.sort!.reverse! }
280
+ hash
281
+ end
282
+ end
283
+ end
284
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-archives-dir-category
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alfred Xing
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-09-19 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.6'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.6'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rdoc
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop-jekyll
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.9'
103
+ - !ruby/object:Gem::Dependency
104
+ name: shoulda
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: Automatically generate post archives by dates, tags, and categories.
118
+ email:
119
+ executables: []
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - lib/jekyll-archives-dir-category.rb
124
+ - lib/jekyll-archives-dir-category/archive.rb
125
+ - lib/jekyll-archives-dir-category/version.rb
126
+ homepage: https://github.com/bijianing/jekyll-archives-dir-category
127
+ licenses:
128
+ - MIT
129
+ metadata: {}
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 2.3.0
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubygems_version: 3.1.6
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Post archives for Jekyll.
149
+ test_files: []