bridgetown-core 0.14.1 → 0.15.0
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/Rakefile +3 -1
- data/bin/bridgetown +9 -23
- data/bridgetown-core.gemspec +3 -1
- data/lib/bridgetown-core.rb +9 -2
- data/lib/bridgetown-core/commands/apply.rb +73 -0
- data/lib/bridgetown-core/commands/base.rb +45 -0
- data/lib/bridgetown-core/commands/build.rb +91 -86
- data/lib/bridgetown-core/commands/clean.rb +30 -29
- data/lib/bridgetown-core/commands/concerns/actions.rb +128 -0
- data/lib/bridgetown-core/commands/concerns/build_options.rb +76 -0
- data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +18 -0
- data/lib/bridgetown-core/commands/concerns/summarizable.rb +13 -0
- data/lib/bridgetown-core/commands/console.rb +57 -39
- data/lib/bridgetown-core/commands/doctor.rb +126 -126
- data/lib/bridgetown-core/commands/new.rb +120 -155
- data/lib/bridgetown-core/commands/plugins.rb +167 -130
- data/lib/bridgetown-core/commands/registrations.rb +16 -0
- data/lib/bridgetown-core/commands/serve.rb +219 -215
- data/lib/bridgetown-core/concerns/convertible.rb +1 -4
- data/lib/bridgetown-core/concerns/site/renderable.rb +1 -2
- data/lib/bridgetown-core/drops/document_drop.rb +9 -1
- data/lib/bridgetown-core/drops/page_drop.rb +1 -1
- data/lib/bridgetown-core/excerpt.rb +4 -1
- data/lib/bridgetown-core/generators/prototype_generator.rb +2 -0
- data/lib/bridgetown-core/liquid_renderer.rb +1 -0
- data/lib/bridgetown-core/liquid_renderer/file.rb +1 -4
- data/lib/bridgetown-core/liquid_renderer/file_system.rb +3 -1
- data/lib/bridgetown-core/page.rb +3 -18
- data/lib/bridgetown-core/plugin_manager.rb +31 -17
- data/lib/bridgetown-core/renderer.rb +31 -18
- data/lib/bridgetown-core/tags/include.rb +14 -0
- data/lib/bridgetown-core/tags/render_content.rb +39 -16
- data/lib/bridgetown-core/tags/with.rb +15 -0
- data/lib/bridgetown-core/utils.rb +44 -0
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +17 -10
- data/lib/site_template/Gemfile.erb +19 -0
- data/lib/site_template/bridgetown.config.yml +5 -3
- data/lib/site_template/package.json +1 -0
- data/lib/site_template/src/_components/footer.liquid +3 -0
- data/lib/site_template/src/_components/head.liquid +9 -0
- data/lib/site_template/src/{_includes/navbar.html → _components/navbar.liquid} +0 -0
- data/lib/site_template/src/_layouts/default.html +3 -3
- data/lib/site_template/start.js +1 -1
- data/lib/site_template/webpack.config.js +3 -3
- metadata +53 -19
- data/lib/bridgetown-core/command.rb +0 -112
- data/lib/bridgetown-core/commands/help.rb +0 -34
- data/lib/site_template/src/_components/.keep +0 -0
- data/lib/site_template/src/_includes/footer.html +0 -3
- data/lib/site_template/src/_includes/head.html +0 -9
@@ -188,13 +188,10 @@ module Bridgetown
|
|
188
188
|
#
|
189
189
|
# Returns nothing.
|
190
190
|
def do_layout(payload, layouts)
|
191
|
-
|
191
|
+
_renderer.tap do |renderer|
|
192
192
|
renderer.layouts = layouts
|
193
193
|
renderer.payload = payload
|
194
194
|
end.run
|
195
|
-
|
196
|
-
Bridgetown.logger.debug "Post-Render Hooks:", relative_path
|
197
|
-
Bridgetown::Hooks.trigger hook_owner, :post_render, self
|
198
195
|
ensure
|
199
196
|
@_renderer = nil # this will allow the modifications above to disappear
|
200
197
|
end
|
@@ -43,8 +43,7 @@ module Bridgetown
|
|
43
43
|
def render_regenerated(document, payload)
|
44
44
|
return unless regenerator.regenerate?(document)
|
45
45
|
|
46
|
-
|
47
|
-
document.trigger_hooks(:post_render)
|
46
|
+
Bridgetown::Renderer.new(self, document, payload).run
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
@@ -12,7 +12,15 @@ module Bridgetown
|
|
12
12
|
mutable false
|
13
13
|
|
14
14
|
def_delegator :@obj, :relative_path, :path
|
15
|
-
def_delegators :@obj,
|
15
|
+
def_delegators :@obj,
|
16
|
+
:id,
|
17
|
+
:output,
|
18
|
+
:content,
|
19
|
+
:to_s,
|
20
|
+
:relative_path,
|
21
|
+
:url,
|
22
|
+
:date,
|
23
|
+
:related_posts
|
16
24
|
|
17
25
|
private def_delegator :@obj, :data, :fallback_data
|
18
26
|
|
@@ -63,6 +63,8 @@ module Bridgetown
|
|
63
63
|
new_page
|
64
64
|
end
|
65
65
|
|
66
|
+
# TODO: this would be a great use of .try
|
67
|
+
# document.try(:collection).try(:label) == @configured_collection
|
66
68
|
def terms_matching_pages(search_term)
|
67
69
|
selected_docs = @site.documents.select do |document|
|
68
70
|
document.respond_to?(:collection) && document.collection.label == @configured_collection
|
@@ -10,11 +10,8 @@ module Bridgetown
|
|
10
10
|
|
11
11
|
def parse(content)
|
12
12
|
measure_time do
|
13
|
-
# Remove extraneous indentation for rendercontent tags
|
14
|
-
processed_content = content.gsub(%r!^[ \t]+{%-? rendercontent!, "{% rendercontent")
|
15
|
-
|
16
13
|
@renderer.cache[@filename] ||= Liquid::Template.parse(
|
17
|
-
|
14
|
+
content, line_numbers: true
|
18
15
|
)
|
19
16
|
end
|
20
17
|
@template = @renderer.cache[@filename]
|
@@ -31,7 +31,9 @@ module Bridgetown
|
|
31
31
|
raise Liquid::FileSystemError, "No such template '#{template_path}'" if found_paths.empty?
|
32
32
|
|
33
33
|
# Last path in the list wins
|
34
|
-
|
34
|
+
LiquidComponent.parse(
|
35
|
+
::File.read(found_paths.last, site.file_read_opts)
|
36
|
+
).content
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
data/lib/bridgetown-core/page.rb
CHANGED
@@ -73,18 +73,6 @@ module Bridgetown
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
# For backwards-compatibility in subclasses that do not redefine
|
77
|
-
# the `:to_liquid` method, stash existing definition under a new name
|
78
|
-
#
|
79
|
-
# TODO: Remove in Bridgetown 5.0
|
80
|
-
alias_method :legacy_to_liquid, :to_liquid
|
81
|
-
private :legacy_to_liquid
|
82
|
-
|
83
|
-
# Private
|
84
|
-
# Subclasses can choose to optimize their `:to_liquid` method by wrapping
|
85
|
-
# it around this definition.
|
86
|
-
#
|
87
|
-
# TODO: Remove in Bridgetown 5.0
|
88
76
|
def liquid_drop
|
89
77
|
@liquid_drop ||= begin
|
90
78
|
defaults = site.frontmatter_defaults.all(relative_path, type)
|
@@ -94,15 +82,12 @@ module Bridgetown
|
|
94
82
|
Drops::PageDrop.new(self)
|
95
83
|
end
|
96
84
|
end
|
97
|
-
private :liquid_drop
|
98
85
|
|
99
86
|
# Public
|
100
87
|
#
|
101
88
|
# Liquid representation of current page
|
102
|
-
|
103
|
-
|
104
|
-
def to_liquid(attrs = nil)
|
105
|
-
self.class == Bridgetown::Page ? liquid_drop : legacy_to_liquid(attrs)
|
89
|
+
def to_liquid
|
90
|
+
liquid_drop
|
106
91
|
end
|
107
92
|
|
108
93
|
# The full path and filename of the post. Defined in the YAML of the post
|
@@ -180,7 +165,7 @@ module Bridgetown
|
|
180
165
|
|
181
166
|
# The path to the page source file, relative to the site source
|
182
167
|
def relative_path
|
183
|
-
@relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).
|
168
|
+
@relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).delete_prefix("/")
|
184
169
|
end
|
185
170
|
|
186
171
|
# Obtain destination path.
|
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Bridgetown
|
4
4
|
class PluginManager
|
5
|
+
PLUGINS_GROUP = :bridgetown_plugins
|
6
|
+
YARN_DEPENDENCY_REGEXP = %r!(.+)@([^@]*)$!.freeze
|
7
|
+
|
5
8
|
attr_reader :site
|
6
9
|
|
7
10
|
@source_manifests = Set.new
|
@@ -40,11 +43,9 @@ module Bridgetown
|
|
40
43
|
if !ENV["BRIDGETOWN_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
|
41
44
|
require "bundler"
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
required_gems = Bundler.require group_name
|
46
|
+
required_gems = Bundler.require PLUGINS_GROUP
|
46
47
|
required_gems.select! do |dep|
|
47
|
-
(dep.groups & [
|
48
|
+
(dep.groups & [PLUGINS_GROUP]).any? && dep.should_include?
|
48
49
|
end
|
49
50
|
|
50
51
|
install_yarn_dependencies(required_gems)
|
@@ -67,30 +68,43 @@ module Bridgetown
|
|
67
68
|
# If that exact package hasn't been installed, execute yarn add
|
68
69
|
#
|
69
70
|
# Returns nothing.
|
70
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
71
71
|
def self.install_yarn_dependencies(required_gems)
|
72
72
|
return unless File.exist?("package.json")
|
73
73
|
|
74
74
|
package_json = JSON.parse(File.read("package.json"))
|
75
75
|
|
76
76
|
required_gems.each do |loaded_gem|
|
77
|
-
|
78
|
-
|
79
|
-
yarn_add_dependency = loaded_gem.to_spec.metadata["yarn-add"].split("@")
|
80
|
-
next unless yarn_add_dependency.length == 2
|
81
|
-
|
82
|
-
# check matching version number is see if it's already installed
|
83
|
-
if package_json["dependencies"]
|
84
|
-
current_package = package_json["dependencies"].dig(yarn_add_dependency.first)
|
85
|
-
next unless current_package.nil? || current_package != yarn_add_dependency.last
|
86
|
-
end
|
77
|
+
yarn_dependency = find_yarn_dependency(loaded_gem)
|
78
|
+
next unless add_yarn_dependency?(yarn_dependency, package_json)
|
87
79
|
|
88
80
|
# all right, time to install the package
|
89
|
-
cmd = "yarn add #{
|
81
|
+
cmd = "yarn add #{yarn_dependency.join("@")}"
|
90
82
|
system cmd
|
91
83
|
end
|
92
84
|
end
|
93
|
-
|
85
|
+
|
86
|
+
def self.find_yarn_dependency(loaded_gem)
|
87
|
+
yarn_dependency = loaded_gem.to_spec&.metadata&.dig("yarn-add")&.match(YARN_DEPENDENCY_REGEXP)
|
88
|
+
return nil if yarn_dependency&.length != 3 || yarn_dependency[2] == ""
|
89
|
+
|
90
|
+
yarn_dependency[1..2]
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.add_yarn_dependency?(yarn_dependency, package_json)
|
94
|
+
return false if yarn_dependency.nil?
|
95
|
+
|
96
|
+
# check matching version number is see if it's already installed
|
97
|
+
if package_json["dependencies"]
|
98
|
+
current_version = package_json["dependencies"].dig(yarn_dependency.first)
|
99
|
+
package_requires_updating?(current_version, yarn_dependency.last)
|
100
|
+
else
|
101
|
+
true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.package_requires_updating?(current_version, dep_version)
|
106
|
+
current_version.nil? || current_version != dep_version && !current_version.include?("/")
|
107
|
+
end
|
94
108
|
|
95
109
|
# Require all .rb files
|
96
110
|
#
|
@@ -5,11 +5,16 @@ module Bridgetown
|
|
5
5
|
attr_reader :document, :site
|
6
6
|
attr_writer :layouts, :payload
|
7
7
|
|
8
|
+
class << self
|
9
|
+
attr_accessor :cached_partials
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(site, document, site_payload = nil)
|
9
13
|
@site = site
|
10
14
|
@document = document
|
11
15
|
@payload = site_payload
|
12
16
|
@layouts = nil
|
17
|
+
self.class.cached_partials ||= {}
|
13
18
|
end
|
14
19
|
|
15
20
|
# Fetches the payload used in Liquid rendering.
|
@@ -48,7 +53,7 @@ module Bridgetown
|
|
48
53
|
|
49
54
|
# Prepare payload and render the document
|
50
55
|
#
|
51
|
-
# Returns
|
56
|
+
# Returns nothing
|
52
57
|
def run
|
53
58
|
Bridgetown.logger.debug "Rendering:", document.relative_path
|
54
59
|
|
@@ -58,8 +63,8 @@ module Bridgetown
|
|
58
63
|
assign_layout_data!
|
59
64
|
|
60
65
|
document.trigger_hooks(:pre_render, payload)
|
61
|
-
|
62
|
-
|
66
|
+
document.output = render_document
|
67
|
+
document.trigger_hooks(:post_render)
|
63
68
|
end
|
64
69
|
|
65
70
|
# Render the document.
|
@@ -67,18 +72,14 @@ module Bridgetown
|
|
67
72
|
# Returns String rendered document output
|
68
73
|
# rubocop: disable Metrics/AbcSize
|
69
74
|
def render_document
|
70
|
-
|
71
|
-
registers: { site: site, page: payload["page"] },
|
72
|
-
strict_filters: liquid_options["strict_filters"],
|
73
|
-
strict_variables: liquid_options["strict_variables"],
|
74
|
-
}
|
75
|
+
liquid_context = provide_liquid_context
|
75
76
|
|
76
77
|
execute_inline_ruby!
|
77
78
|
|
78
79
|
output = document.content
|
79
80
|
if document.render_with_liquid?
|
80
81
|
Bridgetown.logger.debug "Rendering Liquid:", document.relative_path
|
81
|
-
output = render_liquid(output, payload,
|
82
|
+
output = render_liquid(output, payload, liquid_context, document.path)
|
82
83
|
end
|
83
84
|
|
84
85
|
Bridgetown.logger.debug "Rendering Markup:", document.relative_path
|
@@ -87,12 +88,24 @@ module Bridgetown
|
|
87
88
|
|
88
89
|
if document.place_in_layout?
|
89
90
|
Bridgetown.logger.debug "Rendering Layout:", document.relative_path
|
90
|
-
output = place_in_layouts(output, payload,
|
91
|
+
output = place_in_layouts(output, payload, liquid_context)
|
91
92
|
end
|
92
93
|
|
93
94
|
output
|
94
95
|
end
|
95
96
|
|
97
|
+
def provide_liquid_context
|
98
|
+
{
|
99
|
+
registers: {
|
100
|
+
site: site,
|
101
|
+
page: payload["page"],
|
102
|
+
cached_partials: self.class.cached_partials,
|
103
|
+
},
|
104
|
+
strict_filters: liquid_options["strict_filters"],
|
105
|
+
strict_variables: liquid_options["strict_variables"],
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
96
109
|
def execute_inline_ruby!
|
97
110
|
return unless site.config.should_execute_inline_ruby?
|
98
111
|
|
@@ -101,21 +114,21 @@ module Bridgetown
|
|
101
114
|
|
102
115
|
# rubocop: enable Metrics/AbcSize
|
103
116
|
|
104
|
-
# Render the given content with the payload and
|
117
|
+
# Render the given content with the payload and context
|
105
118
|
#
|
106
119
|
# content -
|
107
120
|
# payload -
|
108
|
-
#
|
121
|
+
# context -
|
109
122
|
# path - (optional) the path to the file, for use in ex
|
110
123
|
#
|
111
124
|
# Returns String the content, rendered by Liquid.
|
112
|
-
def render_liquid(content, payload,
|
125
|
+
def render_liquid(content, payload, liquid_context, path = nil)
|
113
126
|
template = site.liquid_renderer.file(path).parse(content)
|
114
127
|
template.warnings.each do |e|
|
115
128
|
Bridgetown.logger.warn "Liquid Warning:",
|
116
129
|
LiquidRenderer.format_error(e, path || document.relative_path)
|
117
130
|
end
|
118
|
-
template.render!(payload,
|
131
|
+
template.render!(payload, liquid_context)
|
119
132
|
# rubocop: disable Lint/RescueException
|
120
133
|
rescue Exception => e
|
121
134
|
Bridgetown.logger.error "Liquid Exception:",
|
@@ -151,7 +164,7 @@ module Bridgetown
|
|
151
164
|
# Render layouts and place document content inside.
|
152
165
|
#
|
153
166
|
# Returns String rendered content
|
154
|
-
def place_in_layouts(content, payload,
|
167
|
+
def place_in_layouts(content, payload, liquid_context)
|
155
168
|
output = content.dup
|
156
169
|
layout = layouts[document.data["layout"].to_s]
|
157
170
|
validate_layout(layout)
|
@@ -162,7 +175,7 @@ module Bridgetown
|
|
162
175
|
payload["layout"] = nil
|
163
176
|
|
164
177
|
while layout
|
165
|
-
output = render_layout(output, layout,
|
178
|
+
output = render_layout(output, layout, liquid_context)
|
166
179
|
add_regenerator_dependencies(layout)
|
167
180
|
|
168
181
|
next unless (layout = site.layouts[layout.data["layout"]])
|
@@ -189,14 +202,14 @@ module Bridgetown
|
|
189
202
|
# Render layout content into document.output
|
190
203
|
#
|
191
204
|
# Returns String rendered content
|
192
|
-
def render_layout(output, layout,
|
205
|
+
def render_layout(output, layout, liquid_context)
|
193
206
|
payload["content"] = output
|
194
207
|
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
195
208
|
|
196
209
|
render_liquid(
|
197
210
|
layout.content,
|
198
211
|
payload,
|
199
|
-
|
212
|
+
liquid_context,
|
200
213
|
layout.path
|
201
214
|
)
|
202
215
|
end
|
@@ -3,6 +3,10 @@
|
|
3
3
|
module Bridgetown
|
4
4
|
module Tags
|
5
5
|
class IncludeTag < Liquid::Tag
|
6
|
+
class << self
|
7
|
+
attr_accessor :deprecation_message_shown
|
8
|
+
end
|
9
|
+
|
6
10
|
VALID_SYNTAX = %r!
|
7
11
|
([\w-]+)\s*=\s*
|
8
12
|
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
|
@@ -18,6 +22,14 @@ module Bridgetown
|
|
18
22
|
|
19
23
|
def initialize(tag_name, markup, tokens)
|
20
24
|
super
|
25
|
+
|
26
|
+
unless self.class.deprecation_message_shown
|
27
|
+
Bridgetown.logger.warn "NOTICE: the {% include %} tag is deprecated and" \
|
28
|
+
" will be removed in Bridgetown 1.0. You should" \
|
29
|
+
" use the {% render %} tag instead."
|
30
|
+
self.class.deprecation_message_shown = true
|
31
|
+
end
|
32
|
+
|
21
33
|
matched = markup.strip.match(VARIABLE_SYNTAX)
|
22
34
|
if matched
|
23
35
|
@file = matched["variable"].strip
|
@@ -200,7 +212,9 @@ module Bridgetown
|
|
200
212
|
else
|
201
213
|
File.join(site.config["collections_dir"], page_payload["path"])
|
202
214
|
end
|
215
|
+
# rubocop:disable Performance/DeleteSuffix
|
203
216
|
resource_path.sub!(%r!/#excerpt\z!, "")
|
217
|
+
# rubocop:enable Performance/DeleteSuffix
|
204
218
|
site.in_source_dir File.dirname(resource_path)
|
205
219
|
end
|
206
220
|
end
|
@@ -3,28 +3,51 @@
|
|
3
3
|
module Bridgetown
|
4
4
|
module Tags
|
5
5
|
class BlockRenderTag < Liquid::Block
|
6
|
-
|
7
|
-
|
6
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
7
|
+
def render(context)
|
8
|
+
context.stack({}) do
|
9
|
+
# unindent the incoming text
|
10
|
+
content = Bridgetown::Utils.reindent_for_markdown(super)
|
8
11
|
|
9
|
-
|
10
|
-
@markup = markup
|
11
|
-
@options = options
|
12
|
-
end
|
12
|
+
regions = gather_content_regions(context)
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
site = context.registers[:site]
|
15
|
+
converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
|
16
|
+
markdownified_content = converter.convert(content)
|
17
|
+
context["processed_component_content"] = markdownified_content
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
render_params = [@markup, "content: processed_component_content"]
|
20
|
+
unless regions.empty?
|
21
|
+
regions.each do |region_name, region_content|
|
22
|
+
region_name = region_name.sub("content_with_region_", "")
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
if region_name.end_with? ":markdown"
|
25
|
+
region_name.sub!(%r!:markdown$!, "")
|
26
|
+
context[region_name] = converter.convert(
|
27
|
+
Bridgetown::Utils.reindent_for_markdown(region_content)
|
28
|
+
)
|
29
|
+
else
|
30
|
+
context[region_name] = region_content
|
31
|
+
end
|
32
|
+
render_params.push "#{region_name}: #{region_name}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Liquid::Render.parse("render", render_params.join(","), nil, @parse_context)
|
37
|
+
.render_tag(context, +"")
|
26
38
|
end
|
27
39
|
end
|
40
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def gather_content_regions(context)
|
45
|
+
unless context.scopes[0].keys.find { |k| k.to_s.start_with? "content_with_region_" }
|
46
|
+
return {}
|
47
|
+
end
|
48
|
+
|
49
|
+
context.scopes[0].select { |k| k.to_s.start_with? "content_with_region_" }
|
50
|
+
end
|
28
51
|
end
|
29
52
|
end
|
30
53
|
end
|