bridgetown-core 0.20.0 → 0.21.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
],
|