bridgetown-core 0.18.6 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bridgetown +6 -0
- data/bridgetown-core.gemspec +4 -4
- data/lib/bridgetown-core.rb +46 -13
- data/lib/bridgetown-core/cleaner.rb +7 -1
- data/lib/bridgetown-core/collection.rb +173 -77
- data/lib/bridgetown-core/commands/apply.rb +4 -3
- data/lib/bridgetown-core/commands/base.rb +9 -0
- data/lib/bridgetown-core/commands/concerns/actions.rb +0 -5
- data/lib/bridgetown-core/commands/configure.rb +66 -0
- data/lib/bridgetown-core/commands/console.rb +4 -0
- data/lib/bridgetown-core/commands/new.rb +28 -1
- data/lib/bridgetown-core/commands/plugins.rb +1 -0
- data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
- data/lib/bridgetown-core/concerns/site/configurable.rb +7 -3
- data/lib/bridgetown-core/concerns/site/content.rb +57 -15
- data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
- data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
- data/lib/bridgetown-core/concerns/site/writable.rb +11 -1
- data/lib/bridgetown-core/concerns/validatable.rb +1 -0
- data/lib/bridgetown-core/configuration.rb +39 -19
- data/lib/bridgetown-core/configurations/.keep +0 -0
- data/lib/bridgetown-core/configurations/bt-postcss.rb +26 -0
- data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +21 -0
- data/lib/bridgetown-core/configurations/minitesting.rb +95 -0
- data/lib/bridgetown-core/configurations/netlify.rb +6 -0
- data/lib/bridgetown-core/configurations/netlify/netlify.sh +14 -0
- data/lib/bridgetown-core/configurations/netlify/netlify.toml +44 -0
- data/lib/bridgetown-core/configurations/purgecss.rb +49 -0
- data/lib/bridgetown-core/configurations/stimulus.rb +49 -0
- data/lib/bridgetown-core/configurations/swup.rb +37 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +29 -0
- data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +4 -0
- data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +12 -0
- data/lib/bridgetown-core/configurations/turbo.rb +16 -0
- data/lib/bridgetown-core/converter.rb +14 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +6 -13
- data/lib/bridgetown-core/converters/identity.rb +0 -9
- data/lib/bridgetown-core/converters/markdown.rb +14 -4
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +3 -0
- data/lib/bridgetown-core/current.rb +10 -0
- data/lib/bridgetown-core/document.rb +6 -14
- data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
- data/lib/bridgetown-core/drops/page_drop.rb +4 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +81 -0
- data/lib/bridgetown-core/drops/site_drop.rb +33 -8
- data/lib/bridgetown-core/drops/unified_payload_drop.rb +4 -0
- data/lib/bridgetown-core/entry_filter.rb +10 -23
- data/lib/bridgetown-core/errors.rb +0 -2
- data/lib/bridgetown-core/filters.rb +4 -3
- data/lib/bridgetown-core/generator.rb +2 -1
- data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
- data/lib/bridgetown-core/layout.rb +2 -2
- data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
- data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
- data/lib/bridgetown-core/model/base.rb +138 -0
- data/lib/bridgetown-core/model/builder_origin.rb +40 -0
- data/lib/bridgetown-core/model/file_origin.rb +119 -0
- data/lib/bridgetown-core/model/origin.rb +38 -0
- data/lib/bridgetown-core/page.rb +9 -1
- data/lib/bridgetown-core/plugin.rb +2 -26
- data/lib/bridgetown-core/plugin_manager.rb +0 -2
- data/lib/bridgetown-core/publisher.rb +7 -1
- data/lib/bridgetown-core/reader.rb +25 -12
- data/lib/bridgetown-core/readers/data_reader.rb +3 -4
- data/lib/bridgetown-core/readers/post_reader.rb +1 -1
- data/lib/bridgetown-core/regenerator.rb +8 -1
- data/lib/bridgetown-core/related_posts.rb +1 -1
- data/lib/bridgetown-core/renderer.rb +5 -12
- data/lib/bridgetown-core/resource/base.rb +275 -0
- data/lib/bridgetown-core/resource/destination.rb +49 -0
- data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
- data/lib/bridgetown-core/resource/taxonomy_term.rb +25 -0
- data/lib/bridgetown-core/resource/taxonomy_type.rb +47 -0
- data/lib/bridgetown-core/resource/transformer.rb +173 -0
- data/lib/bridgetown-core/ruby_template_view.rb +13 -2
- data/lib/bridgetown-core/site.rb +9 -1
- data/lib/bridgetown-core/static_file.rb +33 -10
- data/lib/bridgetown-core/url.rb +1 -0
- data/lib/bridgetown-core/utils.rb +40 -40
- data/lib/bridgetown-core/utils/platforms.rb +1 -0
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/site_template/README.md +70 -0
- data/lib/site_template/frontend/javascript/index.js.erb +11 -0
- data/lib/site_template/frontend/styles/index.css +19 -0
- data/lib/site_template/{package.json → package.json.erb} +14 -8
- data/lib/site_template/postcss.config.js.erb +11 -0
- data/lib/site_template/src/_components/footer.liquid +1 -1
- data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
- data/lib/site_template/{webpack.config.js → webpack.config.js.erb} +47 -5
- metadata +67 -42
- data/lib/bridgetown-core/page_without_a_file.rb +0 -14
- data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
- data/lib/bridgetown-core/utils/exec.rb +0 -26
- data/lib/bridgetown-core/utils/internet.rb +0 -37
- data/lib/bridgetown-core/utils/win_tz.rb +0 -75
- data/lib/site_template/frontend/javascript/index.js +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c58653595832ef2fb9e6bbea3f147a0b3be9edae554d169e974570b84565a507
|
4
|
+
data.tar.gz: 7af409e9a01570321171cf1afc562c00cacdcc6e0dce98f2b8eac4988a60e8d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b21d9c304dd99dd306b70e97e172d1ec172f0d1fa48034610cc3d9e6bc9c40b98e7fe10479226103cb2ff501c22c7c2841f20630235262cc7214661be62bcf3e
|
7
|
+
data.tar.gz: cab7afb0f441e412850ce648d6e7ca9a3996f106b0800c31ef24a0cf63af9db770498f307da275860c0572d6d6f2a5f1e56570d10349bb11cd4f17f96b3266ee
|
data/bin/bridgetown
CHANGED
@@ -5,6 +5,12 @@ STDOUT.sync = true
|
|
5
5
|
|
6
6
|
$LOAD_PATH.unshift File.expand_path("../../bridgetown/lib", __dir__)
|
7
7
|
|
8
|
+
# Used by commands/automations
|
9
|
+
require "active_support"
|
10
|
+
require "active_support/core_ext/array/extract_options"
|
11
|
+
require "active_support/core_ext/string/strip"
|
12
|
+
require "active_support/core_ext/string/indent"
|
13
|
+
|
8
14
|
require "bridgetown"
|
9
15
|
|
10
16
|
Bridgetown::PluginManager.require_from_bundler
|
data/bridgetown-core.gemspec
CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.required_ruby_version = ">= 2.5.0"
|
32
32
|
s.required_rubygems_version = ">= 2.7.0"
|
33
33
|
|
34
|
+
s.add_runtime_dependency("activemodel", "~> 6.0")
|
34
35
|
s.add_runtime_dependency("activesupport", "~> 6.0")
|
35
36
|
s.add_runtime_dependency("addressable", "~> 2.4")
|
36
37
|
s.add_runtime_dependency("amazing_print", "~> 1.2")
|
@@ -42,14 +43,13 @@ Gem::Specification.new do |s|
|
|
42
43
|
s.add_runtime_dependency("i18n", "~> 1.0")
|
43
44
|
s.add_runtime_dependency("kramdown", "~> 2.1")
|
44
45
|
s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
|
45
|
-
s.add_runtime_dependency("liquid", "~>
|
46
|
+
s.add_runtime_dependency("liquid", "~> 5.0")
|
46
47
|
s.add_runtime_dependency("liquid-component", ">= 0.1")
|
47
|
-
s.add_runtime_dependency("liquid-render-tag", "~> 0.2")
|
48
48
|
s.add_runtime_dependency("listen", "~> 3.0")
|
49
|
-
s.add_runtime_dependency("pathutil", "~> 0.9")
|
50
49
|
s.add_runtime_dependency("rouge", "~> 3.0")
|
51
50
|
s.add_runtime_dependency("safe_yaml", "~> 1.0")
|
52
51
|
s.add_runtime_dependency("terminal-table", "~> 1.8")
|
53
|
-
s.add_runtime_dependency("thor", "~> 1.
|
52
|
+
s.add_runtime_dependency("thor", "~> 1.1")
|
54
53
|
s.add_runtime_dependency("tilt", "~> 2.0")
|
54
|
+
s.add_runtime_dependency("webrick", "~> 1.7")
|
55
55
|
end
|
data/lib/bridgetown-core.rb
CHANGED
@@ -18,6 +18,7 @@ end
|
|
18
18
|
require "rubygems"
|
19
19
|
|
20
20
|
# stdlib
|
21
|
+
require "find"
|
21
22
|
require "forwardable"
|
22
23
|
require "fileutils"
|
23
24
|
require "time"
|
@@ -29,20 +30,28 @@ require "csv"
|
|
29
30
|
require "json"
|
30
31
|
|
31
32
|
# 3rd party
|
33
|
+
require "active_support"
|
34
|
+
require "active_support/core_ext/hash/keys"
|
35
|
+
require "active_support/core_ext/module/delegation"
|
32
36
|
require "active_support/core_ext/object/blank"
|
37
|
+
require "active_support/core_ext/object/deep_dup"
|
38
|
+
require "active_support/core_ext/object/inclusion"
|
33
39
|
require "active_support/core_ext/string/inflections"
|
40
|
+
require "active_support/core_ext/string/inquiry"
|
41
|
+
require "active_support/core_ext/string/starts_ends_with"
|
42
|
+
require "active_support/current_attributes"
|
43
|
+
require "active_support/descendants_tracker"
|
34
44
|
require "hash_with_dot_access"
|
35
|
-
require "pathutil"
|
36
45
|
require "addressable/uri"
|
37
46
|
require "safe_yaml/load"
|
38
47
|
require "liquid"
|
39
|
-
require "liquid-render-tag"
|
40
48
|
require "liquid-component"
|
41
49
|
require "kramdown"
|
42
50
|
require "colorator"
|
43
51
|
require "i18n"
|
44
52
|
require "faraday"
|
45
53
|
require "thor"
|
54
|
+
require "zeitwerk"
|
46
55
|
|
47
56
|
module HashWithDotAccess
|
48
57
|
class Hash # :nodoc:
|
@@ -58,8 +67,17 @@ SafeYAML::OPTIONS[:suppress_warnings] = true
|
|
58
67
|
class Rb < String; end
|
59
68
|
SafeYAML::OPTIONS[:whitelisted_tags] = ["!ruby/string:Rb"]
|
60
69
|
|
70
|
+
if RUBY_VERSION.start_with?("3.0")
|
71
|
+
# workaround for Ruby 3 preview 2, maybe can remove later
|
72
|
+
# rubocop:disable Style/GlobalVars
|
73
|
+
old_verbose = $VERBOSE
|
74
|
+
$VERBOSE = nil
|
75
|
+
SafeYAML::SafeToRubyVisitor.const_set(:INITIALIZE_ARITY, 2)
|
76
|
+
$verbose = old_verbose
|
77
|
+
# rubocop:enable Style/GlobalVars
|
78
|
+
end
|
79
|
+
|
61
80
|
module Bridgetown
|
62
|
-
# internal requires
|
63
81
|
autoload :Cleaner, "bridgetown-core/cleaner"
|
64
82
|
autoload :Collection, "bridgetown-core/collection"
|
65
83
|
autoload :Configuration, "bridgetown-core/configuration"
|
@@ -67,30 +85,38 @@ module Bridgetown
|
|
67
85
|
autoload :Deprecator, "bridgetown-core/deprecator"
|
68
86
|
autoload :Document, "bridgetown-core/document"
|
69
87
|
autoload :EntryFilter, "bridgetown-core/entry_filter"
|
88
|
+
# TODO: we have too many errors! This is silly
|
70
89
|
autoload :Errors, "bridgetown-core/errors"
|
71
90
|
autoload :Excerpt, "bridgetown-core/excerpt"
|
91
|
+
# TODO: this is a poorly named, unclear class. Relocate to Utils:
|
72
92
|
autoload :External, "bridgetown-core/external"
|
73
93
|
autoload :FrontmatterDefaults, "bridgetown-core/frontmatter_defaults"
|
74
94
|
autoload :Hooks, "bridgetown-core/hooks"
|
75
95
|
autoload :Layout, "bridgetown-core/layout"
|
76
96
|
autoload :LayoutPlaceable, "bridgetown-core/concerns/layout_placeable"
|
77
97
|
autoload :Cache, "bridgetown-core/cache"
|
78
|
-
autoload :
|
98
|
+
autoload :Current, "bridgetown-core/current"
|
99
|
+
# TODO: remove this when legacy content engine is gone:
|
79
100
|
autoload :DataReader, "bridgetown-core/readers/data_reader"
|
80
101
|
autoload :DefaultsReader, "bridgetown-core/readers/defaults_reader"
|
81
102
|
autoload :LayoutReader, "bridgetown-core/readers/layout_reader"
|
103
|
+
# TODO: remove this when legacy content engine is gone:
|
82
104
|
autoload :PostReader, "bridgetown-core/readers/post_reader"
|
105
|
+
# TODO: we can merge this back into Reader class:
|
83
106
|
autoload :PageReader, "bridgetown-core/readers/page_reader"
|
84
107
|
autoload :PluginContentReader, "bridgetown-core/readers/plugin_content_reader"
|
108
|
+
# TODO: also merge this:
|
85
109
|
autoload :StaticFileReader, "bridgetown-core/readers/static_file_reader"
|
86
110
|
autoload :LogAdapter, "bridgetown-core/log_adapter"
|
87
111
|
autoload :Page, "bridgetown-core/page"
|
88
|
-
autoload :
|
112
|
+
autoload :GeneratedPage, "bridgetown-core/page"
|
113
|
+
# TODO: figure out how to get rid of this seemingly banal class:
|
89
114
|
autoload :PathManager, "bridgetown-core/path_manager"
|
90
115
|
autoload :PluginManager, "bridgetown-core/plugin_manager"
|
91
116
|
autoload :Publishable, "bridgetown-core/concerns/publishable"
|
92
117
|
autoload :Publisher, "bridgetown-core/publisher"
|
93
118
|
autoload :Reader, "bridgetown-core/reader"
|
119
|
+
# TODO: remove this when the incremental regenerator is gone:
|
94
120
|
autoload :Regenerator, "bridgetown-core/regenerator"
|
95
121
|
autoload :RelatedPosts, "bridgetown-core/related_posts"
|
96
122
|
autoload :Renderer, "bridgetown-core/renderer"
|
@@ -116,6 +142,7 @@ module Bridgetown
|
|
116
142
|
|
117
143
|
require "bridgetown-core/drops/drop"
|
118
144
|
require "bridgetown-core/drops/document_drop"
|
145
|
+
require "bridgetown-core/drops/resource_drop"
|
119
146
|
require_all "bridgetown-core/converters"
|
120
147
|
require_all "bridgetown-core/converters/markdown"
|
121
148
|
require_all "bridgetown-core/drops"
|
@@ -126,7 +153,7 @@ module Bridgetown
|
|
126
153
|
# Tells you which Bridgetown environment you are building in so
|
127
154
|
# you can skip tasks if you need to.
|
128
155
|
def environment
|
129
|
-
ENV["BRIDGETOWN_ENV"] || "development"
|
156
|
+
(ENV["BRIDGETOWN_ENV"] || "development").inquiry
|
130
157
|
end
|
131
158
|
alias_method :env, :environment
|
132
159
|
|
@@ -179,11 +206,7 @@ module Bridgetown
|
|
179
206
|
# @return [void]
|
180
207
|
# rubocop:disable Naming/AccessorMethodName
|
181
208
|
def set_timezone(timezone)
|
182
|
-
ENV["TZ"] =
|
183
|
-
Utils::WinTZ.calculate(timezone)
|
184
|
-
else
|
185
|
-
timezone
|
186
|
-
end
|
209
|
+
ENV["TZ"] = timezone
|
187
210
|
end
|
188
211
|
# rubocop:enable Naming/AccessorMethodName
|
189
212
|
|
@@ -204,11 +227,11 @@ module Bridgetown
|
|
204
227
|
@logger = LogAdapter.new(writer, (ENV["BRIDGETOWN_LOG_LEVEL"] || :info).to_sym)
|
205
228
|
end
|
206
229
|
|
207
|
-
#
|
230
|
+
# Deprecated. Now using the Current site.
|
208
231
|
#
|
209
232
|
# @return [Array<Bridgetown::Site>] the Bridgetown sites created.
|
210
233
|
def sites
|
211
|
-
|
234
|
+
[Bridgetown::Current.site].compact
|
212
235
|
end
|
213
236
|
|
214
237
|
# Ensures the questionable path is prefixed with the base directory
|
@@ -245,3 +268,13 @@ module Bridgetown
|
|
245
268
|
Bridgetown::External.require_if_present("liquid/c")
|
246
269
|
end
|
247
270
|
end
|
271
|
+
|
272
|
+
module Bridgetown
|
273
|
+
module Model; end
|
274
|
+
module Resource; end
|
275
|
+
end
|
276
|
+
|
277
|
+
loader = Zeitwerk::Loader.new
|
278
|
+
loader.push_dir File.join(__dir__, "bridgetown-core/model"), namespace: Bridgetown::Model
|
279
|
+
loader.push_dir File.join(__dir__, "bridgetown-core/resource"), namespace: Bridgetown::Resource
|
280
|
+
loader.setup # ready!
|
@@ -58,7 +58,13 @@ module Bridgetown
|
|
58
58
|
# Returns a Set with the file paths
|
59
59
|
def new_files
|
60
60
|
@new_files ||= Set.new.tap do |files|
|
61
|
-
site.each_site_file
|
61
|
+
site.each_site_file do |item|
|
62
|
+
files << if item.method(:destination).arity == 1
|
63
|
+
item.destination(site.dest)
|
64
|
+
else
|
65
|
+
item.destination.output_path
|
66
|
+
end
|
67
|
+
end
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
@@ -8,82 +8,104 @@ module Bridgetown
|
|
8
8
|
attr_reader :label, :metadata
|
9
9
|
attr_writer :docs
|
10
10
|
|
11
|
+
attr_writer :resources
|
12
|
+
|
11
13
|
# Create a new Collection.
|
12
14
|
#
|
13
|
-
# site
|
14
|
-
# label
|
15
|
-
#
|
16
|
-
# Returns nothing.
|
15
|
+
# @param site [Bridgetown::Site] the site to which this collection belongs
|
16
|
+
# @param label [String] the name of the collection
|
17
17
|
def initialize(site, label)
|
18
18
|
@site = site
|
19
19
|
@label = sanitize_label(label)
|
20
20
|
@metadata = extract_metadata
|
21
21
|
end
|
22
22
|
|
23
|
+
def builtin?
|
24
|
+
label.in? %w(posts pages data).freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def legacy_reader?
|
28
|
+
label.in? %w(posts data).freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
def data?
|
32
|
+
label == "data"
|
33
|
+
end
|
34
|
+
|
23
35
|
# Fetch the Documents in this collection.
|
24
36
|
# Defaults to an empty array if no documents have been read in.
|
25
37
|
#
|
26
|
-
#
|
38
|
+
# @return [Array<Bridgetown::Document>]
|
27
39
|
def docs
|
28
40
|
@docs ||= []
|
29
41
|
end
|
30
42
|
|
31
|
-
#
|
32
|
-
#
|
33
|
-
|
34
|
-
|
43
|
+
# Fetch the Resources in this collection.
|
44
|
+
# Defaults to an empty array if no resources have been read in.
|
45
|
+
#
|
46
|
+
# @return [Array<Bridgetown::Resource::Base>]
|
47
|
+
def resources
|
48
|
+
@resources ||= []
|
35
49
|
end
|
36
50
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
"#{label}.#{method} should be changed to #{label}.docs.#{method}."
|
42
|
-
Bridgetown.logger.warn "", "Called by #{caller(0..0)}."
|
43
|
-
docs.public_send(method.to_sym, *args, &blck)
|
44
|
-
else
|
45
|
-
super
|
46
|
-
end
|
51
|
+
# Iterate over either Resources or Documents depending on how the site is
|
52
|
+
# configured
|
53
|
+
def each(&block)
|
54
|
+
site.uses_resource? ? resources.each(&block) : docs.each(&block)
|
47
55
|
end
|
48
56
|
|
49
57
|
# Fetch the static files in this collection.
|
50
58
|
# Defaults to an empty array if no static files have been read in.
|
51
59
|
#
|
52
|
-
#
|
60
|
+
# @return [Array<Bridgetown::StaticFile>]
|
61
|
+
def static_files
|
62
|
+
@static_files ||= []
|
63
|
+
end
|
64
|
+
|
53
65
|
def files
|
54
|
-
|
66
|
+
Bridgetown::Deprecator.deprecation_message "Collection#files is now Collection#static_files"
|
67
|
+
static_files
|
55
68
|
end
|
56
69
|
|
57
70
|
# Read the allowed documents into the collection's array of docs.
|
58
71
|
#
|
59
|
-
#
|
60
|
-
def read
|
72
|
+
# @return [Bridgetown::Collection] self
|
73
|
+
def read # rubocop:todo Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
61
74
|
filtered_entries.each do |file_path|
|
62
75
|
full_path = collection_dir(file_path)
|
63
76
|
next if File.directory?(full_path)
|
64
77
|
|
65
|
-
if
|
78
|
+
if site.uses_resource?
|
79
|
+
next if File.basename(file_path).starts_with?("_")
|
80
|
+
|
81
|
+
if label == "data" || Utils.has_yaml_header?(full_path)
|
82
|
+
read_resource(full_path)
|
83
|
+
else
|
84
|
+
read_static_file(file_path, full_path)
|
85
|
+
end
|
86
|
+
elsif Utils.has_yaml_header? full_path
|
66
87
|
read_document(full_path)
|
67
88
|
else
|
68
89
|
read_static_file(file_path, full_path)
|
69
90
|
end
|
70
91
|
end
|
71
|
-
site.static_files.concat(
|
92
|
+
site.static_files.concat(static_files)
|
72
93
|
sort_docs!
|
94
|
+
|
95
|
+
self
|
73
96
|
end
|
74
97
|
|
75
98
|
# All the entries in this collection.
|
76
99
|
#
|
77
|
-
#
|
78
|
-
# relative to the collection's
|
100
|
+
# @return [Array<String>] file paths to the documents in this collection
|
101
|
+
# relative to the collection's folder
|
79
102
|
def entries
|
80
103
|
return [] unless exists?
|
81
104
|
|
82
105
|
@entries ||= begin
|
83
106
|
collection_dir_slash = "#{collection_dir}/"
|
84
107
|
Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry|
|
85
|
-
entry
|
86
|
-
entry
|
108
|
+
entry.sub(collection_dir_slash, "")
|
87
109
|
end
|
88
110
|
end
|
89
111
|
end
|
@@ -91,85 +113,87 @@ module Bridgetown
|
|
91
113
|
# Filtered version of the entries in this collection.
|
92
114
|
# See `Bridgetown::EntryFilter#filter` for more information.
|
93
115
|
#
|
94
|
-
#
|
116
|
+
# @return [Array<String>] list of filtered entry paths
|
95
117
|
def filtered_entries
|
96
118
|
return [] unless exists?
|
97
119
|
|
98
120
|
@filtered_entries ||=
|
99
|
-
Dir.chdir(
|
121
|
+
Dir.chdir(absolute_path) do
|
100
122
|
entry_filter.filter(entries).reject do |f|
|
101
123
|
path = collection_dir(f)
|
102
|
-
File.directory?(path)
|
124
|
+
File.directory?(path)
|
103
125
|
end
|
104
126
|
end
|
105
127
|
end
|
106
128
|
|
107
|
-
# The
|
108
|
-
# containing the collection.
|
129
|
+
# The folder name of this Collection, e.g. `_posts` or `_events`
|
109
130
|
#
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
@relative_directory ||= "_#{label}"
|
131
|
+
# @return [String]
|
132
|
+
def folder_name
|
133
|
+
@folder_name ||= "_#{label}"
|
114
134
|
end
|
135
|
+
alias_method :relative_directory, :folder_name
|
115
136
|
|
116
|
-
# The relative path to the
|
137
|
+
# The relative path to the folder containing the collection.
|
117
138
|
#
|
118
|
-
#
|
119
|
-
#
|
139
|
+
# @return [String] folder where the collection is stored relative to the
|
140
|
+
# configured collections folder (usually the site source)
|
120
141
|
def relative_path
|
121
|
-
Pathname.new(container).join(
|
142
|
+
Pathname.new(container).join(folder_name).to_s
|
122
143
|
end
|
123
144
|
|
124
|
-
# The full path to the
|
145
|
+
# The full path to the folder containing the collection.
|
125
146
|
#
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
@directory ||= site.in_source_dir(relative_path)
|
147
|
+
# @return [String] full path where the collection is stored on the filesystem
|
148
|
+
def absolute_path
|
149
|
+
@absolute_path ||= site.in_source_dir(relative_path)
|
130
150
|
end
|
151
|
+
alias_method :directory, :absolute_path
|
131
152
|
|
132
|
-
# The full path to the
|
153
|
+
# The full path to the folder containing the collection, with
|
133
154
|
# optional subpaths.
|
134
155
|
#
|
135
|
-
# *files
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# Returns a String containing th directory name where the collection
|
139
|
-
# is stored on the filesystem.
|
156
|
+
# @param *files [Array<String>] any other path pieces relative to the
|
157
|
+
# folder to append to the path
|
158
|
+
# @return [String]
|
140
159
|
def collection_dir(*files)
|
141
|
-
return
|
160
|
+
return absolute_path if files.empty?
|
142
161
|
|
143
|
-
site.in_source_dir(
|
162
|
+
site.in_source_dir(relative_path, *files)
|
144
163
|
end
|
145
164
|
|
146
|
-
# Checks whether the
|
165
|
+
# Checks whether the folder "exists" for this collection.
|
166
|
+
#
|
167
|
+
# @return [Boolean]
|
147
168
|
def exists?
|
148
|
-
File.directory?(
|
169
|
+
File.directory?(absolute_path)
|
149
170
|
end
|
150
171
|
|
151
172
|
# The entry filter for this collection.
|
152
|
-
# Creates an instance of Bridgetown::EntryFilter.
|
173
|
+
# Creates an instance of Bridgetown::EntryFilter if needed.
|
153
174
|
#
|
154
|
-
#
|
175
|
+
# @return [Bridgetown::EntryFilter]
|
155
176
|
def entry_filter
|
156
|
-
@entry_filter ||= Bridgetown::EntryFilter.new(
|
177
|
+
@entry_filter ||= Bridgetown::EntryFilter.new(
|
178
|
+
site,
|
179
|
+
base_directory: folder_name,
|
180
|
+
include_underscores: site.uses_resource?
|
181
|
+
)
|
157
182
|
end
|
158
183
|
|
159
184
|
# An inspect string.
|
160
185
|
#
|
161
|
-
#
|
186
|
+
# @return [String]
|
162
187
|
def inspect
|
163
|
-
"#<#{self.class} @label=#{label} docs=#{docs}>"
|
188
|
+
"#<#{self.class} @label=#{label} docs=#{docs} resources=#{resources}>"
|
164
189
|
end
|
165
190
|
|
166
191
|
# Produce a sanitized label name
|
167
192
|
# Label names may not contain anything but alphanumeric characters,
|
168
193
|
# underscores, and hyphens.
|
169
194
|
#
|
170
|
-
# label
|
171
|
-
#
|
172
|
-
# Returns a sanitized version of the label.
|
195
|
+
# @param label [String] the possibly-unsafe label
|
196
|
+
# @return [String] sanitized version of the label.
|
173
197
|
def sanitize_label(label)
|
174
198
|
label.gsub(%r![^a-z0-9_\-\.]!i, "")
|
175
199
|
end
|
@@ -179,7 +203,8 @@ module Bridgetown
|
|
179
203
|
# - label
|
180
204
|
# - docs
|
181
205
|
#
|
182
|
-
#
|
206
|
+
# @return [Bridgetown::Drops::CollectionDrop] representation of this
|
207
|
+
# collection for use in Liquid
|
183
208
|
def to_liquid
|
184
209
|
Drops::CollectionDrop.new self
|
185
210
|
end
|
@@ -187,14 +212,22 @@ module Bridgetown
|
|
187
212
|
# Whether the collection's documents ought to be written as individual
|
188
213
|
# files in the output.
|
189
214
|
#
|
190
|
-
#
|
215
|
+
# @return [Boolean] true if the 'write' metadata is true, false otherwise.
|
191
216
|
def write?
|
192
217
|
!!metadata.fetch("output", false)
|
193
218
|
end
|
194
219
|
|
195
|
-
#
|
220
|
+
# Used by Resource's permalink processor
|
221
|
+
# @return [String]
|
222
|
+
def default_permalink
|
223
|
+
metadata.fetch("permalink") do
|
224
|
+
"/:collection/:path/"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# LEGACY: The URL template to render collection's documents at.
|
196
229
|
#
|
197
|
-
#
|
230
|
+
# @return [String]
|
198
231
|
def url_template
|
199
232
|
@url_template ||= metadata.fetch("permalink") do
|
200
233
|
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
@@ -203,13 +236,47 @@ module Bridgetown
|
|
203
236
|
|
204
237
|
# Extract options for this collection from the site configuration.
|
205
238
|
#
|
206
|
-
#
|
239
|
+
# @return [HashWithDotAccess::Hash]
|
207
240
|
def extract_metadata
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
241
|
+
site.config.collections[label] || HashWithDotAccess::Hash.new
|
242
|
+
end
|
243
|
+
|
244
|
+
def merge_data_resources
|
245
|
+
data_contents = {}
|
246
|
+
|
247
|
+
sanitize_filename = ->(name) do
|
248
|
+
name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
|
249
|
+
.gsub(%r!\s+!, "_")
|
212
250
|
end
|
251
|
+
|
252
|
+
resources.each do |data_resource|
|
253
|
+
segments = data_resource.relative_path.each_filename.to_a[1..-1]
|
254
|
+
nested = []
|
255
|
+
segments.each_with_index do |segment, index|
|
256
|
+
sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
|
257
|
+
hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
|
258
|
+
hsh[sanitized_segment] = if index == segments.length - 1
|
259
|
+
data_resource.data.array || data_resource.data
|
260
|
+
else
|
261
|
+
{}
|
262
|
+
end
|
263
|
+
nested << sanitized_segment
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
merge_environment_specific_metadata(data_contents).with_dot_access
|
268
|
+
end
|
269
|
+
|
270
|
+
def merge_environment_specific_metadata(data_contents)
|
271
|
+
if data_contents["site_metadata"]
|
272
|
+
data_contents["site_metadata"][Bridgetown.environment]&.each_key do |k|
|
273
|
+
data_contents["site_metadata"][k] =
|
274
|
+
data_contents["site_metadata"][Bridgetown.environment][k]
|
275
|
+
end
|
276
|
+
data_contents["site_metadata"].delete(Bridgetown.environment)
|
277
|
+
end
|
278
|
+
|
279
|
+
data_contents
|
213
280
|
end
|
214
281
|
|
215
282
|
private
|
@@ -219,17 +286,28 @@ module Bridgetown
|
|
219
286
|
end
|
220
287
|
|
221
288
|
def read_document(full_path)
|
222
|
-
doc = Document.new(full_path, site: site, collection: self)
|
223
|
-
doc.read
|
289
|
+
doc = Document.new(full_path, site: site, collection: self).tap(&:read)
|
224
290
|
docs << doc if site.unpublished || doc.published?
|
225
291
|
end
|
226
292
|
|
293
|
+
def read_resource(full_path)
|
294
|
+
id = "file://#{label}.collection/" + Addressable::URI.escape(
|
295
|
+
Pathname(full_path).relative_path_from(Pathname(site.source)).to_s
|
296
|
+
)
|
297
|
+
resource = Bridgetown::Model::Base.find(id).to_resource.read!
|
298
|
+
resources << resource if site.unpublished || resource.published?
|
299
|
+
end
|
300
|
+
|
227
301
|
def sort_docs!
|
228
302
|
if metadata["sort_by"].is_a?(String)
|
229
303
|
sort_docs_by_key!
|
304
|
+
sort_resources_by_key!
|
230
305
|
else
|
231
306
|
docs.sort!
|
307
|
+
resources.sort!
|
232
308
|
end
|
309
|
+
docs.reverse! if metadata.sort_direction == "descending"
|
310
|
+
resources.reverse! if metadata.sort_direction == "descending"
|
233
311
|
end
|
234
312
|
|
235
313
|
# A custom sort function based on Schwartzian transform
|
@@ -252,6 +330,24 @@ module Bridgetown
|
|
252
330
|
end.map!(&:last)
|
253
331
|
end
|
254
332
|
|
333
|
+
def sort_resources_by_key!
|
334
|
+
meta_key = metadata["sort_by"]
|
335
|
+
# Modify `docs` array to cache document's property along with the Document instance
|
336
|
+
resources.map! { |doc| [doc.data[meta_key], doc] }.sort! do |apples, olives|
|
337
|
+
order = determine_sort_order(meta_key, apples, olives)
|
338
|
+
|
339
|
+
# Fall back to `Document#<=>` if the properties were equal or were non-sortable
|
340
|
+
# Otherwise continue with current sort-order
|
341
|
+
if order.nil? || order.zero?
|
342
|
+
apples[-1] <=> olives[-1]
|
343
|
+
else
|
344
|
+
order
|
345
|
+
end
|
346
|
+
|
347
|
+
# Finally restore the `docs` array with just the Document objects themselves
|
348
|
+
end.map!(&:last)
|
349
|
+
end
|
350
|
+
|
255
351
|
def determine_sort_order(sort_key, apples, olives)
|
256
352
|
apple_property, apple_document = apples
|
257
353
|
olive_property, olive_document = olives
|
@@ -277,7 +373,7 @@ module Bridgetown
|
|
277
373
|
File.dirname(file_path)
|
278
374
|
).chomp("/.")
|
279
375
|
|
280
|
-
|
376
|
+
static_files << StaticFile.new(
|
281
377
|
site,
|
282
378
|
site.source,
|
283
379
|
relative_dir,
|