jekyll-archives-v2 0.0.1

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: bd3853c2320099f7c356af52603b8cbcbe353a220a5b3f59ae5a4a54c087d9ec
4
+ data.tar.gz: 77a4dbb8bb3342964b79b224767c8d43805ad6640c2af2114ac826bc5645f9ec
5
+ SHA512:
6
+ metadata.gz: a25f649119ae3f1d982dfb41898af49c2898793b9057a8c45c64aaee20450d68e6002dcea3964bb46bb42372f381dd5497f205015884174d74ce33ca2cd7d6fb
7
+ data.tar.gz: 7c9fae3f1f46bd596d301337d2680210de53d797f07f22200ac5cb0737de183908686d2c2b897378406bde1499f9298ffacd2b51919f75300f0b412daf89fcd4
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module ArchivesV2
5
+ class Archive < Jekyll::Page
6
+ attr_accessor :collection_name, :documents, :type, :slug
7
+
8
+ # Attributes for Liquid templates
9
+ ATTRIBUTES_FOR_LIQUID = %w(
10
+ collection_name
11
+ documents
12
+ type
13
+ title
14
+ date
15
+ name
16
+ path
17
+ url
18
+ permalink
19
+ ).freeze
20
+
21
+ # Initialize a new Archive page
22
+ #
23
+ # site - The Site object.
24
+ # title - The name of the tag/category or a Hash of the year/month/day in case of date.
25
+ # e.g. { :year => 2014, :month => 08 } or "my-category" or "my-tag".
26
+ # type - The type of archive. Can be one of "year", "month", "day", "category", or "tag"
27
+ # collection_name - The name of the collection.
28
+ # documents - The array of documents that belong in this archive.
29
+ def initialize(site, title, type, collection_name, documents)
30
+ @site = site
31
+ @documents = documents
32
+ @type = type
33
+ @title = title
34
+ @collection_name = collection_name
35
+ @config = site.config["jekyll-archives"][collection_name]
36
+ @slug = slugify_string_title
37
+
38
+ # Use ".html" for file extension and url for path
39
+ @ext = File.extname(relative_path)
40
+ @path = relative_path
41
+ @name = File.basename(relative_path, @ext)
42
+
43
+ @data = {
44
+ "layout" => layout,
45
+ }
46
+ @content = ""
47
+ end
48
+
49
+ # The template of the permalink.
50
+ #
51
+ # Returns the template String.
52
+ def template
53
+ @config.dig("permalinks", type)
54
+ end
55
+
56
+ # The layout to use for rendering
57
+ #
58
+ # Returns the layout as a String
59
+ def layout
60
+ @config.dig("layouts", type) || @config["layout"]
61
+ end
62
+
63
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
64
+ # desired placeholder replacements. For details see "url.rb".
65
+ def url_placeholders
66
+ if @title.is_a? Hash
67
+ @title.merge(:collection => @collection_name, :type => @type)
68
+ else
69
+ { :collection => @collection_name, :name => @slug, :type => @type }
70
+ end
71
+ end
72
+
73
+ # The generated relative url of this page. e.g. /about.html.
74
+ #
75
+ # Returns the String url.
76
+ def url
77
+ @url ||= URL.new(
78
+ :template => template,
79
+ :placeholders => url_placeholders,
80
+ :permalink => nil
81
+ ).to_s
82
+ rescue ArgumentError
83
+ raise ArgumentError, "Template \"#{template}\" provided is invalid."
84
+ end
85
+
86
+ def permalink
87
+ data&.is_a?(Hash) && data["permalink"]
88
+ end
89
+
90
+ # Produce a title object suitable for Liquid based on type of archive.
91
+ #
92
+ # Returns a String (for tag and category archives) and nil for
93
+ # date-based archives.
94
+ def title
95
+ @title if @title.is_a? String
96
+ end
97
+
98
+ # Produce a date object if a date-based archive
99
+ #
100
+ # Returns a Date.
101
+ def date
102
+ return unless @title.is_a?(Hash)
103
+
104
+ @date ||= begin
105
+ args = @title.values.map(&:to_i)
106
+ Date.new(*args)
107
+ end
108
+ end
109
+
110
+ # Obtain the write path relative to the destination directory
111
+ #
112
+ # Returns the destination relative path String.
113
+ def relative_path
114
+ @relative_path ||= begin
115
+ path = URL.unescape_path(url).gsub(%r!^/!, "")
116
+ path = File.join(path, "index.html") if url.end_with?("/")
117
+ path
118
+ end
119
+ end
120
+
121
+ # Returns the object as a debug String.
122
+ def inspect
123
+ "#<Jekyll:Archive @type=#{@type} @title=#{@title} @data=#{@data.inspect}>"
124
+ end
125
+
126
+ # The Liquid representation of this page.
127
+ def to_liquid
128
+ @to_liquid ||= Jekyll::ArchivesV2::PageDrop.new(self)
129
+ end
130
+
131
+ private
132
+
133
+ # Generate slug if @title attribute is a string.
134
+ #
135
+ # Note: mode other than those expected by Jekyll returns the given string after
136
+ # downcasing it.
137
+ def slugify_string_title
138
+ return unless title.is_a?(String)
139
+
140
+ Utils.slugify(title, :mode => @config["slug_mode"])
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module ArchivesV2
5
+ class PageDrop < Jekyll::Drops::Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegators :@obj, :posts, :type, :title, :date, :name, :path, :url, :permalink
11
+ private def_delegator :@obj, :data, :fallback_data
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module ArchivesV2
5
+ VERSION = "0.0.1"
6
+ end
7
+ end
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ module Jekyll
6
+ module ArchivesV2
7
+ # Internal requires
8
+ autoload :Archive, "jekyll-archives-v2/archive"
9
+ autoload :PageDrop, "jekyll-archives-v2/page_drop"
10
+ autoload :VERSION, "jekyll-archives-v2/version"
11
+
12
+ class Archives < Jekyll::Generator
13
+ safe true
14
+
15
+ def initialize(config = {})
16
+ defaults = {}
17
+ config.fetch("collections", {}).each do |name, collection|
18
+ defaults[name] = {
19
+ "layout" => "archive",
20
+ "enabled" => [],
21
+ "permalinks" => {
22
+ "year" => "/#{name}/:year/",
23
+ "month" => "/#{name}/:year/:month/",
24
+ "day" => "/#{name}/:year/:month/:day/",
25
+ "tag" => "/#{name}/tag/:name/",
26
+ "category" => "/#{name}/category/:name/",
27
+ },
28
+ }
29
+ end
30
+ defaults.freeze
31
+ archives_config = config.fetch("jekyll-archives", {})
32
+ if archives_config.is_a?(Hash)
33
+ @config = Utils.deep_merge_hashes(defaults, archives_config)
34
+ else
35
+ @config = nil
36
+ Jekyll.logger.warn "Archives:", "Expected a hash but got #{archives_config.inspect}"
37
+ Jekyll.logger.warn "", "Archives will not be generated for this site."
38
+ end
39
+ end
40
+
41
+ def generate(site)
42
+ return if @config.nil?
43
+
44
+ @site = site
45
+ @collections = site.collections
46
+ @archives = []
47
+
48
+ @site.config["jekyll-archives"] = @config
49
+
50
+ # loop through collections keys and read them
51
+ @config.each do |collection_name, collection_config|
52
+ read(collection_name)
53
+ end
54
+
55
+ @site.pages.concat(@archives)
56
+ @site.config["archives"] = @archives
57
+ end
58
+
59
+ # Read archive data from collection
60
+ def read(collection_name)
61
+ if enabled?(collection_name, "tags")
62
+ read_tags(collection_name)
63
+ end
64
+
65
+ if enabled?(collection_name, "categories")
66
+ read_categories(collection_name)
67
+ end
68
+
69
+ if enabled?(collection_name, "year") || enabled?(collection_name, "month") || enabled?(collection_name, "day")
70
+ read_dates(collection_name)
71
+ end
72
+ end
73
+
74
+ def read_tags(collection_name)
75
+ tags(@collections[collection_name]).each do |title, documents|
76
+ @archives << Archive.new(@site, title, "tag", collection_name, documents)
77
+ end
78
+ end
79
+
80
+ def read_categories(collection_name)
81
+ categories(@collections[collection_name]).each do |title, documents|
82
+ @archives << Archive.new(@site, title, "category", collection_name, documents)
83
+ end
84
+ end
85
+
86
+ def read_dates(collection_name)
87
+ years(@collections[collection_name]).each do |year, y_documents|
88
+ append_enabled_date_type({ :year => year }, "year", collection_name, y_posts)
89
+ months(y_documents).each do |month, m_documents|
90
+ append_enabled_date_type({ :year => year, :month => month }, "month", collection_name, m_posts)
91
+ days(m_documents).each do |day, d_documents|
92
+ append_enabled_date_type({ :year => year, :month => month, :day => day }, "day", collection_name, d_posts)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ # Checks if archive type is enabled in config
99
+ def enabled?(collection_name, archive)
100
+ @enabled == true || @enabled == "all" || (@enabled.is_a?(Array) && @enabled.include?(archive))
101
+ end
102
+
103
+ def tags(documents)
104
+ doc_attr_hash(documents, "tags")
105
+ end
106
+
107
+ def categories(documents)
108
+ doc_attr_hash(documents, "categories")
109
+ end
110
+
111
+ # Custom `post_attr_hash` method for years
112
+ def years(documents)
113
+ date_attr_hash(documents, "%Y")
114
+ end
115
+
116
+ # Custom `post_attr_hash` method for months
117
+ def months(year_documents)
118
+ date_attr_hash(year_documents, "%m")
119
+ end
120
+
121
+ # Custom `post_attr_hash` method for days
122
+ def days(month_documents)
123
+ date_attr_hash(month_documents, "%d")
124
+ end
125
+
126
+ private
127
+
128
+ # Initialize a new Archive page and append to base array if the associated date `type`
129
+ # has been enabled by configuration.
130
+ #
131
+ # meta - A Hash of the year / month / day as applicable for date.
132
+ # type - The type of date archive.
133
+ # collection_name - the name of the collection
134
+ # documents - The array of documents that belong in the date archive.
135
+ def append_enabled_date_type(meta, type, collection_name, documents)
136
+ @archives << Archive.new(@site, meta, type, collection_name, documents) if enabled?(collection_name, type)
137
+ end
138
+
139
+ # Custom `post_attr_hash` for date type archives.
140
+ #
141
+ # documents - Array of documents to be considered for archiving.
142
+ # id - String used to format post date via `Time.strptime` e.g. %Y, %m, etc.
143
+ def date_attr_hash(documents, id)
144
+ hash = Hash.new { |hsh, key| hsh[key] = [] }
145
+ documents.each { |document| hash[document.date.strftime(id)] << document }
146
+ hash.each_value { |documents| documents.sort!.reverse! }
147
+ hash
148
+ end
149
+
150
+ # Custom `post_attr_hash` for any collection.
151
+ #
152
+ # documents - Array of documents to be considered for archiving.
153
+ # doc_attr - The String name of the Document attribute.
154
+ def doc_attr_hash(documents, doc_attr)
155
+ # Build a hash map based on the specified document attribute ( doc_attr =>
156
+ # array of elements from collection ) then sort each array in reverse order.
157
+ hash = Hash.new { |h, key| h[key] = [] }
158
+ documents.docs.each { |document| document.data[doc_attr]&.each { |t| hash[t] << document } }
159
+ hash.each_value { |documents| documents.sort!.reverse! }
160
+ hash
161
+ end
162
+ end
163
+ end
164
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-archives-v2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - George Corrêa de Araújo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-11-29 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 collections archives by dates, tags, and categories.
118
+ email:
119
+ executables: []
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - lib/jekyll-archives-v2/archive.rb
124
+ - lib/jekyll-archives-v2/page_drop.rb
125
+ - lib/jekyll-archives-v2/version.rb
126
+ - lib/jekyll-archives.rb
127
+ homepage: https://github.com/george-gca/jekyll-archives-v2
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 2.3.0
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 3.4.20
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: Collections archives for Jekyll.
150
+ test_files: []