bridgetown-core 0.21.2 → 1.0.0.alpha2
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/.rubocop.yml +35 -0
- data/Rakefile +5 -5
- data/bin/bridgetown +2 -0
- data/bridgetown-core.gemspec +3 -0
- data/lib/bridgetown-core/cache.rb +3 -5
- data/lib/bridgetown-core/cleaner.rb +2 -10
- data/lib/bridgetown-core/collection.rb +62 -86
- data/lib/bridgetown-core/commands/base.rb +62 -2
- data/lib/bridgetown-core/commands/build.rb +33 -12
- data/lib/bridgetown-core/commands/concerns/actions.rb +2 -2
- data/lib/bridgetown-core/commands/concerns/build_options.rb +3 -10
- data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +3 -1
- data/lib/bridgetown-core/commands/console.rb +3 -3
- data/lib/bridgetown-core/commands/doctor.rb +13 -11
- data/lib/bridgetown-core/commands/new.rb +14 -6
- data/lib/bridgetown-core/commands/plugins.rb +8 -11
- data/lib/bridgetown-core/commands/serve/servlet.rb +4 -4
- data/lib/bridgetown-core/commands/serve.rb +37 -37
- data/lib/bridgetown-core/commands/start.rb +106 -0
- data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +2 -2
- data/lib/bridgetown-core/commands/webpack.rb +1 -1
- data/lib/bridgetown-core/component.rb +1 -5
- data/lib/bridgetown-core/concerns/site/configurable.rb +1 -13
- data/lib/bridgetown-core/concerns/site/content.rb +17 -118
- data/lib/bridgetown-core/concerns/site/extensible.rb +3 -4
- data/lib/bridgetown-core/concerns/site/localizable.rb +3 -1
- data/lib/bridgetown-core/concerns/site/processable.rb +9 -20
- data/lib/bridgetown-core/concerns/site/renderable.rb +19 -30
- data/lib/bridgetown-core/concerns/site/ssr.rb +53 -0
- data/lib/bridgetown-core/concerns/site/writable.rb +6 -9
- data/lib/bridgetown-core/configuration.rb +19 -48
- data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
- data/lib/bridgetown-core/configurations/turbo.rb +1 -1
- data/lib/bridgetown-core/converter.rb +1 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +3 -2
- data/lib/bridgetown-core/converters/liquid_templates.rb +3 -2
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
- data/lib/bridgetown-core/converters/smartypants.rb +1 -0
- data/lib/bridgetown-core/current.rb +4 -0
- data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
- data/lib/bridgetown-core/drops/drop.rb +4 -4
- data/lib/bridgetown-core/drops/generated_page_drop.rb +23 -0
- data/lib/bridgetown-core/drops/resource_drop.rb +3 -3
- data/lib/bridgetown-core/drops/site_drop.rb +3 -47
- data/lib/bridgetown-core/entry_filter.rb +1 -0
- data/lib/bridgetown-core/errors.rb +0 -2
- data/lib/bridgetown-core/filters/url_filters.rb +2 -0
- data/lib/bridgetown-core/filters.rb +11 -12
- data/lib/bridgetown-core/frontmatter_defaults.rb +52 -90
- data/lib/bridgetown-core/{page.rb → generated_page.rb} +34 -60
- data/lib/bridgetown-core/generators/prototype_generator.rb +49 -61
- data/lib/bridgetown-core/helpers.rb +8 -3
- data/lib/bridgetown-core/hooks.rb +2 -2
- data/lib/bridgetown-core/layout.rb +15 -4
- data/lib/bridgetown-core/liquid_renderer.rb +1 -3
- data/lib/bridgetown-core/log_adapter.rb +1 -1
- data/lib/bridgetown-core/log_writer.rb +7 -1
- data/lib/bridgetown-core/model/base.rb +12 -4
- data/lib/bridgetown-core/model/builder_origin.rb +23 -11
- data/lib/bridgetown-core/model/origin.rb +3 -0
- data/lib/bridgetown-core/model/plugin_origin.rb +34 -0
- data/lib/bridgetown-core/model/repo_origin.rb +1 -1
- data/lib/bridgetown-core/plugin_manager.rb +10 -10
- data/lib/bridgetown-core/publisher.rb +1 -1
- data/lib/bridgetown-core/rack/boot.rb +47 -0
- data/lib/bridgetown-core/rack/logger.rb +22 -0
- data/lib/bridgetown-core/rack/roda.rb +66 -0
- data/lib/bridgetown-core/rack/routes.rb +88 -0
- data/lib/bridgetown-core/rack/static_indexes.rb +30 -0
- data/lib/bridgetown-core/reader.rb +20 -47
- data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
- data/lib/bridgetown-core/readers/plugin_content_reader.rb +8 -7
- data/lib/bridgetown-core/renderer.rb +2 -12
- data/lib/bridgetown-core/resource/base.rb +51 -27
- data/lib/bridgetown-core/resource/permalink_processor.rb +23 -12
- data/lib/bridgetown-core/resource/relations.rb +2 -3
- data/lib/bridgetown-core/resource/taxonomy_term.rb +1 -5
- data/lib/bridgetown-core/resource/transformer.rb +8 -6
- data/lib/bridgetown-core/ruby_template_view.rb +6 -8
- data/lib/bridgetown-core/site.rb +4 -8
- data/lib/bridgetown-core/static_file.rb +14 -21
- data/lib/bridgetown-core/tags/find.rb +6 -6
- data/lib/bridgetown-core/tags/highlight.rb +5 -5
- data/lib/bridgetown-core/tags/include.rb +22 -32
- data/lib/bridgetown-core/tags/link.rb +4 -0
- data/lib/bridgetown-core/tags/live_reload_dev_js.rb +13 -0
- data/lib/bridgetown-core/tags/post_url.rb +9 -14
- data/lib/bridgetown-core/tags/render_content.rb +2 -2
- data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +54 -0
- data/lib/bridgetown-core/url.rb +5 -4
- data/lib/bridgetown-core/utils/aux.rb +57 -0
- data/lib/bridgetown-core/utils/ruby_exec.rb +3 -45
- data/lib/bridgetown-core/utils/ruby_front_matter.rb +22 -7
- data/lib/bridgetown-core/utils.rb +60 -33
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +4 -6
- data/lib/bridgetown-core.rb +16 -23
- data/lib/site_template/Gemfile.erb +6 -2
- data/lib/site_template/README.md +6 -6
- data/lib/site_template/Rakefile +49 -0
- data/lib/site_template/bridgetown.config.yml +2 -3
- data/lib/site_template/config/puma.rb +27 -0
- data/lib/site_template/config.ru +7 -0
- data/lib/site_template/frontend/javascript/index.js.erb +3 -3
- data/lib/site_template/package.json.erb +7 -12
- data/lib/site_template/server/roda_app.rb +22 -0
- data/lib/site_template/server/routes/hello.rb.sample +10 -0
- data/lib/site_template/src/_components/head.liquid +2 -1
- data/lib/site_template/src/about.md +0 -1
- data/lib/site_template/src/posts.md +2 -3
- metadata +63 -18
- data/lib/bridgetown-core/concerns/data_accessible.rb +0 -20
- data/lib/bridgetown-core/concerns/validatable.rb +0 -56
- data/lib/bridgetown-core/document.rb +0 -437
- data/lib/bridgetown-core/drops/document_drop.rb +0 -80
- data/lib/bridgetown-core/drops/excerpt_drop.rb +0 -19
- data/lib/bridgetown-core/drops/page_drop.rb +0 -18
- data/lib/bridgetown-core/excerpt.rb +0 -200
- data/lib/bridgetown-core/readers/data_reader.rb +0 -89
- data/lib/bridgetown-core/readers/page_reader.rb +0 -26
- data/lib/bridgetown-core/readers/post_reader.rb +0 -109
- data/lib/bridgetown-core/regenerator.rb +0 -202
- data/lib/bridgetown-core/related_posts.rb +0 -55
- data/lib/site_template/config/.keep +0 -0
- data/lib/site_template/start.js +0 -17
- data/lib/site_template/sync.js +0 -35
|
@@ -30,9 +30,9 @@ module Bridgetown
|
|
|
30
30
|
def initialize(model:)
|
|
31
31
|
@model = model
|
|
32
32
|
@site = model.site
|
|
33
|
-
|
|
33
|
+
@data = front_matter_defaults
|
|
34
34
|
|
|
35
|
-
trigger_hooks
|
|
35
|
+
trigger_hooks :post_init
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Collection associated with this resource
|
|
@@ -53,7 +53,7 @@ module Bridgetown
|
|
|
53
53
|
@layout = site.layouts[data.layout].tap do |layout|
|
|
54
54
|
unless layout
|
|
55
55
|
Bridgetown.logger.warn "Resource:", "Layout '#{data.layout}' " \
|
|
56
|
-
|
|
56
|
+
"requested via #{relative_path} does not exist."
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -75,20 +75,21 @@ module Bridgetown
|
|
|
75
75
|
@relations ||= Bridgetown::Resource::Relations.new(self)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
# Loads in any default front matter associated with the resource.
|
|
79
|
+
#
|
|
80
|
+
# @return [HashWithDotAccess::Hash]
|
|
81
|
+
def front_matter_defaults
|
|
82
|
+
site.frontmatter_defaults.all(
|
|
83
|
+
relative_path.to_s,
|
|
84
|
+
collection.label.to_sym
|
|
85
|
+
).with_dot_access
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Merges new data into the existing data hash.
|
|
89
|
+
#
|
|
78
90
|
# @param new_data [HashWithDotAccess::Hash]
|
|
79
91
|
def data=(new_data)
|
|
80
|
-
|
|
81
|
-
raise "#{self.class} data should be of type HashWithDotAccess::Hash"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
@data = new_data
|
|
85
|
-
@data.default_proc = proc do |_, key|
|
|
86
|
-
site.frontmatter_defaults.find(
|
|
87
|
-
relative_path.to_s,
|
|
88
|
-
collection.label.to_sym,
|
|
89
|
-
key.to_s
|
|
90
|
-
)
|
|
91
|
-
end
|
|
92
|
+
@data = @data.merge(new_data)
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
# @return [Bridgetown::Resource::Base]
|
|
@@ -107,7 +108,7 @@ module Bridgetown
|
|
|
107
108
|
|
|
108
109
|
@destination = Destination.new(self) if requires_destination?
|
|
109
110
|
|
|
110
|
-
trigger_hooks
|
|
111
|
+
trigger_hooks :post_read
|
|
111
112
|
|
|
112
113
|
self
|
|
113
114
|
end
|
|
@@ -115,6 +116,8 @@ module Bridgetown
|
|
|
115
116
|
|
|
116
117
|
def transform!
|
|
117
118
|
transformer.process! unless collection.data?
|
|
119
|
+
|
|
120
|
+
self
|
|
118
121
|
end
|
|
119
122
|
|
|
120
123
|
def trigger_hooks(hook_name, *args)
|
|
@@ -188,7 +191,7 @@ module Bridgetown
|
|
|
188
191
|
def summary
|
|
189
192
|
return summary_extension_output if respond_to?(:summary_extension_output)
|
|
190
193
|
|
|
191
|
-
content.to_s.strip.lines.first.to_s.strip
|
|
194
|
+
content.to_s.strip.lines.first.to_s.strip.html_safe
|
|
192
195
|
end
|
|
193
196
|
|
|
194
197
|
# @return [Hash<String, Hash<String => Bridgetown::Resource::TaxonomyType,
|
|
@@ -260,19 +263,18 @@ module Bridgetown
|
|
|
260
263
|
"#<#{self.class} #{id}>"
|
|
261
264
|
end
|
|
262
265
|
|
|
263
|
-
# Compare this
|
|
264
|
-
# Comparison is a comparison between the 2 paths of the
|
|
266
|
+
# Compare this resource against another resource.
|
|
267
|
+
# Comparison is a comparison between the 2 dates or paths of the resources.
|
|
265
268
|
#
|
|
266
|
-
#
|
|
267
|
-
# equal or greater than the other doc's path. See String#<=> for more details.
|
|
269
|
+
# @return [Integer] -1, 0, or +1
|
|
268
270
|
def <=>(other) # rubocop:todo Metrics/AbcSize
|
|
269
271
|
return nil unless other.respond_to?(:data)
|
|
270
272
|
|
|
271
|
-
if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
cmp = if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
|
|
274
|
+
data.date.to_datetime <=> other.data.date.to_datetime
|
|
275
|
+
end
|
|
274
276
|
|
|
275
|
-
cmp = data["date"] <=> other.data["date"]
|
|
277
|
+
cmp = data["date"] <=> other.data["date"] if cmp.nil?
|
|
276
278
|
cmp = path <=> other.path if cmp.nil? || cmp.zero?
|
|
277
279
|
cmp
|
|
278
280
|
end
|
|
@@ -291,7 +293,9 @@ module Bridgetown
|
|
|
291
293
|
|
|
292
294
|
private
|
|
293
295
|
|
|
294
|
-
def ensure_default_data
|
|
296
|
+
def ensure_default_data # rubocop:todo Metrics/AbcSize
|
|
297
|
+
determine_locale
|
|
298
|
+
|
|
295
299
|
slug = if matches = relative_path.to_s.match(DATE_FILENAME_MATCHER) # rubocop:disable Lint/AssignmentInCondition
|
|
296
300
|
set_date_from_string(matches[1]) unless data.date
|
|
297
301
|
matches[2]
|
|
@@ -299,6 +303,8 @@ module Bridgetown
|
|
|
299
303
|
basename_without_ext
|
|
300
304
|
end
|
|
301
305
|
|
|
306
|
+
slug.chomp!(".#{data.locale}") if data.locale && slug.ends_with?(".#{data.locale}")
|
|
307
|
+
|
|
302
308
|
data.slug ||= slug
|
|
303
309
|
data.title ||= Bridgetown::Utils.titleize_slug(slug)
|
|
304
310
|
end
|
|
@@ -308,7 +314,7 @@ module Bridgetown
|
|
|
308
314
|
|
|
309
315
|
data.date = Bridgetown::Utils.parse_date(
|
|
310
316
|
new_date,
|
|
311
|
-
"
|
|
317
|
+
"Resource '#{relative_path}' does not have a valid date."
|
|
312
318
|
)
|
|
313
319
|
end
|
|
314
320
|
|
|
@@ -331,6 +337,24 @@ module Bridgetown
|
|
|
331
337
|
end
|
|
332
338
|
end
|
|
333
339
|
|
|
340
|
+
def determine_locale # rubocop:todo Metrics/AbcSize
|
|
341
|
+
unless data.locale
|
|
342
|
+
data.locale = locale_from_alt_data_or_filename.presence || site.config.default_locale
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
return unless data.locale_overrides.is_a?(Hash) && data.locale_overrides&.key?(data.locale)
|
|
346
|
+
|
|
347
|
+
data.merge!(data.locale_overrides[data.locale])
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Look for alternative front matter or look at the filename pattern: slug.locale.ext
|
|
351
|
+
def locale_from_alt_data_or_filename
|
|
352
|
+
found_locale = data.language || data.lang || basename_without_ext.split(".")[1..-1].last
|
|
353
|
+
return unless found_locale && site.config.available_locales.include?(found_locale.to_sym)
|
|
354
|
+
|
|
355
|
+
found_locale
|
|
356
|
+
end
|
|
357
|
+
|
|
334
358
|
def format_url(url)
|
|
335
359
|
url.to_s.sub(%r{index\.html?$}, "").sub(%r{\.html?$}, "")
|
|
336
360
|
end
|
|
@@ -36,20 +36,20 @@ module Bridgetown
|
|
|
36
36
|
new_url = url_segments.map do |segment|
|
|
37
37
|
segment.starts_with?(":") ? process_segment(segment.sub(%r{^:}, "")) : segment
|
|
38
38
|
end.select(&:present?).join("/")
|
|
39
|
-
|
|
40
39
|
# No relative URLs should ever end in /index.html
|
|
41
40
|
new_url.sub!(%r{/index$}, "") if final_ext == ".html"
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
ensure_base_path finalize_permalink(new_url, permalink)
|
|
44
43
|
end
|
|
45
44
|
|
|
46
45
|
def process_segment(segment)
|
|
47
46
|
segment = segment.to_sym
|
|
48
47
|
if self.class.placeholder_processors[segment]
|
|
49
48
|
segment_value = self.class.placeholder_processors[segment].(resource)
|
|
50
|
-
|
|
49
|
+
case segment_value
|
|
50
|
+
when Hash
|
|
51
51
|
segment_value[:raw_value]
|
|
52
|
-
|
|
52
|
+
when Array
|
|
53
53
|
segment_value.map do |subsegment|
|
|
54
54
|
Utils.slugify(subsegment, mode: slugify_mode)
|
|
55
55
|
end.join("/")
|
|
@@ -66,13 +66,13 @@ module Bridgetown
|
|
|
66
66
|
|
|
67
67
|
case permalink_style.to_sym
|
|
68
68
|
when :pretty
|
|
69
|
-
"
|
|
69
|
+
"/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug/"
|
|
70
70
|
when :pretty_ext, :date
|
|
71
|
-
"
|
|
71
|
+
"/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug.*"
|
|
72
72
|
when :simple
|
|
73
|
-
"
|
|
73
|
+
"/:locale/#{collection_prefix}/:categories/:slug/"
|
|
74
74
|
when :simple_ext
|
|
75
|
-
"
|
|
75
|
+
"/:locale/#{collection_prefix}/:categories/:slug.*"
|
|
76
76
|
else
|
|
77
77
|
permalink_style.to_s
|
|
78
78
|
end
|
|
@@ -96,7 +96,7 @@ module Bridgetown
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
def
|
|
99
|
+
def ensure_base_path(permalink)
|
|
100
100
|
if resource.site.base_path.present?
|
|
101
101
|
return "#{resource.site.base_path(strip_slash_only: true)}#{permalink}"
|
|
102
102
|
end
|
|
@@ -108,7 +108,16 @@ module Bridgetown
|
|
|
108
108
|
|
|
109
109
|
# @param resource [Bridgetown::Resource::Base]
|
|
110
110
|
register_placeholder :path, ->(resource) do
|
|
111
|
-
{
|
|
111
|
+
{
|
|
112
|
+
raw_value: resource.relative_path_basename_without_prefix.tap do |path|
|
|
113
|
+
if resource.site.config["collections_dir"].present?
|
|
114
|
+
path.delete_prefix! "#{resource.site.config["collections_dir"]}/"
|
|
115
|
+
end
|
|
116
|
+
if resource.data.locale && path.ends_with?(".#{resource.data.locale}")
|
|
117
|
+
path.chomp!(".#{resource.data.locale}")
|
|
118
|
+
end
|
|
119
|
+
end,
|
|
120
|
+
}
|
|
112
121
|
end
|
|
113
122
|
|
|
114
123
|
# @param resource [Bridgetown::Resource::Base]
|
|
@@ -128,8 +137,10 @@ module Bridgetown
|
|
|
128
137
|
|
|
129
138
|
# @param resource [Bridgetown::Resource::Base]
|
|
130
139
|
register_placeholder :locale, ->(resource) do
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
next nil if resource.data.locale&.to_sym == resource.site.config.default_locale
|
|
141
|
+
|
|
142
|
+
locale_data = resource.data.locale&.to_sym
|
|
143
|
+
resource.site.config.available_locales.include?(locale_data) ? locale_data.to_s : nil
|
|
133
144
|
end
|
|
134
145
|
register_placeholder :lang, placeholder_processors[:locale]
|
|
135
146
|
|
|
@@ -94,9 +94,8 @@ module Bridgetown
|
|
|
94
94
|
# @return [Bridgetown::Resource::Base, Array<Bridgetown::Resource::Base>]
|
|
95
95
|
def belongs_to_relation_for_type(type)
|
|
96
96
|
if resource.data[type].is_a?(Array)
|
|
97
|
-
other_collection_for_type(type).
|
|
98
|
-
|
|
99
|
-
end
|
|
97
|
+
other_slugs = other_collection_for_type(type).resources_by_slug
|
|
98
|
+
resource.data[type].map { |slug| other_slugs[slug] }.compact
|
|
100
99
|
else
|
|
101
100
|
other_collection_for_type(type).resources.find do |other_resource|
|
|
102
101
|
other_resource.data.slug == resource.data[type]
|
|
@@ -41,7 +41,7 @@ module Bridgetown
|
|
|
41
41
|
def execute_inline_ruby!
|
|
42
42
|
return unless site.config.should_execute_inline_ruby?
|
|
43
43
|
|
|
44
|
-
Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource
|
|
44
|
+
Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def inspect
|
|
@@ -103,10 +103,12 @@ module Bridgetown
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def warn_on_missing_layout(layout, layout_name)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
return unless layout.nil? && layout_name
|
|
107
|
+
|
|
108
|
+
Bridgetown.logger.warn(
|
|
109
|
+
"Build Warning:",
|
|
110
|
+
"Layout '#{layout_name}' requested via #{resource.relative_path} does not exist."
|
|
111
|
+
)
|
|
110
112
|
end
|
|
111
113
|
|
|
112
114
|
### Transformation Actions
|
|
@@ -152,7 +154,7 @@ module Bridgetown
|
|
|
152
154
|
layout_input = layout.content.dup
|
|
153
155
|
|
|
154
156
|
layout_converters.inject(layout_input) do |content, converter|
|
|
155
|
-
next(content) unless [2, -2].include?(converter.method(:convert).arity)
|
|
157
|
+
next(content) unless [2, -2].include?(converter.method(:convert).arity) # rubocop:disable Performance/CollectionLiteralInLoop
|
|
156
158
|
|
|
157
159
|
layout.current_document = resource
|
|
158
160
|
layout.current_document_output = output
|
|
@@ -61,19 +61,17 @@ module Bridgetown
|
|
|
61
61
|
@helpers ||= Helpers.new(self, site)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
helpers.send method.to_sym, *args, &block
|
|
64
|
+
ruby2_keywords def method_missing(method_name, *args, &block)
|
|
65
|
+
if helpers.respond_to?(method_name.to_sym)
|
|
66
|
+
helpers.send method_name.to_sym, *args, &block
|
|
68
67
|
else
|
|
69
68
|
super
|
|
70
69
|
end
|
|
71
70
|
end
|
|
72
71
|
|
|
73
|
-
def respond_to_missing?(
|
|
74
|
-
helpers.respond_to?(
|
|
72
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
73
|
+
helpers.respond_to?(method_name.to_sym, include_private) || super
|
|
75
74
|
end
|
|
76
|
-
# rubocop:enable Style/MissingRespondToMissing
|
|
77
75
|
|
|
78
76
|
private
|
|
79
77
|
|
|
@@ -84,7 +82,7 @@ module Bridgetown
|
|
|
84
82
|
["{% render \"#{component}\""]
|
|
85
83
|
end
|
|
86
84
|
unless options.empty?
|
|
87
|
-
render_statement << ",
|
|
85
|
+
render_statement << ", #{options.keys.map { |k| "#{k}: #{k}" }.join(", ")}"
|
|
88
86
|
end
|
|
89
87
|
render_statement << " %}"
|
|
90
88
|
if options[:_block_content]
|
data/lib/bridgetown-core/site.rb
CHANGED
|
@@ -10,10 +10,11 @@ module Bridgetown
|
|
|
10
10
|
include Localizable
|
|
11
11
|
include Processable
|
|
12
12
|
include Renderable
|
|
13
|
+
include SSR
|
|
13
14
|
include Writable
|
|
14
15
|
|
|
15
16
|
attr_reader :root_dir, :source, :dest, :cache_dir, :config,
|
|
16
|
-
:
|
|
17
|
+
:liquid_renderer, :components_load_paths,
|
|
17
18
|
:includes_load_paths
|
|
18
19
|
|
|
19
20
|
# All files not pages/documents or structured data in the source folder
|
|
@@ -23,12 +24,8 @@ module Bridgetown
|
|
|
23
24
|
# @return [Array<Layout>]
|
|
24
25
|
attr_accessor :layouts
|
|
25
26
|
|
|
26
|
-
# @return [Array<
|
|
27
|
-
attr_accessor :
|
|
28
|
-
|
|
29
|
-
# NOTE: Eventually pages will be deprecated once the Resource content engine
|
|
30
|
-
# is default
|
|
31
|
-
alias_method :generated_pages, :pages
|
|
27
|
+
# @return [Array<GeneratedPage>]
|
|
28
|
+
attr_accessor :generated_pages
|
|
32
29
|
|
|
33
30
|
attr_accessor :permalink_style, :time, :data,
|
|
34
31
|
:file_read_opts, :plugin_manager, :converters,
|
|
@@ -44,7 +41,6 @@ module Bridgetown
|
|
|
44
41
|
@plugin_manager = PluginManager.new(self)
|
|
45
42
|
@cleaner = Cleaner.new(self)
|
|
46
43
|
@reader = Reader.new(self)
|
|
47
|
-
@regenerator = Regenerator.new(self)
|
|
48
44
|
@liquid_renderer = LiquidRenderer.new(self)
|
|
49
45
|
|
|
50
46
|
ensure_not_in_dest
|
|
@@ -21,10 +21,11 @@ module Bridgetown
|
|
|
21
21
|
|
|
22
22
|
# Initialize a new StaticFile.
|
|
23
23
|
#
|
|
24
|
-
# site
|
|
25
|
-
# base
|
|
26
|
-
# dir
|
|
27
|
-
# name
|
|
24
|
+
# @param site [Bridgetown::Site]
|
|
25
|
+
# @param base [String] path to the <source>.
|
|
26
|
+
# @param dir [String] path between <source> and the file.
|
|
27
|
+
# @param name [String] filename of the file.
|
|
28
|
+
# @param collection [Bridgetown::Collection] optional collection the file is attached to
|
|
28
29
|
def initialize(site, base, dir, name, collection = nil) # rubocop:disable Metrics/ParameterLists
|
|
29
30
|
@site = site
|
|
30
31
|
@base = base
|
|
@@ -34,20 +35,16 @@ module Bridgetown
|
|
|
34
35
|
@relative_path = File.join(*[@dir, @name].compact)
|
|
35
36
|
@extname = File.extname(@name)
|
|
36
37
|
@data = @site.frontmatter_defaults.all(relative_path, type).with_dot_access
|
|
37
|
-
if
|
|
38
|
-
|
|
39
|
-
"/:collection/:path.*"
|
|
38
|
+
data.permalink ||= if collection && !collection.builtin?
|
|
39
|
+
"#{collection.default_permalink.chomp("/").chomp(".*")}.*"
|
|
40
40
|
else
|
|
41
41
|
"/:path.*"
|
|
42
42
|
end
|
|
43
|
-
end
|
|
44
43
|
end
|
|
45
44
|
|
|
46
45
|
# Returns source file path.
|
|
47
46
|
def path
|
|
48
|
-
@path ||=
|
|
49
|
-
File.join(*[@base, @dir, @name].compact)
|
|
50
|
-
end
|
|
47
|
+
@path ||= File.join(*[@base, @dir, @name].compact)
|
|
51
48
|
end
|
|
52
49
|
|
|
53
50
|
# Obtain destination path.
|
|
@@ -58,7 +55,7 @@ module Bridgetown
|
|
|
58
55
|
def destination(dest)
|
|
59
56
|
dest = site.in_dest_dir(dest)
|
|
60
57
|
dest_url = url
|
|
61
|
-
if site.
|
|
58
|
+
if site.base_path.present? && collection
|
|
62
59
|
dest_url = dest_url.delete_prefix site.base_path(strip_slash_only: true)
|
|
63
60
|
end
|
|
64
61
|
site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
|
|
@@ -112,6 +109,7 @@ module Bridgetown
|
|
|
112
109
|
|
|
113
110
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
114
111
|
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
|
112
|
+
Bridgetown.logger.debug "Saving file:", dest_path
|
|
115
113
|
copy_file(dest_path)
|
|
116
114
|
|
|
117
115
|
true
|
|
@@ -177,14 +175,9 @@ module Bridgetown
|
|
|
177
175
|
site.config.content_engine != "resource"
|
|
178
176
|
base = if @collection.nil? || special_posts_case
|
|
179
177
|
cleaned_relative_path
|
|
180
|
-
|
|
178
|
+
else
|
|
181
179
|
newly_processed = true
|
|
182
180
|
Bridgetown::Resource::PermalinkProcessor.new(self).transform
|
|
183
|
-
else
|
|
184
|
-
Bridgetown::URL.new(
|
|
185
|
-
template: @collection.url_template,
|
|
186
|
-
placeholders: placeholders
|
|
187
|
-
)
|
|
188
181
|
end.to_s.chomp("/")
|
|
189
182
|
newly_processed ? base : "#{base}#{extname}"
|
|
190
183
|
end
|
|
@@ -212,9 +205,9 @@ module Bridgetown
|
|
|
212
205
|
def copy_file(dest_path)
|
|
213
206
|
FileUtils.copy_entry(path, dest_path)
|
|
214
207
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
208
|
+
return if File.symlink?(dest_path)
|
|
209
|
+
|
|
210
|
+
File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
|
|
218
211
|
end
|
|
219
212
|
end
|
|
220
213
|
end
|
|
@@ -11,12 +11,7 @@ module Bridgetown
|
|
|
11
11
|
|
|
12
12
|
def initialize(tag_name, markup, tokens)
|
|
13
13
|
super
|
|
14
|
-
|
|
15
|
-
@new_var_name = Regexp.last_match(1).strip
|
|
16
|
-
@single_or_group = Regexp.last_match(2)
|
|
17
|
-
@arr_name = Regexp.last_match(3).strip
|
|
18
|
-
@conditions = process_conditions(Regexp.last_match(4).strip)
|
|
19
|
-
else
|
|
14
|
+
unless markup.strip =~ SYNTAX
|
|
20
15
|
raise SyntaxError, <<~MSG
|
|
21
16
|
Syntax Error in tag 'find' while parsing the following markup:
|
|
22
17
|
|
|
@@ -25,6 +20,11 @@ module Bridgetown
|
|
|
25
20
|
Valid syntax: find <varname> where|in <array>, <condition(s)>
|
|
26
21
|
MSG
|
|
27
22
|
end
|
|
23
|
+
|
|
24
|
+
@new_var_name = Regexp.last_match(1).strip
|
|
25
|
+
@single_or_group = Regexp.last_match(2)
|
|
26
|
+
@arr_name = Regexp.last_match(3).strip
|
|
27
|
+
@conditions = process_conditions(Regexp.last_match(4).strip)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def render(context)
|
|
@@ -14,10 +14,7 @@ module Bridgetown
|
|
|
14
14
|
|
|
15
15
|
def initialize(tag_name, markup, tokens)
|
|
16
16
|
super
|
|
17
|
-
|
|
18
|
-
@lang = Regexp.last_match(1).downcase
|
|
19
|
-
@highlight_options = parse_options(Regexp.last_match(2))
|
|
20
|
-
else
|
|
17
|
+
unless markup.strip =~ SYNTAX
|
|
21
18
|
raise SyntaxError, <<~MSG
|
|
22
19
|
Syntax Error in tag 'highlight' while parsing the following markup:
|
|
23
20
|
|
|
@@ -26,6 +23,9 @@ module Bridgetown
|
|
|
26
23
|
Valid syntax: highlight <lang> [linenos]
|
|
27
24
|
MSG
|
|
28
25
|
end
|
|
26
|
+
|
|
27
|
+
@lang = Regexp.last_match(1).downcase
|
|
28
|
+
@highlight_options = parse_options(Regexp.last_match(2))
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
LEADING_OR_TRAILING_LINE_TERMINATORS = %r!\A(\n|\r)+|(\n|\r)+\z!.freeze
|
|
@@ -89,7 +89,7 @@ module Bridgetown
|
|
|
89
89
|
"data-lang=\"#{@lang}\"",
|
|
90
90
|
].join(" ")
|
|
91
91
|
"<figure class=\"highlight\"><pre><code #{code_attributes}>"\
|
|
92
|
-
|
|
92
|
+
"#{code.chomp}</code></pre></figure>"
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
end
|
|
@@ -9,15 +9,18 @@ module Bridgetown
|
|
|
9
9
|
|
|
10
10
|
VALID_SYNTAX = %r!
|
|
11
11
|
([\w-]+)\s*=\s*
|
|
12
|
-
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w
|
|
12
|
+
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.-]+))
|
|
13
13
|
!x.freeze
|
|
14
|
+
|
|
15
|
+
# rubocop:disable Lint/MixedRegexpCaptureTypes
|
|
14
16
|
VARIABLE_SYNTAX = %r!
|
|
15
|
-
(?<variable>[^{]*(\{\{\s*[\w
|
|
17
|
+
(?<variable>[^{]*(\{\{\s*[\w\-.]+\s*(\|.*)?\}\}[^\s{}]*)+)
|
|
16
18
|
(?<params>.*)
|
|
17
19
|
!mx.freeze
|
|
20
|
+
# rubocop:enable Lint/MixedRegexpCaptureTypes
|
|
18
21
|
|
|
19
22
|
FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
|
|
20
|
-
VALID_FILENAME_CHARS = %r!^[\w
|
|
23
|
+
VALID_FILENAME_CHARS = %r!^[\w/.-]+$!.freeze
|
|
21
24
|
INVALID_SEQUENCES = %r![./]{2,}!.freeze
|
|
22
25
|
|
|
23
26
|
def initialize(tag_name, markup, tokens)
|
|
@@ -66,33 +69,33 @@ module Bridgetown
|
|
|
66
69
|
end
|
|
67
70
|
|
|
68
71
|
def validate_file_name(file)
|
|
69
|
-
|
|
70
|
-
raise ArgumentError, <<~MSG
|
|
71
|
-
Invalid syntax for include tag. File contains invalid characters or sequences:
|
|
72
|
+
return unless INVALID_SEQUENCES.match?(file) || !VALID_FILENAME_CHARS.match?(file)
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
raise ArgumentError, <<~MSG
|
|
75
|
+
Invalid syntax for include tag. File contains invalid characters or sequences:
|
|
74
76
|
|
|
75
|
-
|
|
77
|
+
#{file}
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
Valid syntax:
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
#{syntax_example}
|
|
82
|
+
|
|
83
|
+
MSG
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
def validate_params
|
|
84
|
-
|
|
85
|
-
raise ArgumentError, <<~MSG
|
|
86
|
-
Invalid syntax for include tag:
|
|
87
|
+
return if FULL_VALID_SYNTAX.match?(@params)
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
raise ArgumentError, <<~MSG
|
|
90
|
+
Invalid syntax for include tag:
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
#{@params}
|
|
91
93
|
|
|
92
|
-
|
|
94
|
+
Valid syntax:
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
#{syntax_example}
|
|
97
|
+
|
|
98
|
+
MSG
|
|
96
99
|
end
|
|
97
100
|
|
|
98
101
|
# Grab file read opts in the context
|
|
@@ -119,16 +122,12 @@ module Bridgetown
|
|
|
119
122
|
end
|
|
120
123
|
|
|
121
124
|
def render(context)
|
|
122
|
-
site = context.registers[:site]
|
|
123
|
-
|
|
124
125
|
file = render_variable(context) || @file
|
|
125
126
|
validate_file_name(file)
|
|
126
127
|
|
|
127
128
|
path = locate_include_file(context, file)
|
|
128
129
|
return unless path
|
|
129
130
|
|
|
130
|
-
add_include_to_dependency(site, path, context)
|
|
131
|
-
|
|
132
131
|
partial = load_cached_partial(path, context)
|
|
133
132
|
|
|
134
133
|
context.stack do
|
|
@@ -143,15 +142,6 @@ module Bridgetown
|
|
|
143
142
|
end
|
|
144
143
|
end
|
|
145
144
|
|
|
146
|
-
def add_include_to_dependency(site, path, context)
|
|
147
|
-
if context.registers[:page]&.key?("path")
|
|
148
|
-
site.regenerator.add_dependency(
|
|
149
|
-
site.in_source_dir(context.registers[:page]["path"]),
|
|
150
|
-
path
|
|
151
|
-
)
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
145
|
def load_cached_partial(path, context)
|
|
156
146
|
context.registers[:cached_partials] ||= {}
|
|
157
147
|
cached_partial = context.registers[:cached_partials]
|
|
@@ -23,6 +23,10 @@ module Bridgetown
|
|
|
23
23
|
relative_path = Liquid::Template.parse(@relative_path).render(context)
|
|
24
24
|
|
|
25
25
|
site.each_site_file do |item|
|
|
26
|
+
# Resource engine:
|
|
27
|
+
if item.respond_to?(:relative_url) && item.relative_path.to_s == relative_path
|
|
28
|
+
return item.relative_url
|
|
29
|
+
end
|
|
26
30
|
return relative_url(item) if item.relative_path == relative_path
|
|
27
31
|
# This takes care of the case for static files that have a leading /
|
|
28
32
|
return relative_url(item) if item.relative_path == "/#{relative_path}"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bridgetown
|
|
4
|
+
module Tags
|
|
5
|
+
class LiveReloadJsTag < Liquid::Tag
|
|
6
|
+
def render(context)
|
|
7
|
+
Bridgetown::Utils.live_reload_js(context.registers[:site])
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Liquid::Template.register_tag("live_reload_dev_js", Bridgetown::Tags::LiveReloadJsTag)
|