bridgetown-core 0.19.2 → 0.21.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bridgetown-core.gemspec +1 -2
- data/lib/bridgetown-core.rb +37 -29
- data/lib/bridgetown-core/cleaner.rb +9 -3
- data/lib/bridgetown-core/collection.rb +177 -78
- data/lib/bridgetown-core/commands/base.rb +9 -0
- data/lib/bridgetown-core/commands/build.rb +0 -11
- data/lib/bridgetown-core/commands/concerns/git_helpers.rb +20 -0
- data/lib/bridgetown-core/commands/configure.rb +8 -3
- data/lib/bridgetown-core/commands/console.rb +4 -0
- data/lib/bridgetown-core/commands/doctor.rb +1 -19
- data/lib/bridgetown-core/commands/new.rb +2 -2
- data/lib/bridgetown-core/commands/plugins.rb +14 -13
- data/lib/bridgetown-core/commands/serve.rb +0 -14
- data/lib/bridgetown-core/component.rb +178 -0
- data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
- data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
- data/lib/bridgetown-core/concerns/site/configurable.rb +10 -10
- data/lib/bridgetown-core/concerns/site/content.rb +56 -15
- data/lib/bridgetown-core/concerns/site/localizable.rb +3 -5
- data/lib/bridgetown-core/concerns/site/processable.rb +6 -4
- data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
- data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
- data/lib/bridgetown-core/concerns/validatable.rb +2 -5
- data/lib/bridgetown-core/configuration.rb +51 -30
- data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -3
- data/lib/bridgetown-core/configurations/netlify.rb +1 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +1 -3
- data/lib/bridgetown-core/converter.rb +23 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +51 -35
- data/lib/bridgetown-core/converters/identity.rb +0 -9
- data/lib/bridgetown-core/converters/liquid_templates.rb +1 -1
- data/lib/bridgetown-core/converters/markdown.rb +14 -4
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +5 -38
- data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
- data/lib/bridgetown-core/converters/smartypants.rb +3 -1
- data/lib/bridgetown-core/core_ext/psych.rb +19 -0
- data/lib/bridgetown-core/current.rb +10 -0
- data/lib/bridgetown-core/document.rb +9 -16
- 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/relations_drop.rb +23 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
- data/lib/bridgetown-core/drops/site_drop.rb +33 -8
- data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
- data/lib/bridgetown-core/entry_filter.rb +17 -28
- data/lib/bridgetown-core/errors.rb +0 -2
- data/lib/bridgetown-core/filters.rb +3 -26
- data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
- data/lib/bridgetown-core/filters/url_filters.rb +12 -0
- data/lib/bridgetown-core/frontmatter_defaults.rb +1 -1
- data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
- data/lib/bridgetown-core/helpers.rb +48 -9
- data/lib/bridgetown-core/layout.rb +28 -13
- 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/origin.rb +38 -0
- data/lib/bridgetown-core/model/repo_origin.rb +126 -0
- data/lib/bridgetown-core/page.rb +11 -2
- data/lib/bridgetown-core/plugin_manager.rb +1 -3
- data/lib/bridgetown-core/publisher.rb +8 -2
- data/lib/bridgetown-core/reader.rb +37 -22
- data/lib/bridgetown-core/readers/data_reader.rb +5 -5
- data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
- data/lib/bridgetown-core/readers/page_reader.rb +1 -0
- data/lib/bridgetown-core/readers/post_reader.rb +5 -4
- data/lib/bridgetown-core/regenerator.rb +9 -2
- data/lib/bridgetown-core/related_posts.rb +9 -6
- data/lib/bridgetown-core/renderer.rb +6 -13
- data/lib/bridgetown-core/resource/base.rb +313 -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/relations.rb +132 -0
- data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
- data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
- data/lib/bridgetown-core/resource/transformer.rb +177 -0
- data/lib/bridgetown-core/ruby_template_view.rb +11 -11
- data/lib/bridgetown-core/site.rb +13 -6
- data/lib/bridgetown-core/static_file.rb +33 -10
- data/lib/bridgetown-core/tags/highlight.rb +2 -15
- data/lib/bridgetown-core/tags/include.rb +1 -1
- data/lib/bridgetown-core/tags/post_url.rb +2 -2
- data/lib/bridgetown-core/url.rb +1 -0
- data/lib/bridgetown-core/utils.rb +49 -43
- data/lib/bridgetown-core/utils/require_gems.rb +60 -0
- data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
- data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +1 -1
- data/lib/bridgetown-core/yaml_parser.rb +22 -0
- data/lib/site_template/package.json.erb +2 -2
- data/lib/site_template/plugins/site_builder.rb +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.erb +26 -6
- metadata +39 -40
- data/lib/bridgetown-core/external.rb +0 -58
- data/lib/bridgetown-core/page_without_a_file.rb +0 -17
- data/lib/bridgetown-core/path_manager.rb +0 -31
- data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
- data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
- data/lib/bridgetown-core/utils/exec.rb +0 -26
- data/lib/bridgetown-core/utils/internet.rb +0 -37
- data/lib/bridgetown-core/utils/platforms.rb +0 -80
- data/lib/bridgetown-core/utils/thread_event.rb +0 -31
- data/lib/bridgetown-core/utils/win_tz.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc153d4826e8e0678bea76a9e2c251040123418ab9cfe0b1243b7f38cb8f1ec5
|
4
|
+
data.tar.gz: '08d6c10878993b10963dc1a89058c8b0a9dbd57a5ed2b399963a68ea537ea5f8'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7151ae352509556c2b6b7e524e56186a3c782746dc1f2090756a37e9325c9153e48a03daf720e64fd0450e472a43b96c3e9b90ec53896d409881ab33b8aabea0
|
7
|
+
data.tar.gz: 42289c4f1da1116e37fa50bdb49345264e2a56a719f1e76691eb294721a1b4c834909ab7dc22691d238bec4df509c6680c479fa7b6fec8831f69d79bee8fef6b
|
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")
|
@@ -45,9 +46,7 @@ Gem::Specification.new do |s|
|
|
45
46
|
s.add_runtime_dependency("liquid", "~> 5.0")
|
46
47
|
s.add_runtime_dependency("liquid-component", ">= 0.1")
|
47
48
|
s.add_runtime_dependency("listen", "~> 3.0")
|
48
|
-
s.add_runtime_dependency("pathutil", "~> 0.9")
|
49
49
|
s.add_runtime_dependency("rouge", "~> 3.0")
|
50
|
-
s.add_runtime_dependency("safe_yaml", "~> 1.0")
|
51
50
|
s.add_runtime_dependency("terminal-table", "~> 1.8")
|
52
51
|
s.add_runtime_dependency("thor", "~> 1.1")
|
53
52
|
s.add_runtime_dependency("tilt", "~> 2.0")
|
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"
|
@@ -27,19 +28,23 @@ require "logger"
|
|
27
28
|
require "set"
|
28
29
|
require "csv"
|
29
30
|
require "json"
|
31
|
+
require "yaml"
|
30
32
|
|
31
33
|
# 3rd party
|
32
34
|
require "active_support"
|
33
35
|
require "active_support/core_ext/hash/keys"
|
36
|
+
require "active_support/core_ext/module/delegation"
|
34
37
|
require "active_support/core_ext/object/blank"
|
38
|
+
require "active_support/core_ext/object/deep_dup"
|
39
|
+
require "active_support/core_ext/object/inclusion"
|
35
40
|
require "active_support/core_ext/string/inflections"
|
36
41
|
require "active_support/core_ext/string/inquiry"
|
42
|
+
require "active_support/core_ext/string/output_safety"
|
37
43
|
require "active_support/core_ext/string/starts_ends_with"
|
44
|
+
require "active_support/current_attributes"
|
38
45
|
require "active_support/descendants_tracker"
|
39
46
|
require "hash_with_dot_access"
|
40
|
-
require "pathutil"
|
41
47
|
require "addressable/uri"
|
42
|
-
require "safe_yaml/load"
|
43
48
|
require "liquid"
|
44
49
|
require "liquid-component"
|
45
50
|
require "kramdown"
|
@@ -47,6 +52,7 @@ require "colorator"
|
|
47
52
|
require "i18n"
|
48
53
|
require "faraday"
|
49
54
|
require "thor"
|
55
|
+
require "zeitwerk"
|
50
56
|
|
51
57
|
module HashWithDotAccess
|
52
58
|
class Hash # :nodoc:
|
@@ -56,55 +62,45 @@ module HashWithDotAccess
|
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
59
|
-
SafeYAML::OPTIONS[:suppress_warnings] = true
|
60
|
-
|
61
65
|
# Create our little String subclass for Ruby Front Matter
|
62
66
|
class Rb < String; end
|
63
|
-
SafeYAML::OPTIONS[:whitelisted_tags] = ["!ruby/string:Rb"]
|
64
|
-
|
65
|
-
if RUBY_VERSION.start_with?("3.0")
|
66
|
-
# workaround for Ruby 3 preview 2, maybe can remove later
|
67
|
-
# rubocop:disable Style/GlobalVars
|
68
|
-
old_verbose = $VERBOSE
|
69
|
-
$VERBOSE = nil
|
70
|
-
SafeYAML::SafeToRubyVisitor.const_set(:INITIALIZE_ARITY, 2)
|
71
|
-
$verbose = old_verbose
|
72
|
-
# rubocop:enable Style/GlobalVars
|
73
|
-
end
|
74
67
|
|
75
68
|
module Bridgetown
|
76
|
-
# internal requires
|
77
69
|
autoload :Cleaner, "bridgetown-core/cleaner"
|
78
70
|
autoload :Collection, "bridgetown-core/collection"
|
71
|
+
autoload :Component, "bridgetown-core/component"
|
79
72
|
autoload :Configuration, "bridgetown-core/configuration"
|
80
73
|
autoload :DataAccessible, "bridgetown-core/concerns/data_accessible"
|
81
74
|
autoload :Deprecator, "bridgetown-core/deprecator"
|
82
75
|
autoload :Document, "bridgetown-core/document"
|
83
76
|
autoload :EntryFilter, "bridgetown-core/entry_filter"
|
77
|
+
# TODO: we have too many errors! This is silly
|
84
78
|
autoload :Errors, "bridgetown-core/errors"
|
85
79
|
autoload :Excerpt, "bridgetown-core/excerpt"
|
86
|
-
autoload :External, "bridgetown-core/external"
|
87
80
|
autoload :FrontmatterDefaults, "bridgetown-core/frontmatter_defaults"
|
81
|
+
autoload :FrontMatterImporter, "bridgetown-core/concerns/front_matter_importer"
|
88
82
|
autoload :Hooks, "bridgetown-core/hooks"
|
89
83
|
autoload :Layout, "bridgetown-core/layout"
|
90
84
|
autoload :LayoutPlaceable, "bridgetown-core/concerns/layout_placeable"
|
91
85
|
autoload :Cache, "bridgetown-core/cache"
|
92
|
-
autoload :
|
86
|
+
autoload :Current, "bridgetown-core/current"
|
87
|
+
# TODO: remove this when legacy content engine is gone:
|
93
88
|
autoload :DataReader, "bridgetown-core/readers/data_reader"
|
94
89
|
autoload :DefaultsReader, "bridgetown-core/readers/defaults_reader"
|
95
90
|
autoload :LayoutReader, "bridgetown-core/readers/layout_reader"
|
91
|
+
# TODO: remove this when legacy content engine is gone:
|
96
92
|
autoload :PostReader, "bridgetown-core/readers/post_reader"
|
93
|
+
# TODO: remove this when legacy content engine is gone:
|
97
94
|
autoload :PageReader, "bridgetown-core/readers/page_reader"
|
98
95
|
autoload :PluginContentReader, "bridgetown-core/readers/plugin_content_reader"
|
99
|
-
autoload :StaticFileReader, "bridgetown-core/readers/static_file_reader"
|
100
96
|
autoload :LogAdapter, "bridgetown-core/log_adapter"
|
101
97
|
autoload :Page, "bridgetown-core/page"
|
102
|
-
autoload :
|
103
|
-
autoload :PathManager, "bridgetown-core/path_manager"
|
98
|
+
autoload :GeneratedPage, "bridgetown-core/page"
|
104
99
|
autoload :PluginManager, "bridgetown-core/plugin_manager"
|
105
100
|
autoload :Publishable, "bridgetown-core/concerns/publishable"
|
106
101
|
autoload :Publisher, "bridgetown-core/publisher"
|
107
102
|
autoload :Reader, "bridgetown-core/reader"
|
103
|
+
# TODO: remove this when the incremental regenerator is gone:
|
108
104
|
autoload :Regenerator, "bridgetown-core/regenerator"
|
109
105
|
autoload :RelatedPosts, "bridgetown-core/related_posts"
|
110
106
|
autoload :Renderer, "bridgetown-core/renderer"
|
@@ -119,6 +115,7 @@ module Bridgetown
|
|
119
115
|
autoload :Validatable, "bridgetown-core/concerns/validatable"
|
120
116
|
autoload :VERSION, "bridgetown-core/version"
|
121
117
|
autoload :Watcher, "bridgetown-core/watcher"
|
118
|
+
autoload :YAMLParser, "bridgetown-core/yaml_parser"
|
122
119
|
|
123
120
|
# extensions
|
124
121
|
require "bridgetown-core/commands/registrations"
|
@@ -130,11 +127,13 @@ module Bridgetown
|
|
130
127
|
|
131
128
|
require "bridgetown-core/drops/drop"
|
132
129
|
require "bridgetown-core/drops/document_drop"
|
130
|
+
require "bridgetown-core/drops/resource_drop"
|
133
131
|
require_all "bridgetown-core/converters"
|
134
132
|
require_all "bridgetown-core/converters/markdown"
|
135
133
|
require_all "bridgetown-core/drops"
|
136
134
|
require_all "bridgetown-core/generators"
|
137
135
|
require_all "bridgetown-core/tags"
|
136
|
+
require_all "bridgetown-core/core_ext"
|
138
137
|
|
139
138
|
class << self
|
140
139
|
# Tells you which Bridgetown environment you are building in so
|
@@ -193,11 +192,7 @@ module Bridgetown
|
|
193
192
|
# @return [void]
|
194
193
|
# rubocop:disable Naming/AccessorMethodName
|
195
194
|
def set_timezone(timezone)
|
196
|
-
ENV["TZ"] =
|
197
|
-
Utils::WinTZ.calculate(timezone)
|
198
|
-
else
|
199
|
-
timezone
|
200
|
-
end
|
195
|
+
ENV["TZ"] = timezone
|
201
196
|
end
|
202
197
|
# rubocop:enable Naming/AccessorMethodName
|
203
198
|
|
@@ -218,11 +213,11 @@ module Bridgetown
|
|
218
213
|
@logger = LogAdapter.new(writer, (ENV["BRIDGETOWN_LOG_LEVEL"] || :info).to_sym)
|
219
214
|
end
|
220
215
|
|
221
|
-
#
|
216
|
+
# Deprecated. Now using the Current site.
|
222
217
|
#
|
223
218
|
# @return [Array<Bridgetown::Site>] the Bridgetown sites created.
|
224
219
|
def sites
|
225
|
-
|
220
|
+
[Bridgetown::Current.site].compact
|
226
221
|
end
|
227
222
|
|
228
223
|
# Ensures the questionable path is prefixed with the base directory
|
@@ -256,6 +251,19 @@ module Bridgetown
|
|
256
251
|
end
|
257
252
|
|
258
253
|
# Conditional optimizations
|
259
|
-
Bridgetown::
|
254
|
+
Bridgetown::Utils::RequireGems.require_if_present("liquid/c")
|
260
255
|
end
|
261
256
|
end
|
257
|
+
|
258
|
+
module Bridgetown
|
259
|
+
module Model; end
|
260
|
+
module Resource; end
|
261
|
+
end
|
262
|
+
|
263
|
+
# This method is available in Ruby 3, monkey patching for older versions
|
264
|
+
Psych.extend Bridgetown::CoreExt::Psych::SafeLoadFile unless Psych.respond_to?(:safe_load_file)
|
265
|
+
|
266
|
+
loader = Zeitwerk::Loader.new
|
267
|
+
loader.push_dir File.join(__dir__, "bridgetown-core/model"), namespace: Bridgetown::Model
|
268
|
+
loader.push_dir File.join(__dir__, "bridgetown-core/resource"), namespace: Bridgetown::Resource
|
269
|
+
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
|
|
@@ -95,7 +101,7 @@ module Bridgetown
|
|
95
101
|
#
|
96
102
|
# Returns a Set with the directory paths
|
97
103
|
def keep_dirs
|
98
|
-
site.keep_files.flat_map { |file| parent_dirs(site.in_dest_dir(file)) }.to_set
|
104
|
+
site.config.keep_files.flat_map { |file| parent_dirs(site.in_dest_dir(file)) }.to_set
|
99
105
|
end
|
100
106
|
|
101
107
|
# Private: Creates a regular expression from the config's keep_files array
|
@@ -106,7 +112,7 @@ module Bridgetown
|
|
106
112
|
#
|
107
113
|
# Returns the regular expression
|
108
114
|
def keep_file_regex
|
109
|
-
%r!\A#{Regexp.quote(site.dest)}\/(#{Regexp.union(site.keep_files).source})!
|
115
|
+
%r!\A#{Regexp.quote(site.dest)}\/(#{Regexp.union(site.config.keep_files).source})!
|
110
116
|
end
|
111
117
|
end
|
112
118
|
end
|
@@ -8,82 +8,105 @@ 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
|
+
Utils.has_rbfm_header?(full_path)
|
83
|
+
read_resource(full_path)
|
84
|
+
else
|
85
|
+
read_static_file(file_path, full_path)
|
86
|
+
end
|
87
|
+
elsif Utils.has_yaml_header? full_path
|
66
88
|
read_document(full_path)
|
67
89
|
else
|
68
90
|
read_static_file(file_path, full_path)
|
69
91
|
end
|
70
92
|
end
|
71
|
-
site.static_files.concat(
|
93
|
+
site.static_files.concat(static_files)
|
72
94
|
sort_docs!
|
95
|
+
|
96
|
+
self
|
73
97
|
end
|
74
98
|
|
75
99
|
# All the entries in this collection.
|
76
100
|
#
|
77
|
-
#
|
78
|
-
# relative to the collection's
|
101
|
+
# @return [Array<String>] file paths to the documents in this collection
|
102
|
+
# relative to the collection's folder
|
79
103
|
def entries
|
80
104
|
return [] unless exists?
|
81
105
|
|
82
106
|
@entries ||= begin
|
83
107
|
collection_dir_slash = "#{collection_dir}/"
|
84
108
|
Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry|
|
85
|
-
entry
|
86
|
-
entry
|
109
|
+
entry.sub(collection_dir_slash, "")
|
87
110
|
end
|
88
111
|
end
|
89
112
|
end
|
@@ -91,85 +114,87 @@ module Bridgetown
|
|
91
114
|
# Filtered version of the entries in this collection.
|
92
115
|
# See `Bridgetown::EntryFilter#filter` for more information.
|
93
116
|
#
|
94
|
-
#
|
117
|
+
# @return [Array<String>] list of filtered entry paths
|
95
118
|
def filtered_entries
|
96
119
|
return [] unless exists?
|
97
120
|
|
98
121
|
@filtered_entries ||=
|
99
|
-
Dir.chdir(
|
122
|
+
Dir.chdir(absolute_path) do
|
100
123
|
entry_filter.filter(entries).reject do |f|
|
101
124
|
path = collection_dir(f)
|
102
|
-
File.directory?(path)
|
125
|
+
File.directory?(path)
|
103
126
|
end
|
104
127
|
end
|
105
128
|
end
|
106
129
|
|
107
|
-
# The
|
108
|
-
# containing the collection.
|
130
|
+
# The folder name of this Collection, e.g. `_posts` or `_events`
|
109
131
|
#
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
@relative_directory ||= "_#{label}"
|
132
|
+
# @return [String]
|
133
|
+
def folder_name
|
134
|
+
@folder_name ||= "_#{label}"
|
114
135
|
end
|
136
|
+
alias_method :relative_directory, :folder_name
|
115
137
|
|
116
|
-
# The relative path to the
|
138
|
+
# The relative path to the folder containing the collection.
|
117
139
|
#
|
118
|
-
#
|
119
|
-
#
|
140
|
+
# @return [String] folder where the collection is stored relative to the
|
141
|
+
# configured collections folder (usually the site source)
|
120
142
|
def relative_path
|
121
|
-
Pathname.new(container).join(
|
143
|
+
Pathname.new(container).join(folder_name).to_s
|
122
144
|
end
|
123
145
|
|
124
|
-
# The full path to the
|
146
|
+
# The full path to the folder containing the collection.
|
125
147
|
#
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
@directory ||= site.in_source_dir(relative_path)
|
148
|
+
# @return [String] full path where the collection is stored on the filesystem
|
149
|
+
def absolute_path
|
150
|
+
@absolute_path ||= site.in_source_dir(relative_path)
|
130
151
|
end
|
152
|
+
alias_method :directory, :absolute_path
|
131
153
|
|
132
|
-
# The full path to the
|
154
|
+
# The full path to the folder containing the collection, with
|
133
155
|
# optional subpaths.
|
134
156
|
#
|
135
|
-
# *files
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# Returns a String containing th directory name where the collection
|
139
|
-
# is stored on the filesystem.
|
157
|
+
# @param *files [Array<String>] any other path pieces relative to the
|
158
|
+
# folder to append to the path
|
159
|
+
# @return [String]
|
140
160
|
def collection_dir(*files)
|
141
|
-
return
|
161
|
+
return absolute_path if files.empty?
|
142
162
|
|
143
|
-
site.in_source_dir(
|
163
|
+
site.in_source_dir(relative_path, *files)
|
144
164
|
end
|
145
165
|
|
146
|
-
# Checks whether the
|
166
|
+
# Checks whether the folder "exists" for this collection.
|
167
|
+
#
|
168
|
+
# @return [Boolean]
|
147
169
|
def exists?
|
148
|
-
File.directory?(
|
170
|
+
File.directory?(absolute_path)
|
149
171
|
end
|
150
172
|
|
151
173
|
# The entry filter for this collection.
|
152
|
-
# Creates an instance of Bridgetown::EntryFilter.
|
174
|
+
# Creates an instance of Bridgetown::EntryFilter if needed.
|
153
175
|
#
|
154
|
-
#
|
176
|
+
# @return [Bridgetown::EntryFilter]
|
155
177
|
def entry_filter
|
156
|
-
@entry_filter ||= Bridgetown::EntryFilter.new(
|
178
|
+
@entry_filter ||= Bridgetown::EntryFilter.new(
|
179
|
+
site,
|
180
|
+
base_directory: folder_name,
|
181
|
+
include_underscores: site.uses_resource?
|
182
|
+
)
|
157
183
|
end
|
158
184
|
|
159
185
|
# An inspect string.
|
160
186
|
#
|
161
|
-
#
|
187
|
+
# @return [String]
|
162
188
|
def inspect
|
163
|
-
"#<#{self.class} @label=#{label} docs=#{docs}>"
|
189
|
+
"#<#{self.class} @label=#{label} docs=#{docs} resources=#{resources}>"
|
164
190
|
end
|
165
191
|
|
166
192
|
# Produce a sanitized label name
|
167
193
|
# Label names may not contain anything but alphanumeric characters,
|
168
194
|
# underscores, and hyphens.
|
169
195
|
#
|
170
|
-
# label
|
171
|
-
#
|
172
|
-
# Returns a sanitized version of the label.
|
196
|
+
# @param label [String] the possibly-unsafe label
|
197
|
+
# @return [String] sanitized version of the label.
|
173
198
|
def sanitize_label(label)
|
174
199
|
label.gsub(%r![^a-z0-9_\-\.]!i, "")
|
175
200
|
end
|
@@ -179,7 +204,8 @@ module Bridgetown
|
|
179
204
|
# - label
|
180
205
|
# - docs
|
181
206
|
#
|
182
|
-
#
|
207
|
+
# @return [Bridgetown::Drops::CollectionDrop] representation of this
|
208
|
+
# collection for use in Liquid
|
183
209
|
def to_liquid
|
184
210
|
Drops::CollectionDrop.new self
|
185
211
|
end
|
@@ -187,14 +213,22 @@ module Bridgetown
|
|
187
213
|
# Whether the collection's documents ought to be written as individual
|
188
214
|
# files in the output.
|
189
215
|
#
|
190
|
-
#
|
216
|
+
# @return [Boolean] true if the 'write' metadata is true, false otherwise.
|
191
217
|
def write?
|
192
218
|
!!metadata.fetch("output", false)
|
193
219
|
end
|
194
220
|
|
195
|
-
#
|
221
|
+
# Used by Resource's permalink processor
|
222
|
+
# @return [String]
|
223
|
+
def default_permalink
|
224
|
+
metadata.fetch("permalink") do
|
225
|
+
"/:collection/:path/"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# LEGACY: The URL template to render collection's documents at.
|
196
230
|
#
|
197
|
-
#
|
231
|
+
# @return [String]
|
198
232
|
def url_template
|
199
233
|
@url_template ||= metadata.fetch("permalink") do
|
200
234
|
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
@@ -203,13 +237,57 @@ module Bridgetown
|
|
203
237
|
|
204
238
|
# Extract options for this collection from the site configuration.
|
205
239
|
#
|
206
|
-
#
|
240
|
+
# @return [HashWithDotAccess::Hash]
|
207
241
|
def extract_metadata
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
242
|
+
site.config.collections[label] || HashWithDotAccess::Hash.new
|
243
|
+
end
|
244
|
+
|
245
|
+
def merge_data_resources
|
246
|
+
data_contents = {}
|
247
|
+
|
248
|
+
sanitize_filename = ->(name) do
|
249
|
+
name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
|
250
|
+
.gsub(%r!\s+!, "_")
|
212
251
|
end
|
252
|
+
|
253
|
+
resources.each do |data_resource|
|
254
|
+
segments = data_resource.relative_path.each_filename.to_a[1..-1]
|
255
|
+
nested = []
|
256
|
+
segments.each_with_index do |segment, index|
|
257
|
+
sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
|
258
|
+
hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
|
259
|
+
hsh[sanitized_segment] = if index == segments.length - 1
|
260
|
+
data_resource.data.rows || data_resource.data
|
261
|
+
else
|
262
|
+
{}
|
263
|
+
end
|
264
|
+
nested << sanitized_segment
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
merge_environment_specific_metadata(data_contents).with_dot_access
|
269
|
+
end
|
270
|
+
|
271
|
+
def merge_environment_specific_metadata(data_contents)
|
272
|
+
if data_contents["site_metadata"]
|
273
|
+
data_contents["site_metadata"][Bridgetown.environment]&.each_key do |k|
|
274
|
+
data_contents["site_metadata"][k] =
|
275
|
+
data_contents["site_metadata"][Bridgetown.environment][k]
|
276
|
+
end
|
277
|
+
data_contents["site_metadata"].delete(Bridgetown.environment)
|
278
|
+
end
|
279
|
+
|
280
|
+
data_contents
|
281
|
+
end
|
282
|
+
|
283
|
+
# Read in resource from repo path
|
284
|
+
# @param full_path [String]
|
285
|
+
def read_resource(full_path)
|
286
|
+
id = "repo://#{label}.collection/" + Addressable::URI.escape(
|
287
|
+
Pathname(full_path).relative_path_from(Pathname(site.source)).to_s
|
288
|
+
)
|
289
|
+
resource = Bridgetown::Model::Base.find(id).to_resource.read!
|
290
|
+
resources << resource if site.config.unpublished || resource.published?
|
213
291
|
end
|
214
292
|
|
215
293
|
private
|
@@ -219,17 +297,20 @@ module Bridgetown
|
|
219
297
|
end
|
220
298
|
|
221
299
|
def read_document(full_path)
|
222
|
-
doc = Document.new(full_path, site: site, collection: self)
|
223
|
-
doc.
|
224
|
-
docs << doc if site.unpublished || doc.published?
|
300
|
+
doc = Document.new(full_path, site: site, collection: self).tap(&:read)
|
301
|
+
docs << doc if site.config.unpublished || doc.published?
|
225
302
|
end
|
226
303
|
|
227
304
|
def sort_docs!
|
228
305
|
if metadata["sort_by"].is_a?(String)
|
229
306
|
sort_docs_by_key!
|
307
|
+
sort_resources_by_key!
|
230
308
|
else
|
231
309
|
docs.sort!
|
310
|
+
resources.sort!
|
232
311
|
end
|
312
|
+
docs.reverse! if metadata.sort_direction == "descending"
|
313
|
+
resources.reverse! if metadata.sort_direction == "descending"
|
233
314
|
end
|
234
315
|
|
235
316
|
# A custom sort function based on Schwartzian transform
|
@@ -252,6 +333,24 @@ module Bridgetown
|
|
252
333
|
end.map!(&:last)
|
253
334
|
end
|
254
335
|
|
336
|
+
def sort_resources_by_key!
|
337
|
+
meta_key = metadata["sort_by"]
|
338
|
+
# Modify `docs` array to cache document's property along with the Document instance
|
339
|
+
resources.map! { |doc| [doc.data[meta_key], doc] }.sort! do |apples, olives|
|
340
|
+
order = determine_sort_order(meta_key, apples, olives)
|
341
|
+
|
342
|
+
# Fall back to `Document#<=>` if the properties were equal or were non-sortable
|
343
|
+
# Otherwise continue with current sort-order
|
344
|
+
if order.nil? || order.zero?
|
345
|
+
apples[-1] <=> olives[-1]
|
346
|
+
else
|
347
|
+
order
|
348
|
+
end
|
349
|
+
|
350
|
+
# Finally restore the `docs` array with just the Document objects themselves
|
351
|
+
end.map!(&:last)
|
352
|
+
end
|
353
|
+
|
255
354
|
def determine_sort_order(sort_key, apples, olives)
|
256
355
|
apple_property, apple_document = apples
|
257
356
|
olive_property, olive_document = olives
|
@@ -277,7 +376,7 @@ module Bridgetown
|
|
277
376
|
File.dirname(file_path)
|
278
377
|
).chomp("/.")
|
279
378
|
|
280
|
-
|
379
|
+
static_files << StaticFile.new(
|
281
380
|
site,
|
282
381
|
site.source,
|
283
382
|
relative_dir,
|