bridgetown-core 0.20.0 → 0.21.0.beta1
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/lib/bridgetown-core.rb +3 -0
- data/lib/bridgetown-core/collection.rb +13 -10
- data/lib/bridgetown-core/component.rb +178 -0
- data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
- data/lib/bridgetown-core/concerns/site/content.rb +2 -3
- data/lib/bridgetown-core/concerns/site/writable.rb +1 -1
- data/lib/bridgetown-core/concerns/validatable.rb +0 -4
- data/lib/bridgetown-core/configuration.rb +10 -9
- data/lib/bridgetown-core/converter.rb +9 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +50 -34
- data/lib/bridgetown-core/converters/markdown.rb +1 -1
- data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
- data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +3 -1
- data/lib/bridgetown-core/drops/unified_payload_drop.rb +1 -0
- data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
- data/lib/bridgetown-core/helpers.rb +48 -9
- data/lib/bridgetown-core/layout.rb +27 -12
- data/lib/bridgetown-core/model/origin.rb +1 -1
- data/lib/bridgetown-core/model/{file_origin.rb → repo_origin.rb} +32 -25
- data/lib/bridgetown-core/reader.rb +2 -2
- data/lib/bridgetown-core/renderer.rb +1 -1
- data/lib/bridgetown-core/resource/base.rb +69 -27
- data/lib/bridgetown-core/resource/relations.rb +132 -0
- data/lib/bridgetown-core/resource/taxonomy_term.rb +10 -1
- data/lib/bridgetown-core/resource/taxonomy_type.rb +9 -0
- data/lib/bridgetown-core/resource/transformer.rb +14 -12
- data/lib/bridgetown-core/ruby_template_view.rb +7 -11
- data/lib/bridgetown-core/utils.rb +8 -1
- 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/site_template/package.json.erb +2 -2
- data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
- data/lib/site_template/webpack.config.js.erb +3 -1
- metadata +10 -3
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Resource
|
5
|
+
class Relations
|
6
|
+
# @return [Bridgetown::Resource::Base]
|
7
|
+
attr_reader :resource
|
8
|
+
|
9
|
+
# @return [Bridgetown::Site]
|
10
|
+
attr_reader :site
|
11
|
+
|
12
|
+
# @param resource [Bridgetown::Resource::Base]
|
13
|
+
def initialize(resource)
|
14
|
+
@resource = resource
|
15
|
+
@site = resource.site
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [HashWithDotAccess::Hash]
|
19
|
+
def relation_schema
|
20
|
+
resource.collection.metadata.relations
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Array<String>]
|
24
|
+
def relation_types
|
25
|
+
@relation_types ||= begin
|
26
|
+
types = []
|
27
|
+
relation_schema&.each do |_relation_type, collections|
|
28
|
+
types << collections
|
29
|
+
types << Array(collections).map { |item| ActiveSupport::Inflector.pluralize(item) }
|
30
|
+
end
|
31
|
+
types.flatten.uniq
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param type [Symbol]
|
36
|
+
# @return [Bridgetown::Resource::Base, Array<Bridgetown::Resource::Base>]
|
37
|
+
def resources_for_type(type)
|
38
|
+
relation_kind = kind_of_relation_for_type(type)
|
39
|
+
return [] unless relation_kind
|
40
|
+
|
41
|
+
case relation_kind.to_sym
|
42
|
+
when :belongs_to
|
43
|
+
belongs_to_relation_for_type(type)
|
44
|
+
when :has_many
|
45
|
+
has_many_relation_for_type(type)
|
46
|
+
when :has_one
|
47
|
+
has_one_relation_for_type(type)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_missing(type, *args)
|
52
|
+
return super unless type.to_s.in?(relation_types)
|
53
|
+
|
54
|
+
resources_for_type(type)
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_to_missing?(type, *_args)
|
58
|
+
type.to_s.in?(relation_types)
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_liquid
|
62
|
+
@to_liquid ||= Drops::RelationsDrop.new(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @param type [Symbol]
|
68
|
+
# @return [String]
|
69
|
+
def kind_of_relation_for_type(type)
|
70
|
+
relation_schema&.each do |relation_type, collections|
|
71
|
+
collections = Array(collections).yield_self do |collections_arr|
|
72
|
+
collections_arr +
|
73
|
+
collections_arr.map { |item| ActiveSupport::Inflector.pluralize(item) }
|
74
|
+
end.flatten.uniq
|
75
|
+
return relation_type if collections.include?(type.to_s)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# @param type [Symbol]
|
80
|
+
# @return [Bridgetown::Collection]
|
81
|
+
def other_collection_for_type(type)
|
82
|
+
site.collections[type] || site.collections[ActiveSupport::Inflector.pluralize(type)]
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Array<String>]
|
86
|
+
def collection_labels
|
87
|
+
[
|
88
|
+
resource.collection.label,
|
89
|
+
ActiveSupport::Inflector.singularize(resource.collection.label),
|
90
|
+
]
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param type [Symbol]
|
94
|
+
# @return [Bridgetown::Resource::Base, Array<Bridgetown::Resource::Base>]
|
95
|
+
def belongs_to_relation_for_type(type)
|
96
|
+
if resource.data[type].is_a?(Array)
|
97
|
+
other_collection_for_type(type).resources.select do |other_resource|
|
98
|
+
other_resource.data.slug.in?(resource.data[type])
|
99
|
+
end
|
100
|
+
else
|
101
|
+
other_collection_for_type(type).resources.find do |other_resource|
|
102
|
+
other_resource.data.slug == resource.data[type]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param type [Symbol]
|
108
|
+
# @return [Array<Bridgetown::Resource::Base>]
|
109
|
+
def has_many_relation_for_type(type) # rubocop:disable Naming/PredicateName
|
110
|
+
label, singular_label = collection_labels
|
111
|
+
|
112
|
+
other_collection_for_type(type).resources.select do |other_resource|
|
113
|
+
resource.data.slug.in?(
|
114
|
+
Array(other_resource.data[label] || other_resource.data[singular_label])
|
115
|
+
)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# @param type [Symbol]
|
120
|
+
# @return [Bridgetown::Resource::Base]
|
121
|
+
def has_one_relation_for_type(type) # rubocop:disable Naming/PredicateName
|
122
|
+
label, singular_label = collection_labels
|
123
|
+
|
124
|
+
other_collection_for_type(type).resources.find do |other_resource|
|
125
|
+
resource.data.slug.in?(
|
126
|
+
Array(other_resource.data[label] || other_resource.data[singular_label])
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -17,9 +17,18 @@ module Bridgetown
|
|
17
17
|
|
18
18
|
def to_liquid
|
19
19
|
{
|
20
|
-
label
|
20
|
+
"label" => label,
|
21
21
|
}
|
22
22
|
end
|
23
|
+
alias_method :to_h, :to_liquid
|
24
|
+
|
25
|
+
def as_json(*)
|
26
|
+
to_h
|
27
|
+
end
|
28
|
+
|
29
|
+
ruby2_keywords def to_json(*options)
|
30
|
+
as_json(*options).to_json(*options)
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
@@ -12,18 +12,20 @@ module Bridgetown
|
|
12
12
|
# @return [Bridgetown::Site]
|
13
13
|
attr_reader :site
|
14
14
|
|
15
|
-
# @return [String]
|
16
|
-
attr_reader :output_ext
|
17
|
-
|
18
15
|
def initialize(resource)
|
19
16
|
@resource = resource
|
20
17
|
@site = resource.site
|
21
|
-
|
22
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String]
|
21
|
+
def output_ext
|
22
|
+
@output_ext ||= output_ext_from_converters
|
23
23
|
end
|
24
24
|
|
25
25
|
# @return [String]
|
26
26
|
def final_ext
|
27
|
+
output_ext # we always need this to get run
|
28
|
+
|
27
29
|
permalink_ext || output_ext
|
28
30
|
end
|
29
31
|
|
@@ -35,6 +37,12 @@ module Bridgetown
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
40
|
+
def execute_inline_ruby!
|
41
|
+
return unless site.config.should_execute_inline_ruby?
|
42
|
+
|
43
|
+
Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource, self)
|
44
|
+
end
|
45
|
+
|
38
46
|
def inspect
|
39
47
|
"#<#{self.class} Conversion Steps: #{conversions.length}>"
|
40
48
|
end
|
@@ -102,12 +110,6 @@ module Bridgetown
|
|
102
110
|
|
103
111
|
### Transformation Actions
|
104
112
|
|
105
|
-
def execute_inline_ruby
|
106
|
-
return unless site.config.should_execute_inline_ruby?
|
107
|
-
|
108
|
-
Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource, self)
|
109
|
-
end
|
110
|
-
|
111
113
|
def run_conversions # rubocop:disable Metrics/AbcSize
|
112
114
|
input = resource.content.to_s
|
113
115
|
|
@@ -125,7 +127,7 @@ module Bridgetown
|
|
125
127
|
output: Bridgetown.env.production? ? nil : output,
|
126
128
|
output_ext: conversions[index][:output_ext],
|
127
129
|
}
|
128
|
-
output
|
130
|
+
output.html_safe
|
129
131
|
rescue StandardError => e
|
130
132
|
Bridgetown.logger.error "Conversion error:",
|
131
133
|
"#{converter.class} encountered an error while "\
|
@@ -7,6 +7,7 @@ module Bridgetown
|
|
7
7
|
require "bridgetown-core/helpers"
|
8
8
|
|
9
9
|
attr_reader :layout, :page, :paginator, :site, :content
|
10
|
+
alias_method :resource, :page
|
10
11
|
|
11
12
|
def initialize(convertible)
|
12
13
|
if convertible.is_a?(Layout)
|
@@ -27,17 +28,10 @@ module Bridgetown
|
|
27
28
|
|
28
29
|
def render(item, options = {}, &block)
|
29
30
|
if item.respond_to?(:render_in)
|
30
|
-
previous_buffer_state = @_erbout
|
31
|
-
@_erbout = Bridgetown::ERBBuffer.new
|
32
|
-
|
33
|
-
@in_view_component ||= defined?(::ViewComponent::Base) && item.is_a?(::ViewComponent::Base)
|
34
31
|
result = item.render_in(self, &block)
|
35
|
-
|
36
|
-
|
37
|
-
@_erbout = previous_buffer_state
|
38
|
-
result
|
32
|
+
result&.html_safe
|
39
33
|
else
|
40
|
-
partial(item, options, &block)
|
34
|
+
partial(item, options, &block)&.html_safe
|
41
35
|
end
|
42
36
|
end
|
43
37
|
|
@@ -60,14 +54,15 @@ module Bridgetown
|
|
60
54
|
Bridgetown.logger.warn "Liquid Warning:",
|
61
55
|
LiquidRenderer.format_error(e, path || document.relative_path)
|
62
56
|
end
|
63
|
-
template.render!(options.deep_stringify_keys, _liquid_context)
|
57
|
+
template.render!(options.deep_stringify_keys, _liquid_context).html_safe
|
64
58
|
end
|
65
59
|
|
66
60
|
def helpers
|
67
61
|
@helpers ||= Helpers.new(self, site)
|
68
62
|
end
|
69
63
|
|
70
|
-
|
64
|
+
# rubocop:disable Style/MissingRespondToMissing
|
65
|
+
ruby2_keywords def method_missing(method, *args, &block)
|
71
66
|
if helpers.respond_to?(method.to_sym)
|
72
67
|
helpers.send method.to_sym, *args, &block
|
73
68
|
else
|
@@ -78,6 +73,7 @@ module Bridgetown
|
|
78
73
|
def respond_to_missing?(method, include_private = false)
|
79
74
|
helpers.respond_to?(method.to_sym, include_private) || super
|
80
75
|
end
|
76
|
+
# rubocop:enable Style/MissingRespondToMissing
|
81
77
|
|
82
78
|
private
|
83
79
|
|
@@ -5,6 +5,7 @@ module Bridgetown
|
|
5
5
|
extend self
|
6
6
|
autoload :Ansi, "bridgetown-core/utils/ansi"
|
7
7
|
autoload :RubyExec, "bridgetown-core/utils/ruby_exec"
|
8
|
+
autoload :RubyFrontMatterDSL, "bridgetown-core/utils/ruby_front_matter"
|
8
9
|
autoload :Platforms, "bridgetown-core/utils/platforms"
|
9
10
|
autoload :ThreadEvent, "bridgetown-core/utils/thread_event"
|
10
11
|
|
@@ -118,7 +119,13 @@ module Bridgetown
|
|
118
119
|
# @return [Boolean] if the YAML front matter is present.
|
119
120
|
# rubocop: disable Naming/PredicateName
|
120
121
|
def has_yaml_header?(file)
|
121
|
-
File.open(file, "rb", &:readline).match?
|
122
|
+
File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::YAML_HEADER
|
123
|
+
rescue EOFError
|
124
|
+
false
|
125
|
+
end
|
126
|
+
|
127
|
+
def has_rbfm_header?(file)
|
128
|
+
File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::RUBY_HEADER
|
122
129
|
rescue EOFError
|
123
130
|
false
|
124
131
|
end
|
@@ -5,8 +5,8 @@ module Bridgetown
|
|
5
5
|
module RubyExec
|
6
6
|
extend self
|
7
7
|
|
8
|
-
#
|
9
|
-
def search_data_for_ruby_code(convertible, renderer)
|
8
|
+
# TODO: Deprecate storing Ruby code in YAML, Rb, etc. and just use native Ruby Front Matter
|
9
|
+
def search_data_for_ruby_code(convertible, renderer) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
10
10
|
return if convertible.data.empty?
|
11
11
|
|
12
12
|
# Iterate using `keys` here so inline Ruby script can add new data keys
|
@@ -14,24 +14,21 @@ module Bridgetown
|
|
14
14
|
data_keys = convertible.data.keys
|
15
15
|
data_keys.each do |k|
|
16
16
|
v = convertible.data[k]
|
17
|
-
next unless v.is_a?(Rb) || v.is_a?(Hash)
|
17
|
+
next unless v.is_a?(Rb) || v.is_a?(Hash) || v.is_a?(Proc)
|
18
18
|
|
19
|
-
if v.is_a?(
|
19
|
+
if v.is_a?(Proc)
|
20
|
+
convertible.data[k] = convertible.instance_exec(&v)
|
21
|
+
elsif v.is_a?(Hash)
|
20
22
|
v.each do |nested_k, nested_v|
|
21
23
|
next unless nested_v.is_a?(Rb)
|
22
24
|
|
23
|
-
Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
|
24
25
|
convertible.data[k][nested_k] = run(nested_v, convertible, renderer)
|
25
|
-
Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
|
26
26
|
end
|
27
27
|
else
|
28
|
-
Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
|
29
28
|
convertible.data[k] = run(v, convertible, renderer)
|
30
|
-
Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
34
|
-
# rubocop:enable Metrics/AbcSize
|
35
32
|
|
36
33
|
# Sets up a new context in which to eval Ruby coming from front matter.
|
37
34
|
#
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module Utils
|
5
|
+
module RubyFrontMatterDSL
|
6
|
+
def front_matter(&block)
|
7
|
+
RubyFrontMatter.new.tap { |fm| fm.instance_exec(&block) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class RubyFrontMatter
|
12
|
+
def initialize
|
13
|
+
@data = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(key, value) # rubocop:disable Style/MissingRespondToMissing
|
17
|
+
return super if respond_to?(key)
|
18
|
+
|
19
|
+
set(key, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
@data.each(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(key)
|
27
|
+
@data[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def set(key, value)
|
31
|
+
@data[key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_h
|
35
|
+
@data
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -140,7 +140,7 @@ module Bridgetown
|
|
140
140
|
if options[:trace]
|
141
141
|
Bridgetown.logger.info e.backtrace.join("\n")
|
142
142
|
else
|
143
|
-
Bridgetown.logger.warn "
|
143
|
+
Bridgetown.logger.warn "Backtrace:", "Use the --trace option for more information."
|
144
144
|
end
|
145
145
|
end
|
146
146
|
Bridgetown.logger.info ""
|
@@ -21,6 +21,6 @@ def print_hi(name)
|
|
21
21
|
end
|
22
22
|
print_hi('Tom')
|
23
23
|
#=> prints 'Hi, Tom' to STDOUT.
|
24
|
-
|
24
|
+
```
|
25
25
|
|
26
26
|
Check out the [Bridgetown docs](https://bridgetownrb.com/docs/) for more info on how to get the most out of Bridgetown. File all bugs/feature requests at [Bridgetown’s GitHub repo](https://github.com/bridgetownrb/bridgetown). If you have questions, you can ask them on [Bridgetown Discussions on GitHub](https://github.com/bridgetownrb/bridgetown/discussions).
|
@@ -72,7 +72,7 @@ module.exports = {
|
|
72
72
|
},
|
73
73
|
"postcss-loader"
|
74
74
|
],
|
75
|
-
},
|
75
|
+
},
|
76
76
|
<% else %>
|
77
77
|
{
|
78
78
|
test: /\.(s[ac]|c)ss$/,
|
@@ -87,7 +87,9 @@ module.exports = {
|
|
87
87
|
{
|
88
88
|
loader: "sass-loader",
|
89
89
|
options: {
|
90
|
+
implementation: require("sass"),
|
90
91
|
sassOptions: {
|
92
|
+
fiber: false,
|
91
93
|
includePaths: [
|
92
94
|
path.resolve(__dirname, "src/_components")
|
93
95
|
],
|