bridgetown-core 0.19.2 → 0.21.0.beta3
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 +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,
|