bridgetown-core 0.17.0 → 0.18.3
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/.yardopts +1 -0
- data/bridgetown-core.gemspec +1 -0
- data/lib/bridgetown-core.rb +44 -29
- data/lib/bridgetown-core/collection.rb +5 -1
- data/lib/bridgetown-core/commands/apply.rb +2 -2
- data/lib/bridgetown-core/commands/new.rb +1 -1
- data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
- data/lib/bridgetown-core/concerns/liquid_renderable.rb +10 -0
- data/lib/bridgetown-core/concerns/site/configurable.rb +21 -23
- data/lib/bridgetown-core/concerns/site/content.rb +46 -33
- data/lib/bridgetown-core/concerns/site/extensible.rb +14 -13
- data/lib/bridgetown-core/concerns/site/localizable.rb +6 -2
- data/lib/bridgetown-core/concerns/site/processable.rb +12 -15
- data/lib/bridgetown-core/concerns/site/renderable.rb +34 -26
- data/lib/bridgetown-core/concerns/site/writable.rb +7 -15
- data/lib/bridgetown-core/concerns/validatable.rb +2 -2
- data/lib/bridgetown-core/configuration.rb +10 -4
- data/lib/bridgetown-core/converter.rb +0 -42
- data/lib/bridgetown-core/converters/erb_templates.rb +80 -16
- data/lib/bridgetown-core/converters/liquid_templates.rb +103 -0
- data/lib/bridgetown-core/converters/markdown.rb +0 -3
- data/lib/bridgetown-core/document.rb +34 -21
- data/lib/bridgetown-core/drops/site_drop.rb +4 -0
- data/lib/bridgetown-core/drops/unified_payload_drop.rb +0 -1
- data/lib/bridgetown-core/drops/url_drop.rb +19 -3
- data/lib/bridgetown-core/excerpt.rb +1 -1
- data/lib/bridgetown-core/filters.rb +36 -7
- data/lib/bridgetown-core/generators/prototype_generator.rb +42 -25
- data/lib/bridgetown-core/helpers.rb +84 -0
- data/lib/bridgetown-core/liquid_renderer.rb +1 -1
- data/lib/bridgetown-core/log_writer.rb +2 -2
- data/lib/bridgetown-core/page.rb +8 -2
- data/lib/bridgetown-core/plugin_manager.rb +34 -1
- data/lib/bridgetown-core/reader.rb +1 -4
- data/lib/bridgetown-core/readers/data_reader.rb +3 -3
- data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
- data/lib/bridgetown-core/readers/post_reader.rb +28 -15
- data/lib/bridgetown-core/renderer.rb +42 -162
- data/lib/bridgetown-core/ruby_template_view.rb +26 -26
- data/lib/bridgetown-core/site.rb +12 -2
- data/lib/bridgetown-core/tags/render_content.rb +2 -2
- data/lib/bridgetown-core/utils.rb +14 -0
- data/lib/bridgetown-core/utils/ruby_exec.rb +1 -1
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +1 -0
- data/lib/site_template/src/images/.keep +1 -0
- metadata +21 -3
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
class RubyTemplateView
|
5
|
+
class Helpers
|
6
|
+
include Bridgetown::Filters
|
7
|
+
|
8
|
+
attr_reader :view, :site
|
9
|
+
|
10
|
+
Context = Struct.new(:registers)
|
11
|
+
|
12
|
+
def initialize(view, site)
|
13
|
+
@view = view
|
14
|
+
@site = site
|
15
|
+
|
16
|
+
# duck typing for Liquid context
|
17
|
+
@context = Context.new({ site: site })
|
18
|
+
end
|
19
|
+
|
20
|
+
def webpack_path(asset_type)
|
21
|
+
Bridgetown::Utils.parse_webpack_manifest_file(site, asset_type.to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param pairs [Hash] A hash of key/value pairs.
|
25
|
+
#
|
26
|
+
# @return [String] Space-separated keys where the values are truthy.
|
27
|
+
def class_map(pairs = {})
|
28
|
+
pairs.select { |_key, truthy| truthy }.keys.join(" ")
|
29
|
+
end
|
30
|
+
|
31
|
+
# This helper will generate the correct permalink URL for the file path.
|
32
|
+
#
|
33
|
+
# @param relative_path [String, Object] source file path, e.g.
|
34
|
+
# "_posts/2020-10-20-my-post.md", or object that responds to `url`
|
35
|
+
# @return [String] the permalink URL for the file
|
36
|
+
# @raise [ArgumentError] if the file cannot be found
|
37
|
+
def url_for(relative_path)
|
38
|
+
path_string = !relative_path.is_a?(String) ? relative_path.url : relative_path
|
39
|
+
|
40
|
+
return path_string if path_string.start_with?("/", "http")
|
41
|
+
|
42
|
+
site.each_site_file do |item|
|
43
|
+
if item.relative_path == path_string || item.relative_path == "/#{path_string}"
|
44
|
+
return relative_url(item)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
raise ArgumentError, <<~MSG
|
49
|
+
Could not find document '#{relative_path}' in 'url_for' helper.
|
50
|
+
|
51
|
+
Make sure the document exists and the path is correct.
|
52
|
+
MSG
|
53
|
+
end
|
54
|
+
alias_method :link, :url_for
|
55
|
+
|
56
|
+
# This helper will generate the correct permalink URL for the file path.
|
57
|
+
#
|
58
|
+
# @param text [String] the content inside the anchor tag
|
59
|
+
# @param relative_path [String, Object] source file path, e.g.
|
60
|
+
# "_posts/2020-10-20-my-post.md", or object that responds to `url`
|
61
|
+
# @param options [Hash] key-value pairs of HTML attributes to add to the tag
|
62
|
+
# @return [String] the anchor tag HTML
|
63
|
+
# @raise [ArgumentError] if the file cannot be found
|
64
|
+
def link_to(text, relative_path, options = {})
|
65
|
+
segments = []
|
66
|
+
segments << "a"
|
67
|
+
segments << "href=\"#{url_for(relative_path)}\""
|
68
|
+
options.each do |attr, option|
|
69
|
+
attr = attr.to_s.tr("_", "-")
|
70
|
+
segments << "#{attr}=\"#{Utils.xml_escape(option)}\""
|
71
|
+
end
|
72
|
+
"<#{segments.join(" ")}>#{text}</a>"
|
73
|
+
end
|
74
|
+
|
75
|
+
# Forward all arguments to I18n.t method
|
76
|
+
#
|
77
|
+
# @return [String] the translated string
|
78
|
+
# @see I18n
|
79
|
+
def t(*args)
|
80
|
+
I18n.send :t, *args
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -33,12 +33,12 @@ module Bridgetown
|
|
33
33
|
true
|
34
34
|
end
|
35
35
|
|
36
|
-
# Log a
|
36
|
+
# Log a `WARN` message
|
37
37
|
def warn(progname = nil, &block)
|
38
38
|
add(WARN, nil, progname.yellow, &block)
|
39
39
|
end
|
40
40
|
|
41
|
-
# Log an
|
41
|
+
# Log an `ERROR` message
|
42
42
|
def error(progname = nil, &block)
|
43
43
|
add(ERROR, nil, progname.red, &block)
|
44
44
|
end
|
data/lib/bridgetown-core/page.rb
CHANGED
@@ -9,7 +9,7 @@ module Bridgetown
|
|
9
9
|
include Validatable
|
10
10
|
|
11
11
|
attr_writer :dir
|
12
|
-
attr_accessor :site, :pager
|
12
|
+
attr_accessor :site, :paginator, :pager
|
13
13
|
attr_accessor :name, :ext, :basename
|
14
14
|
attr_accessor :data, :content, :output
|
15
15
|
|
@@ -121,12 +121,18 @@ module Bridgetown
|
|
121
121
|
# desired placeholder replacements. For details see "url.rb"
|
122
122
|
def url_placeholders
|
123
123
|
{
|
124
|
-
path:
|
124
|
+
path: qualified_pages_path_for_url,
|
125
125
|
basename: basename,
|
126
126
|
output_ext: output_ext,
|
127
127
|
}
|
128
128
|
end
|
129
129
|
|
130
|
+
# Strips _pages prefix off if needed for the url/destination generation
|
131
|
+
# @return [String]
|
132
|
+
def qualified_pages_path_for_url
|
133
|
+
@dir.sub(%r!^/_pages!, "")
|
134
|
+
end
|
135
|
+
|
130
136
|
# Extract information from the page filename.
|
131
137
|
#
|
132
138
|
# name - The String filename of the page file.
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zeitwerk"
|
4
|
+
|
3
5
|
module Bridgetown
|
4
6
|
class PluginManager
|
5
7
|
PLUGINS_GROUP = :bridgetown_plugins
|
6
8
|
YARN_DEPENDENCY_REGEXP = %r!(.+)@([^@]*)$!.freeze
|
7
9
|
|
8
|
-
attr_reader :site
|
10
|
+
attr_reader :site, :component_loaders
|
9
11
|
|
10
12
|
@source_manifests = Set.new
|
11
13
|
@registered_plugins = Set.new
|
@@ -37,6 +39,7 @@ module Bridgetown
|
|
37
39
|
# Returns nothing
|
38
40
|
def initialize(site)
|
39
41
|
@site = site
|
42
|
+
@component_loaders = {}
|
40
43
|
end
|
41
44
|
|
42
45
|
def self.require_from_bundler
|
@@ -158,5 +161,35 @@ module Bridgetown
|
|
158
161
|
Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
|
159
162
|
end
|
160
163
|
end
|
164
|
+
|
165
|
+
# rubocop:disable Metrics/AbcSize
|
166
|
+
def setup_component_loaders
|
167
|
+
unless @component_loaders.keys.empty?
|
168
|
+
@component_loaders.each do |_path, loader|
|
169
|
+
loader.unload
|
170
|
+
end
|
171
|
+
@component_loaders = {}
|
172
|
+
end
|
173
|
+
|
174
|
+
# Because "first constant wins" in Zeitwerk, we need to load the local
|
175
|
+
# source components _before_ we load any from plugins
|
176
|
+
site.components_load_paths.reverse_each do |load_path|
|
177
|
+
next unless Dir.exist? load_path
|
178
|
+
next if Zeitwerk::Registry.loaders.find { |loader| loader.manages?(load_path) }
|
179
|
+
|
180
|
+
@component_loaders[load_path] = Zeitwerk::Loader.new
|
181
|
+
@component_loaders[load_path].push_dir(load_path)
|
182
|
+
@component_loaders[load_path].enable_reloading if load_path.start_with?(site.root_dir)
|
183
|
+
@component_loaders[load_path].ignore(File.join(load_path, "**", "*.js.rb"))
|
184
|
+
@component_loaders[load_path].setup
|
185
|
+
end
|
186
|
+
end
|
187
|
+
# rubocop:enable Metrics/AbcSize
|
188
|
+
|
189
|
+
def reload_component_loaders
|
190
|
+
@component_loaders.each do |path, loader|
|
191
|
+
loader.reload if path.start_with?(site.root_dir)
|
192
|
+
end
|
193
|
+
end
|
161
194
|
end
|
162
195
|
end
|
@@ -76,10 +76,7 @@ module Bridgetown
|
|
76
76
|
def retrieve_posts(dir)
|
77
77
|
return if outside_configured_directory?(dir)
|
78
78
|
|
79
|
-
post_reader.read_posts(dir)
|
80
|
-
site.posts.docs.concat(entries.select { |entry| entry.is_a?(Document) })
|
81
|
-
site.posts.files.concat(entries.select { |entry| entry.is_a?(StaticFile) })
|
82
|
-
end
|
79
|
+
post_reader.read_posts(dir)
|
83
80
|
end
|
84
81
|
|
85
82
|
# Recursively traverse directories with the read_directories function.
|
@@ -6,7 +6,7 @@ module Bridgetown
|
|
6
6
|
|
7
7
|
def initialize(site)
|
8
8
|
@site = site
|
9
|
-
@content =
|
9
|
+
@content = {}
|
10
10
|
@entry_filter = EntryFilter.new(site)
|
11
11
|
end
|
12
12
|
|
@@ -20,7 +20,7 @@ module Bridgetown
|
|
20
20
|
base = site.in_source_dir(dir)
|
21
21
|
read_data_to(base, @content)
|
22
22
|
merge_environment_specific_metadata!
|
23
|
-
@content
|
23
|
+
@content = @content.with_dot_access
|
24
24
|
end
|
25
25
|
|
26
26
|
# Read and parse all .yaml, .yml, .json, .csv and .tsv
|
@@ -44,7 +44,7 @@ module Bridgetown
|
|
44
44
|
if File.directory?(path)
|
45
45
|
read_data_to(
|
46
46
|
path,
|
47
|
-
data[sanitize_filename(entry)] =
|
47
|
+
data[sanitize_filename(entry)] = {}
|
48
48
|
)
|
49
49
|
else
|
50
50
|
key = sanitize_filename(File.basename(entry, ".*"))
|
@@ -21,13 +21,13 @@ module Bridgetown
|
|
21
21
|
# Read all the files in <source>/<dir>/<magic_dir> and create a new
|
22
22
|
# Document object with each one insofar as it matches the regexp matcher.
|
23
23
|
#
|
24
|
-
# dir
|
24
|
+
# @param dir [String] relative path of the directory to read.
|
25
25
|
#
|
26
|
-
#
|
26
|
+
# @return [Array<Document, StaticFile>]
|
27
27
|
def read_publishable(dir, magic_dir, matcher)
|
28
28
|
read_content(dir, magic_dir, matcher)
|
29
|
-
.tap { |
|
30
|
-
.select { |
|
29
|
+
.tap { |items| items.select { |item| item.respond_to?(:read) }.each(&:read) }
|
30
|
+
.select { |item| item_added_to_site?(item) }
|
31
31
|
end
|
32
32
|
|
33
33
|
# Read all the content files from <source>/<dir>/magic_dir
|
@@ -70,26 +70,39 @@ module Bridgetown
|
|
70
70
|
)
|
71
71
|
end
|
72
72
|
|
73
|
-
def processable?(
|
74
|
-
return true if
|
73
|
+
def processable?(item)
|
74
|
+
return true if item.is_a?(StaticFile)
|
75
75
|
|
76
|
-
if
|
77
|
-
Bridgetown.logger.debug "Skipping:", "Content in #{
|
76
|
+
if item.content.nil?
|
77
|
+
Bridgetown.logger.debug "Skipping:", "Content in #{item.relative_path} is nil"
|
78
78
|
false
|
79
|
-
elsif !
|
80
|
-
Bridgetown.logger.debug "Skipping:", "#{
|
79
|
+
elsif !item.content.valid_encoding?
|
80
|
+
Bridgetown.logger.debug "Skipping:", "#{item.relative_path} is not valid UTF-8"
|
81
81
|
false
|
82
82
|
else
|
83
|
-
publishable?(
|
83
|
+
publishable?(item)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
def publishable?(
|
88
|
-
site.publisher.publish?(
|
89
|
-
if !will_publish && site.publisher.hidden_in_the_future?(
|
90
|
-
Bridgetown.logger.warn "Skipping:", "#{
|
87
|
+
def publishable?(item)
|
88
|
+
site.publisher.publish?(item).tap do |will_publish|
|
89
|
+
if !will_publish && site.publisher.hidden_in_the_future?(item)
|
90
|
+
Bridgetown.logger.warn "Skipping:", "#{item.relative_path} has a future date"
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
def item_added_to_site?(item)
|
96
|
+
return false unless processable?(item)
|
97
|
+
|
98
|
+
if item.is_a?(Document)
|
99
|
+
site.posts.docs << item
|
100
|
+
elsif item.is_a?(StaticFile)
|
101
|
+
site.posts.files << item
|
102
|
+
site.static_files << item
|
103
|
+
end
|
104
|
+
|
105
|
+
true
|
106
|
+
end
|
94
107
|
end
|
95
108
|
end
|
@@ -3,37 +3,10 @@
|
|
3
3
|
module Bridgetown
|
4
4
|
class Renderer
|
5
5
|
attr_reader :document, :site
|
6
|
-
attr_writer :layouts, :payload
|
7
6
|
|
8
|
-
|
9
|
-
attr_accessor :cached_partials
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(site, document, site_payload = nil)
|
7
|
+
def initialize(site, document)
|
13
8
|
@site = site
|
14
9
|
@document = document
|
15
|
-
@payload = site_payload
|
16
|
-
@layouts = nil
|
17
|
-
self.class.cached_partials ||= {}
|
18
|
-
end
|
19
|
-
|
20
|
-
# Fetches the payload used in Liquid rendering.
|
21
|
-
# It can be written with #payload=(new_payload)
|
22
|
-
# Falls back to site.site_payload if no payload is set.
|
23
|
-
#
|
24
|
-
# Returns a Bridgetown::Drops::UnifiedPayloadDrop
|
25
|
-
def payload
|
26
|
-
@payload ||= site.site_payload
|
27
|
-
end
|
28
|
-
|
29
|
-
# The list of layouts registered for this Renderer.
|
30
|
-
# It can be written with #layouts=(new_layouts)
|
31
|
-
# Falls back to site.layouts if no layouts are registered.
|
32
|
-
#
|
33
|
-
# Returns a Hash of String => Bridgetown::Layout identified
|
34
|
-
# as basename without the extension name.
|
35
|
-
def layouts
|
36
|
-
@layouts || site.layouts
|
37
10
|
end
|
38
11
|
|
39
12
|
# Determine which converters to use based on this document's
|
@@ -41,7 +14,13 @@ module Bridgetown
|
|
41
14
|
#
|
42
15
|
# Returns Array of Converter instances.
|
43
16
|
def converters
|
44
|
-
@converters ||= site.converters.select
|
17
|
+
@converters ||= site.converters.select do |converter|
|
18
|
+
if converter.method(:matches).arity == 1
|
19
|
+
converter.matches(document.extname)
|
20
|
+
else
|
21
|
+
converter.matches(document.extname, document)
|
22
|
+
end
|
23
|
+
end.sort
|
45
24
|
end
|
46
25
|
|
47
26
|
# Determine the extname the outputted file should have
|
@@ -51,93 +30,42 @@ module Bridgetown
|
|
51
30
|
@output_ext ||= (permalink_ext || converter_output_ext)
|
52
31
|
end
|
53
32
|
|
54
|
-
#
|
33
|
+
# Run hooks and render the document
|
55
34
|
#
|
56
35
|
# Returns nothing
|
57
36
|
def run
|
58
37
|
Bridgetown.logger.debug "Rendering:", document.relative_path
|
59
38
|
|
60
|
-
|
61
|
-
# TODO: this can be eliminated I think:
|
62
|
-
assign_current_document!
|
63
|
-
assign_highlighter_options!
|
64
|
-
assign_layout_data!
|
65
|
-
|
66
|
-
document.trigger_hooks(:pre_render, payload)
|
39
|
+
document.trigger_hooks :pre_render
|
67
40
|
document.output = render_document
|
68
|
-
document.trigger_hooks
|
41
|
+
document.trigger_hooks :post_render
|
69
42
|
end
|
70
43
|
|
71
44
|
# Render the document.
|
72
45
|
#
|
73
46
|
# Returns String rendered document output
|
74
|
-
# rubocop: disable Metrics/AbcSize
|
75
47
|
def render_document
|
76
|
-
liquid_context = provide_liquid_context
|
77
|
-
|
78
48
|
execute_inline_ruby!
|
79
49
|
|
80
50
|
output = document.content
|
81
|
-
if document.render_with_liquid?
|
82
|
-
Bridgetown.logger.debug "Rendering Liquid:", document.relative_path
|
83
|
-
output = render_liquid(output, payload, liquid_context, document.path)
|
84
|
-
end
|
85
|
-
|
86
51
|
Bridgetown.logger.debug "Rendering Markup:", document.relative_path
|
87
52
|
output = convert(output.to_s, document)
|
88
53
|
document.content = output
|
89
54
|
|
90
55
|
if document.place_in_layout?
|
91
56
|
Bridgetown.logger.debug "Rendering Layout:", document.relative_path
|
92
|
-
output = place_in_layouts(output
|
57
|
+
output = place_in_layouts(output)
|
93
58
|
end
|
94
59
|
|
95
60
|
output
|
96
61
|
end
|
97
62
|
|
98
|
-
def provide_liquid_context
|
99
|
-
{
|
100
|
-
registers: {
|
101
|
-
site: site,
|
102
|
-
page: payload["page"],
|
103
|
-
cached_partials: self.class.cached_partials,
|
104
|
-
},
|
105
|
-
strict_filters: liquid_options["strict_filters"],
|
106
|
-
strict_variables: liquid_options["strict_variables"],
|
107
|
-
}
|
108
|
-
end
|
109
|
-
|
110
63
|
def execute_inline_ruby!
|
111
64
|
return unless site.config.should_execute_inline_ruby?
|
112
65
|
|
113
66
|
Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document, self)
|
114
67
|
end
|
115
68
|
|
116
|
-
# rubocop: enable Metrics/AbcSize
|
117
|
-
|
118
|
-
# Render the given content with the payload and context
|
119
|
-
#
|
120
|
-
# content -
|
121
|
-
# payload -
|
122
|
-
# context -
|
123
|
-
# path - (optional) the path to the file, for use in ex
|
124
|
-
#
|
125
|
-
# Returns String the content, rendered by Liquid.
|
126
|
-
def render_liquid(content, payload, liquid_context, path = nil)
|
127
|
-
template = site.liquid_renderer.file(path).parse(content)
|
128
|
-
template.warnings.each do |e|
|
129
|
-
Bridgetown.logger.warn "Liquid Warning:",
|
130
|
-
LiquidRenderer.format_error(e, path || document.relative_path)
|
131
|
-
end
|
132
|
-
template.render!(payload, liquid_context)
|
133
|
-
# rubocop: disable Lint/RescueException
|
134
|
-
rescue Exception => e
|
135
|
-
Bridgetown.logger.error "Liquid Exception:",
|
136
|
-
LiquidRenderer.format_error(e, path || document.relative_path)
|
137
|
-
raise e
|
138
|
-
end
|
139
|
-
# rubocop: enable Lint/RescueException
|
140
|
-
|
141
69
|
# Convert the document using the converters which match this renderer's document.
|
142
70
|
#
|
143
71
|
# Returns String the converted content.
|
@@ -151,36 +79,23 @@ module Bridgetown
|
|
151
79
|
rescue StandardError => e
|
152
80
|
Bridgetown.logger.error "Conversion error:",
|
153
81
|
"#{converter.class} encountered an error while "\
|
154
|
-
"converting
|
155
|
-
Bridgetown.logger.error("", e.to_s)
|
82
|
+
"converting `#{document.relative_path}'"
|
156
83
|
raise e
|
157
84
|
end
|
158
85
|
end
|
159
86
|
|
160
|
-
# Checks if the layout specified in the document actually exists
|
161
|
-
#
|
162
|
-
# layout - the layout to check
|
163
|
-
#
|
164
|
-
# Returns Boolean true if the layout is invalid, false if otherwise
|
165
|
-
def invalid_layout?(layout)
|
166
|
-
!document.data["layout"].nil? && layout.nil? && !(document.is_a? Bridgetown::Excerpt)
|
167
|
-
end
|
168
|
-
|
169
87
|
# Render layouts and place document content inside.
|
170
88
|
#
|
171
89
|
# Returns String rendered content
|
172
|
-
def place_in_layouts(content
|
90
|
+
def place_in_layouts(content)
|
173
91
|
output = content.dup
|
174
|
-
layout = layouts[document.data["layout"]
|
92
|
+
layout = site.layouts[document.data["layout"]]
|
175
93
|
validate_layout(layout)
|
176
94
|
|
177
95
|
used = Set.new([layout])
|
178
96
|
|
179
|
-
# Reset the payload layout data to ensure it starts fresh for each page.
|
180
|
-
payload["layout"] = nil
|
181
|
-
|
182
97
|
while layout
|
183
|
-
output = render_layout(output, layout
|
98
|
+
output = render_layout(output, layout)
|
184
99
|
add_regenerator_dependencies(layout)
|
185
100
|
|
186
101
|
next unless (layout = site.layouts[layout.data["layout"]])
|
@@ -198,47 +113,44 @@ module Bridgetown
|
|
198
113
|
# layout - the layout to check
|
199
114
|
# Returns nothing
|
200
115
|
def validate_layout(layout)
|
201
|
-
return unless
|
116
|
+
return unless document.data["layout"].present? &&
|
117
|
+
layout.nil? &&
|
118
|
+
!(document.is_a? Bridgetown::Excerpt)
|
202
119
|
|
203
120
|
Bridgetown.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
|
204
121
|
"in #{document.relative_path} does not exist."
|
205
122
|
end
|
206
123
|
|
124
|
+
def converters_for_layout(layout)
|
125
|
+
site.converters.select do |converter|
|
126
|
+
if converter.method(:matches).arity == 1
|
127
|
+
converter.matches(layout.ext)
|
128
|
+
else
|
129
|
+
converter.matches(layout.ext, layout)
|
130
|
+
end
|
131
|
+
end.sort
|
132
|
+
end
|
133
|
+
|
207
134
|
# Render layout content into document.output
|
208
135
|
#
|
209
136
|
# Returns String rendered content
|
210
|
-
|
211
|
-
|
212
|
-
if layout.render_with_liquid?
|
213
|
-
payload["content"] = output
|
214
|
-
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
215
|
-
|
216
|
-
render_liquid(
|
217
|
-
layout.content,
|
218
|
-
payload,
|
219
|
-
liquid_context,
|
220
|
-
layout.path
|
221
|
-
)
|
222
|
-
else
|
223
|
-
layout_converters ||= site.converters.select { |c| c.matches(layout.ext) }.sort
|
137
|
+
def render_layout(output, layout)
|
138
|
+
layout_converters = converters_for_layout(layout)
|
224
139
|
|
225
|
-
|
226
|
-
|
227
|
-
|
140
|
+
layout_content = layout.content.dup
|
141
|
+
layout_converters.reduce(layout_content) do |layout_output, converter|
|
142
|
+
next(layout_output) unless converter.method(:convert).arity == 2
|
228
143
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
raise e
|
238
|
-
end
|
144
|
+
layout.current_document = document
|
145
|
+
layout.current_document_output = output
|
146
|
+
converter.convert layout_output, layout
|
147
|
+
rescue StandardError => e
|
148
|
+
Bridgetown.logger.error "Conversion error:",
|
149
|
+
"#{converter.class} encountered an error while "\
|
150
|
+
"converting `#{document.relative_path}'"
|
151
|
+
raise e
|
239
152
|
end
|
240
153
|
end
|
241
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
242
154
|
|
243
155
|
def add_regenerator_dependencies(layout)
|
244
156
|
return unless document.write?
|
@@ -249,34 +161,6 @@ module Bridgetown
|
|
249
161
|
)
|
250
162
|
end
|
251
163
|
|
252
|
-
# Set page content to payload and assign pager if document has one.
|
253
|
-
#
|
254
|
-
# Returns nothing
|
255
|
-
def assign_pages!
|
256
|
-
payload["page"] = document.to_liquid
|
257
|
-
payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
|
258
|
-
end
|
259
|
-
|
260
|
-
# Set related posts to payload if document is a post.
|
261
|
-
#
|
262
|
-
# Returns nothing
|
263
|
-
def assign_current_document!
|
264
|
-
payload["site"].current_document = document
|
265
|
-
end
|
266
|
-
|
267
|
-
# Set highlighter prefix and suffix
|
268
|
-
#
|
269
|
-
# Returns nothing
|
270
|
-
def assign_highlighter_options!
|
271
|
-
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
272
|
-
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
273
|
-
end
|
274
|
-
|
275
|
-
def assign_layout_data!
|
276
|
-
layout = layouts[document.data["layout"]]
|
277
|
-
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
|
278
|
-
end
|
279
|
-
|
280
164
|
def permalink_ext
|
281
165
|
document_permalink = document.permalink
|
282
166
|
if document_permalink && !document_permalink.end_with?("/")
|
@@ -298,9 +182,5 @@ module Bridgetown
|
|
298
182
|
c.output_ext(document.extname)
|
299
183
|
end.compact
|
300
184
|
end
|
301
|
-
|
302
|
-
def liquid_options
|
303
|
-
@liquid_options ||= site.config["liquid"]
|
304
|
-
end
|
305
185
|
end
|
306
186
|
end
|