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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02c8827143ec0abe2adfa081ef1fe7723d8d000c4ecec5c6da1ddaa2ef9a8cdf
|
4
|
+
data.tar.gz: 2c81ef34075b80ce956f43b57b01b400852d4a30e3eca8587785febc5c82a850
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f86157dcd3f2fb1139e490fcc1341e2508f4811bda806171e2374e4753cf14c6c121abbb2ceeb6536a925bfd1d1ecba44c6d35fb6ebd6c0bcad3b4ace8d73912
|
7
|
+
data.tar.gz: 9262363b23785be1ad111a611d7660201dd3e948e331fdcf5395afd8fde91f1cb075ba13d1729fcd537cd15e3d209c8016145af04c13f054f87bb37d46406617
|
data/lib/bridgetown-core.rb
CHANGED
@@ -38,6 +38,7 @@ require "active_support/core_ext/object/deep_dup"
|
|
38
38
|
require "active_support/core_ext/object/inclusion"
|
39
39
|
require "active_support/core_ext/string/inflections"
|
40
40
|
require "active_support/core_ext/string/inquiry"
|
41
|
+
require "active_support/core_ext/string/output_safety"
|
41
42
|
require "active_support/core_ext/string/starts_ends_with"
|
42
43
|
require "active_support/current_attributes"
|
43
44
|
require "active_support/descendants_tracker"
|
@@ -80,6 +81,7 @@ end
|
|
80
81
|
module Bridgetown
|
81
82
|
autoload :Cleaner, "bridgetown-core/cleaner"
|
82
83
|
autoload :Collection, "bridgetown-core/collection"
|
84
|
+
autoload :Component, "bridgetown-core/component"
|
83
85
|
autoload :Configuration, "bridgetown-core/configuration"
|
84
86
|
autoload :DataAccessible, "bridgetown-core/concerns/data_accessible"
|
85
87
|
autoload :Deprecator, "bridgetown-core/deprecator"
|
@@ -91,6 +93,7 @@ module Bridgetown
|
|
91
93
|
# TODO: this is a poorly named, unclear class. Relocate to Utils:
|
92
94
|
autoload :External, "bridgetown-core/external"
|
93
95
|
autoload :FrontmatterDefaults, "bridgetown-core/frontmatter_defaults"
|
96
|
+
autoload :FrontMatterImporter, "bridgetown-core/concerns/front_matter_importer"
|
94
97
|
autoload :Hooks, "bridgetown-core/hooks"
|
95
98
|
autoload :Layout, "bridgetown-core/layout"
|
96
99
|
autoload :LayoutPlaceable, "bridgetown-core/concerns/layout_placeable"
|
@@ -78,7 +78,8 @@ module Bridgetown
|
|
78
78
|
if site.uses_resource?
|
79
79
|
next if File.basename(file_path).starts_with?("_")
|
80
80
|
|
81
|
-
if label == "data" || Utils.has_yaml_header?(full_path)
|
81
|
+
if label == "data" || Utils.has_yaml_header?(full_path) ||
|
82
|
+
Utils.has_rbfm_header?(full_path)
|
82
83
|
read_resource(full_path)
|
83
84
|
else
|
84
85
|
read_static_file(file_path, full_path)
|
@@ -256,7 +257,7 @@ module Bridgetown
|
|
256
257
|
sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
|
257
258
|
hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
|
258
259
|
hsh[sanitized_segment] = if index == segments.length - 1
|
259
|
-
data_resource.data.
|
260
|
+
data_resource.data.rows || data_resource.data
|
260
261
|
else
|
261
262
|
{}
|
262
263
|
end
|
@@ -279,6 +280,16 @@ module Bridgetown
|
|
279
280
|
data_contents
|
280
281
|
end
|
281
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.unpublished || resource.published?
|
291
|
+
end
|
292
|
+
|
282
293
|
private
|
283
294
|
|
284
295
|
def container
|
@@ -290,14 +301,6 @@ module Bridgetown
|
|
290
301
|
docs << doc if site.unpublished || doc.published?
|
291
302
|
end
|
292
303
|
|
293
|
-
def read_resource(full_path)
|
294
|
-
id = "file://#{label}.collection/" + Addressable::URI.escape(
|
295
|
-
Pathname(full_path).relative_path_from(Pathname(site.source)).to_s
|
296
|
-
)
|
297
|
-
resource = Bridgetown::Model::Base.find(id).to_resource.read!
|
298
|
-
resources << resource if site.unpublished || resource.published?
|
299
|
-
end
|
300
|
-
|
301
304
|
def sort_docs!
|
302
305
|
if metadata["sort_by"].is_a?(String)
|
303
306
|
sort_docs_by_key!
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
class Component
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@view_context, :helpers, :liquid_render, :partial
|
8
|
+
|
9
|
+
# @return [Bridgetown::Site]
|
10
|
+
attr_reader :site # will be nil unless you explicitly set a `@site` ivar
|
11
|
+
|
12
|
+
# @return [Bridgetown::RubyTemplateView, Bridgetown::Component]
|
13
|
+
attr_reader :view_context
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :source_location
|
17
|
+
|
18
|
+
def inherited(child)
|
19
|
+
# Code cribbed from ViewComponent by GitHub:
|
20
|
+
# Derive the source location of the component Ruby file from the call stack
|
21
|
+
child.source_location = caller_locations(1, 10).reject do |l|
|
22
|
+
l.label == "inherited"
|
23
|
+
end[0].absolute_path
|
24
|
+
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return the appropriate template renderer for a given extension.
|
29
|
+
# TODO: make this extensible
|
30
|
+
#
|
31
|
+
# @param ext [String] erb, slim, etc.
|
32
|
+
def renderer_for_ext(ext, &block)
|
33
|
+
case ext
|
34
|
+
when "erb"
|
35
|
+
include ERBCapture
|
36
|
+
Tilt::ErubiTemplate.new(component_template_path,
|
37
|
+
outvar: "@_erbout",
|
38
|
+
bufval: "Bridgetown::OutputBuffer.new",
|
39
|
+
engine_class: Bridgetown::ERBEngine,
|
40
|
+
&block)
|
41
|
+
when "serb" # requires serbea
|
42
|
+
include Serbea::Helpers
|
43
|
+
Tilt::SerbeaTemplate.new(component_template_path, &block)
|
44
|
+
when "slim" # requires bridgetown-slim
|
45
|
+
Slim::Template.new(component_template_path, &block)
|
46
|
+
when "haml" # requires bridgetown-haml
|
47
|
+
Tilt::HamlTemplate.new(component_template_path, &block)
|
48
|
+
else
|
49
|
+
raise NameError
|
50
|
+
end
|
51
|
+
rescue NameError, LoadError
|
52
|
+
raise "No component rendering engine could be found for .#{ext} templates"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Find the first matching template path based on source location and extension.
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
def component_template_path
|
59
|
+
stripped_path = File.join(
|
60
|
+
File.dirname(source_location),
|
61
|
+
File.basename(source_location, ".*")
|
62
|
+
)
|
63
|
+
supported_template_extensions.each do |ext|
|
64
|
+
test_path = "#{stripped_path}.#{ext}"
|
65
|
+
return test_path if File.exist?(test_path)
|
66
|
+
|
67
|
+
test_path = "#{stripped_path}.html.#{ext}"
|
68
|
+
return test_path if File.exist?(test_path)
|
69
|
+
end
|
70
|
+
|
71
|
+
raise "No matching templates could be found in #{File.dirname(source_location)}"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Read the template file.
|
75
|
+
#
|
76
|
+
# @return [String]
|
77
|
+
def component_template_content
|
78
|
+
File.read(component_template_path)
|
79
|
+
end
|
80
|
+
|
81
|
+
# A list of extensions supported by the renderer
|
82
|
+
# TODO: make this extensible
|
83
|
+
#
|
84
|
+
# @return [Array<String>]
|
85
|
+
def supported_template_extensions
|
86
|
+
%w(erb serb slim haml)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# If a content block was originally passed into via `render`, capture its output.
|
91
|
+
#
|
92
|
+
# @return [String] or nil
|
93
|
+
def content
|
94
|
+
@_content ||= begin
|
95
|
+
view_context.capture(self, &@_content_block) if @_content_block
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Provide a render helper for evaluation within the component context.
|
100
|
+
#
|
101
|
+
# @param item [Object] a component supporting `render_in` or a partial name
|
102
|
+
# @param options [Hash] passed to the `partial` helper if needed
|
103
|
+
# @return [String]
|
104
|
+
def render(item, options = {}, &block)
|
105
|
+
if item.respond_to?(:render_in)
|
106
|
+
result = ""
|
107
|
+
capture do # this ensures no leaky interactions between BT<=>VC blocks
|
108
|
+
result = item.render_in(self, &block)
|
109
|
+
end
|
110
|
+
result&.html_safe
|
111
|
+
else
|
112
|
+
partial(item, options, &block)&.html_safe
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# This is where the magic happens. Render the component within a view context.
|
117
|
+
#
|
118
|
+
# @param view_context [Bridgetown::RubyTemplateView]
|
119
|
+
def render_in(view_context, &block)
|
120
|
+
@view_context = view_context
|
121
|
+
@_content_block = block
|
122
|
+
|
123
|
+
if render?
|
124
|
+
before_render
|
125
|
+
template
|
126
|
+
else
|
127
|
+
""
|
128
|
+
end
|
129
|
+
rescue StandardError => e
|
130
|
+
Bridgetown.logger.error "Component error:",
|
131
|
+
"#{self.class} encountered an error while "\
|
132
|
+
"rendering `#{self.class.component_template_path}'"
|
133
|
+
raise e
|
134
|
+
end
|
135
|
+
|
136
|
+
# Subclasses can override this method to return a string from their own
|
137
|
+
# template handling.
|
138
|
+
def template
|
139
|
+
call || _renderer.render(self)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Typically not used but here as a compatibility nod toward ViewComponent.
|
143
|
+
def call
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
|
147
|
+
# Subclasses can override this method to perform tasks before a render.
|
148
|
+
def before_render; end
|
149
|
+
|
150
|
+
# Subclasses can override this method to determine if the component should
|
151
|
+
# be rendered based on initialized data or other logic.
|
152
|
+
def render?
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
def _renderer
|
157
|
+
# TODO: figure out a way to compile templates for increased performance
|
158
|
+
@_renderer ||= begin
|
159
|
+
ext = File.extname(self.class.component_template_path).delete_prefix(".")
|
160
|
+
self.class.renderer_for_ext(ext) { self.class.component_template_content }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# rubocop:disable Style/MissingRespondToMissing
|
165
|
+
ruby2_keywords def method_missing(method, *args, &block)
|
166
|
+
if helpers.respond_to?(method.to_sym)
|
167
|
+
helpers.send method.to_sym, *args, &block
|
168
|
+
else
|
169
|
+
super
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def respond_to_missing?(method, include_private = false)
|
174
|
+
helpers.respond_to?(method.to_sym, include_private) || super
|
175
|
+
end
|
176
|
+
# rubocop:enable Style/MissingRespondToMissing
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module FrontMatterImporter
|
5
|
+
# Requires klass#content and klass#front_matter_line_count accessors
|
6
|
+
def self.included(klass)
|
7
|
+
klass.include Bridgetown::Utils::RubyFrontMatterDSL
|
8
|
+
end
|
9
|
+
|
10
|
+
YAML_HEADER = %r!\A---\s*\n!.freeze
|
11
|
+
YAML_BLOCK = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
|
12
|
+
RUBY_HEADER = %r!\A[~`#\-]{3,}(?:ruby|<%|{%)\s*\n!.freeze
|
13
|
+
RUBY_BLOCK =
|
14
|
+
%r!#{RUBY_HEADER.source}(.*?\n?)^((?:%>|%})?[~`#\-]{3,}\s*$\n?)!m.freeze
|
15
|
+
|
16
|
+
def read_front_matter(file_path) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
17
|
+
file_contents = File.read(
|
18
|
+
file_path, **Bridgetown::Utils.merged_file_read_opts(Bridgetown::Current.site, {})
|
19
|
+
)
|
20
|
+
yaml_content = file_contents.match(YAML_BLOCK)
|
21
|
+
if !yaml_content && Bridgetown::Current.site.config.should_execute_inline_ruby?
|
22
|
+
ruby_content = file_contents.match(RUBY_BLOCK)
|
23
|
+
end
|
24
|
+
|
25
|
+
if yaml_content
|
26
|
+
self.content = yaml_content.post_match
|
27
|
+
self.front_matter_line_count = yaml_content[1].lines.size - 1
|
28
|
+
SafeYAML.load(yaml_content[1])
|
29
|
+
elsif ruby_content
|
30
|
+
# rbfm header + content underneath
|
31
|
+
self.content = ruby_content.post_match
|
32
|
+
self.front_matter_line_count = ruby_content[1].lines.size
|
33
|
+
process_ruby_data(ruby_content[1], file_path, 2)
|
34
|
+
elsif Bridgetown::Utils.has_rbfm_header?(file_path)
|
35
|
+
process_ruby_data(File.read(file_path).lines[1..-1].join("\n"), file_path, 2)
|
36
|
+
elsif is_a?(Layout)
|
37
|
+
self.content = file_contents
|
38
|
+
{}
|
39
|
+
else
|
40
|
+
yaml_data = SafeYAML.load_file(file_path)
|
41
|
+
yaml_data.is_a?(Array) ? { rows: yaml_data } : yaml_data
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def process_ruby_data(rubycode, file_path, starting_line)
|
46
|
+
ruby_data = instance_eval(rubycode, file_path.to_s, starting_line)
|
47
|
+
ruby_data.is_a?(Array) ? { rows: ruby_data } : ruby_data.to_h
|
48
|
+
rescue StandardError => e
|
49
|
+
raise "Ruby code isn't returning an array, or object which responds to `to_h' (#{e.message})"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -173,9 +173,8 @@ class Bridgetown::Site
|
|
173
173
|
documents.select(&:write?)
|
174
174
|
end
|
175
175
|
|
176
|
-
# Get all
|
177
|
-
# @return [Array<
|
178
|
-
# configuration
|
176
|
+
# Get all loaded resources.
|
177
|
+
# @return [Array<Bridgetown::Resource::Base>] an array of resources
|
179
178
|
def resources
|
180
179
|
collections.each_with_object(Set.new) do |(_, collection), set|
|
181
180
|
set.merge(collection.resources)
|
@@ -21,7 +21,7 @@ class Bridgetown::Site
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# Yields all content objects while looping through {#pages},
|
24
|
-
# {#static_files_to_write},
|
24
|
+
# {#static_files_to_write}, {#docs_to_write}, {#resources_to_write}.
|
25
25
|
#
|
26
26
|
# @yieldparam item [Document, Page, StaticFile]
|
27
27
|
#
|
@@ -3,10 +3,6 @@
|
|
3
3
|
module Bridgetown
|
4
4
|
# TODO: to be retired once the Resource engine is made official
|
5
5
|
module Validatable
|
6
|
-
# FIXME: there should be ONE TRUE METHOD to read the YAML frontmatter
|
7
|
-
# in the entire project. Both this and the equivalent Document method
|
8
|
-
# should be extracted and generalized.
|
9
|
-
#
|
10
6
|
# Read the YAML frontmatter.
|
11
7
|
#
|
12
8
|
# base - The String path to the dir containing the file.
|
@@ -74,15 +74,16 @@ module Bridgetown
|
|
74
74
|
},
|
75
75
|
|
76
76
|
"kramdown" => {
|
77
|
-
"auto_ids"
|
78
|
-
"toc_levels"
|
79
|
-
"entity_output"
|
80
|
-
"smart_quotes"
|
81
|
-
"input"
|
82
|
-
"hard_wrap"
|
83
|
-
"guess_lang"
|
84
|
-
"footnote_nr"
|
85
|
-
"show_warnings"
|
77
|
+
"auto_ids" => true,
|
78
|
+
"toc_levels" => (1..6).to_a,
|
79
|
+
"entity_output" => "as_char",
|
80
|
+
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
81
|
+
"input" => "GFM",
|
82
|
+
"hard_wrap" => false,
|
83
|
+
"guess_lang" => true,
|
84
|
+
"footnote_nr" => 1,
|
85
|
+
"show_warnings" => false,
|
86
|
+
"include_extraction_tags" => false,
|
86
87
|
},
|
87
88
|
}.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
|
88
89
|
|
@@ -53,6 +53,15 @@ module Bridgetown
|
|
53
53
|
".html"
|
54
54
|
end
|
55
55
|
|
56
|
+
def line_start(convertible)
|
57
|
+
if convertible.is_a?(Bridgetown::Resource::Base) &&
|
58
|
+
convertible.model.origin.respond_to?(:front_matter_line_count)
|
59
|
+
convertible.model.origin.front_matter_line_count + 4
|
60
|
+
else
|
61
|
+
1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
56
65
|
def inspect
|
57
66
|
"#<#{self.class}#{self.class.extname_list ? " #{self.class.extname_list.join(", ")}" : nil}>"
|
58
67
|
end
|
@@ -3,14 +3,26 @@
|
|
3
3
|
require "tilt/erubi"
|
4
4
|
|
5
5
|
module Bridgetown
|
6
|
-
class
|
7
|
-
def
|
8
|
-
|
6
|
+
class OutputBuffer < ActiveSupport::SafeBuffer
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
encode!
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def <<(value)
|
13
|
+
return self if value.nil?
|
14
|
+
|
15
|
+
super(value.to_s)
|
16
|
+
end
|
17
|
+
alias_method :append=, :<<
|
18
|
+
|
19
|
+
def safe_expr_append=(val)
|
20
|
+
return self if val.nil? # rubocop:disable Lint/ReturnInVoidContext
|
21
|
+
|
22
|
+
safe_concat val.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :safe_append=, :safe_concat
|
14
26
|
end
|
15
27
|
|
16
28
|
class ERBEngine < Erubi::Engine
|
@@ -22,24 +34,47 @@ module Bridgetown
|
|
22
34
|
@src << ";" unless code[Erubi::RANGE_LAST] == "\n"
|
23
35
|
end
|
24
36
|
|
37
|
+
def add_text(text)
|
38
|
+
return if text.empty?
|
39
|
+
|
40
|
+
src << bufvar << ".safe_append='"
|
41
|
+
src << text.gsub(%r{['\\]}, '\\\\\&')
|
42
|
+
src << "'.freeze;"
|
43
|
+
end
|
44
|
+
|
25
45
|
# pulled from Rails' ActionView
|
26
46
|
BLOCK_EXPR = %r!\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z!.freeze
|
27
47
|
|
28
48
|
def add_expression(indicator, code)
|
49
|
+
src << bufvar << if (indicator == "==") || @escape
|
50
|
+
".safe_expr_append="
|
51
|
+
else
|
52
|
+
".append="
|
53
|
+
end
|
54
|
+
|
29
55
|
if BLOCK_EXPR.match?(code)
|
30
|
-
src << "
|
56
|
+
src << " " << code
|
31
57
|
else
|
32
|
-
|
58
|
+
src << "(" << code << ");"
|
33
59
|
end
|
34
60
|
end
|
61
|
+
end
|
35
62
|
|
36
|
-
|
37
|
-
def
|
38
|
-
|
63
|
+
module ERBCapture
|
64
|
+
def capture(*args)
|
65
|
+
previous_buffer_state = @_erbout
|
66
|
+
@_erbout = OutputBuffer.new
|
67
|
+
result = yield(*args)
|
68
|
+
result = @_erbout.presence || result
|
69
|
+
@_erbout = previous_buffer_state
|
70
|
+
|
71
|
+
result.is_a?(String) ? ERB::Util.h(result) : result
|
39
72
|
end
|
40
73
|
end
|
41
74
|
|
42
75
|
class ERBView < RubyTemplateView
|
76
|
+
include ERBCapture
|
77
|
+
|
43
78
|
def h(input)
|
44
79
|
Erubi.h(input)
|
45
80
|
end
|
@@ -55,30 +90,10 @@ module Bridgetown
|
|
55
90
|
Tilt::ErubiTemplate.new(
|
56
91
|
site.in_source_dir(site.config[:partials_dir], "#{partial_name}.erb"),
|
57
92
|
outvar: "@_erbout",
|
58
|
-
bufval: "Bridgetown::
|
93
|
+
bufval: "Bridgetown::OutputBuffer.new",
|
59
94
|
engine_class: ERBEngine
|
60
95
|
).render(self, options)
|
61
96
|
end
|
62
|
-
|
63
|
-
def markdownify(input = nil, &block)
|
64
|
-
content = Bridgetown::Utils.reindent_for_markdown(
|
65
|
-
block.nil? ? input.to_s : capture(&block)
|
66
|
-
)
|
67
|
-
converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
|
68
|
-
result = converter.convert(content).strip
|
69
|
-
result.respond_to?(:html_safe) ? result.html_safe : result
|
70
|
-
end
|
71
|
-
|
72
|
-
def capture(*args, &block)
|
73
|
-
return capture_in_view_component(*args, &block) if @in_view_component
|
74
|
-
|
75
|
-
previous_buffer_state = @_erbout
|
76
|
-
@_erbout = ERBBuffer.new
|
77
|
-
result = yield(*args)
|
78
|
-
@_erbout = previous_buffer_state
|
79
|
-
|
80
|
-
result.respond_to?(:html_safe) ? result.html_safe : result
|
81
|
-
end
|
82
97
|
end
|
83
98
|
|
84
99
|
module Converters
|
@@ -100,14 +115,15 @@ module Bridgetown
|
|
100
115
|
|
101
116
|
erb_renderer = Tilt::ErubiTemplate.new(
|
102
117
|
convertible.relative_path,
|
118
|
+
line_start(convertible),
|
103
119
|
outvar: "@_erbout",
|
104
|
-
bufval: "Bridgetown::
|
120
|
+
bufval: "Bridgetown::OutputBuffer.new",
|
105
121
|
engine_class: ERBEngine
|
106
122
|
) { content }
|
107
123
|
|
108
124
|
if convertible.is_a?(Bridgetown::Layout)
|
109
125
|
erb_renderer.render(erb_view) do
|
110
|
-
convertible.current_document_output
|
126
|
+
convertible.current_document_output.html_safe
|
111
127
|
end
|
112
128
|
else
|
113
129
|
erb_renderer.render(erb_view)
|