bridgetown-core 1.0.0.alpha9 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/bin/bridgetown +6 -1
- data/bridgetown-core.gemspec +4 -3
- data/lib/bridgetown-core/collection.rb +6 -6
- data/lib/bridgetown-core/commands/base.rb +18 -18
- data/lib/bridgetown-core/commands/build.rb +1 -1
- data/lib/bridgetown-core/commands/clean.rb +2 -2
- data/lib/bridgetown-core/commands/console.rb +1 -0
- data/lib/bridgetown-core/commands/esbuild/esbuild.config.js +27 -0
- data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +216 -0
- data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +47 -0
- data/lib/bridgetown-core/commands/esbuild/setup.rb +4 -0
- data/lib/bridgetown-core/commands/esbuild/update.rb +4 -0
- data/lib/bridgetown-core/commands/esbuild.rb +83 -0
- data/lib/bridgetown-core/commands/new.rb +80 -10
- data/lib/bridgetown-core/commands/plugins.rb +1 -1
- data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +1 -1
- data/lib/bridgetown-core/commands/webpack/update.rb +3 -3
- data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +1 -1
- data/lib/bridgetown-core/commands/webpack.rb +3 -3
- data/lib/bridgetown-core/component.rb +9 -3
- data/lib/bridgetown-core/concerns/site/configurable.rb +6 -0
- data/lib/bridgetown-core/concerns/site/content.rb +4 -4
- data/lib/bridgetown-core/concerns/site/extensible.rb +8 -0
- data/lib/bridgetown-core/concerns/site/processable.rb +23 -4
- data/lib/bridgetown-core/concerns/site/ssr.rb +2 -17
- data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
- data/lib/bridgetown-core/configurations/purgecss.rb +2 -1
- data/lib/bridgetown-core/configurations/render/render.yaml.erb +3 -0
- data/lib/bridgetown-core/configurations/stimulus.rb +41 -12
- data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +5 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +31 -2
- data/lib/bridgetown-core/configurations/turbo/turbo_transitions.js +48 -0
- data/lib/bridgetown-core/configurations/turbo.rb +15 -5
- data/lib/bridgetown-core/configurations/vercel/vercel.json +45 -0
- data/lib/bridgetown-core/configurations/vercel/vercel_url.rb +12 -0
- data/lib/bridgetown-core/configurations/vercel.rb +4 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +7 -9
- data/lib/bridgetown-core/converters/ruby_templates.rb +1 -1
- data/lib/bridgetown-core/converters/serbea_templates.rb +5 -8
- data/lib/bridgetown-core/drops/drop.rb +1 -1
- data/lib/bridgetown-core/drops/resource_drop.rb +28 -5
- data/lib/bridgetown-core/errors.rb +21 -0
- data/lib/bridgetown-core/generators/prototype_generator.rb +3 -3
- data/lib/bridgetown-core/helpers.rb +3 -2
- data/lib/bridgetown-core/hooks.rb +51 -20
- data/lib/bridgetown-core/model/base.rb +24 -1
- data/lib/bridgetown-core/model/origin.rb +4 -6
- data/lib/bridgetown-core/model/repo_origin.rb +48 -0
- data/lib/bridgetown-core/rack/boot.rb +5 -9
- data/lib/bridgetown-core/rack/roda.rb +4 -5
- data/lib/bridgetown-core/rack/routes.rb +44 -10
- data/lib/bridgetown-core/rack/static_indexes.rb +2 -0
- data/lib/bridgetown-core/resource/base.rb +3 -1
- data/lib/bridgetown-core/ruby_template_view.rb +11 -0
- data/lib/bridgetown-core/site.rb +5 -0
- data/lib/bridgetown-core/tags/{webpack_path.rb → asset_path.rb} +7 -9
- data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +2 -1
- data/lib/bridgetown-core/utils/loaders_manager.rb +17 -0
- data/lib/bridgetown-core/utils.rb +88 -30
- data/lib/bridgetown-core/version.rb +1 -1
- data/lib/bridgetown-core/watcher.rb +74 -70
- data/lib/bridgetown-core.rb +1 -0
- data/lib/site_template/Gemfile.erb +17 -11
- data/lib/site_template/README.md +2 -2
- data/lib/site_template/{Rakefile → Rakefile.erb} +15 -0
- data/lib/site_template/TEMPLATES/erb/_components/shared/navbar.erb +11 -0
- data/lib/site_template/TEMPLATES/erb/_components/shared/navbar.rb +5 -0
- data/lib/site_template/TEMPLATES/erb/_layouts/default.erb +15 -0
- data/lib/site_template/TEMPLATES/erb/_layouts/page.erb +7 -0
- data/lib/site_template/TEMPLATES/erb/_layouts/post.erb +7 -0
- data/lib/site_template/TEMPLATES/erb/_partials/_footer.erb +3 -0
- data/lib/site_template/TEMPLATES/erb/_partials/_head.erb +10 -0
- data/lib/site_template/{src → TEMPLATES/liquid}/_components/footer.liquid +0 -0
- data/lib/site_template/TEMPLATES/liquid/_components/head.liquid +10 -0
- data/lib/site_template/TEMPLATES/liquid/_components/navbar.liquid +11 -0
- data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/default.liquid +2 -2
- data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/page.liquid +0 -0
- data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/post.liquid +0 -0
- data/lib/site_template/TEMPLATES/serbea/_components/shared/navbar.rb +5 -0
- data/lib/site_template/TEMPLATES/serbea/_components/shared/navbar.serb +11 -0
- data/lib/site_template/TEMPLATES/serbea/_layouts/default.serb +15 -0
- data/lib/site_template/TEMPLATES/serbea/_layouts/page.serb +7 -0
- data/lib/site_template/TEMPLATES/serbea/_layouts/post.serb +7 -0
- data/lib/site_template/TEMPLATES/serbea/_partials/_footer.serb +3 -0
- data/lib/site_template/TEMPLATES/serbea/_partials/_head.serb +10 -0
- data/lib/site_template/frontend/javascript/index.js.erb +7 -3
- data/lib/site_template/frontend/styles/index.css +71 -6
- data/lib/site_template/package.json.erb +24 -9
- data/lib/site_template/ruby-version.erb +1 -0
- data/lib/site_template/server/roda_app.rb +5 -3
- data/lib/site_template/server/routes/hello.rb.sample +1 -1
- data/lib/site_template/src/images/logo.svg +91 -0
- data/lib/site_template/src/index.md.erb +22 -0
- data/lib/site_template/src/posts.md.erb +28 -0
- metadata +70 -22
- data/lib/bridgetown-core/configurations/swup.rb +0 -37
- data/lib/site_template/frontend/styles/index.scss +0 -17
- data/lib/site_template/src/_components/head.liquid +0 -10
- data/lib/site_template/src/_components/navbar.liquid +0 -5
- data/lib/site_template/src/_layouts/home.liquid +0 -7
- data/lib/site_template/src/images/.keep +0 -1
- data/lib/site_template/src/index.md +0 -7
- data/lib/site_template/src/posts.md +0 -14
@@ -1,16 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
say_status :turbo, "Installing Turbo..."
|
4
4
|
|
5
5
|
run("yarn add @hotwired/turbo")
|
6
6
|
|
7
|
-
|
7
|
+
say_status :turbo, 'Adding Turbo to "frontend/javascript/index.js"...', :magenta
|
8
8
|
|
9
9
|
javascript_import do
|
10
10
|
<<~JS
|
11
|
-
import Turbo from "@hotwired/turbo"
|
11
|
+
import * as Turbo from "@hotwired/turbo"
|
12
|
+
|
13
|
+
// Uncomment the line below to add transition animations when Turbo navigates.
|
14
|
+
// We recommend adding <meta name="turbo-cache-control" content="no-preview" />
|
15
|
+
// to your HTML head if you turn on transitions. Use data-turbo-transition="false"
|
16
|
+
// on your <main> element for pages where you don't want any transition animation.
|
17
|
+
//
|
18
|
+
// import "./turbo_transitions.js"
|
12
19
|
JS
|
13
20
|
end
|
14
21
|
|
15
|
-
|
16
|
-
|
22
|
+
copy_file in_templates_dir("turbo_transitions.js"), "frontend/javascript/turbo_transitions.js"
|
23
|
+
|
24
|
+
say_status :turbo, "Turbo successfully added!", :magenta
|
25
|
+
say_status :turbo, "Take a look in your index.js file for optional animation setup.", :blue
|
26
|
+
say_status :turbo, 'For further reading, check out "https://turbo.hotwired.dev/"', :blue
|
@@ -0,0 +1,45 @@
|
|
1
|
+
{
|
2
|
+
"cleanUrls": true,
|
3
|
+
"trailingSlash": false,
|
4
|
+
"redirects": [],
|
5
|
+
"headers": [
|
6
|
+
{
|
7
|
+
"source": "/(.*)",
|
8
|
+
"headers": [
|
9
|
+
{
|
10
|
+
"key": "X-Content-Type-Options",
|
11
|
+
"value": "nosniff"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"key": "X-Frame-Options",
|
15
|
+
"value": "DENY"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"key": "X-XSS-Protection",
|
19
|
+
"value": "1; mode=block"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"key": "Referrer-Policy",
|
23
|
+
"value": "strict-origin"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"key": "Permissions-Policy",
|
27
|
+
"value": "geolocation=(self), microphone=()"
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"source": "/feed.xml",
|
33
|
+
"headers": [
|
34
|
+
{
|
35
|
+
"key": "Content-Type",
|
36
|
+
"value": "application/rss+xml"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"key": "Cache-Control",
|
40
|
+
"value": "public, max-age=3600"
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
]
|
45
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Builders::VercelUrl < SiteBuilder
|
4
|
+
def build
|
5
|
+
hook :site, :pre_render do |site|
|
6
|
+
next unless ENV["VERCEL_URL"] && ENV["VERCEL_ENV"] != "production"
|
7
|
+
|
8
|
+
Bridgetown.logger.info("Subbing Vercel URL")
|
9
|
+
site.config.update(url: "https://#{ENV["VERCEL_URL"]}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -38,7 +38,7 @@ module Bridgetown
|
|
38
38
|
return if text.empty?
|
39
39
|
|
40
40
|
src << bufvar << ".safe_append='"
|
41
|
-
src << text.gsub(%r{['\\]}, '\\\\\&')
|
41
|
+
src << text.gsub(%r{['\\]}, '\\\\\&')
|
42
42
|
src << "'.freeze;"
|
43
43
|
end
|
44
44
|
|
@@ -83,16 +83,14 @@ module Bridgetown
|
|
83
83
|
options.merge!(options[:locals]) if options[:locals]
|
84
84
|
options[:content] = yield if block_given?
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
Tilt::ErubiTemplate.new(
|
91
|
-
site.in_source_dir(site.config[:partials_dir], "#{partial_name}.erb"),
|
86
|
+
partial_path = _partial_path(partial_name, "erb")
|
87
|
+
tmpl = site.tmp_cache["partial-tmpl:#{partial_path}"] ||= Tilt::ErubiTemplate.new(
|
88
|
+
partial_path,
|
92
89
|
outvar: "@_erbout",
|
93
90
|
bufval: "Bridgetown::OutputBuffer.new",
|
94
91
|
engine_class: ERBEngine
|
95
|
-
)
|
92
|
+
)
|
93
|
+
tmpl.render(self, options)
|
96
94
|
end
|
97
95
|
end
|
98
96
|
|
@@ -115,7 +113,7 @@ module Bridgetown
|
|
115
113
|
erb_view = Bridgetown::ERBView.new(convertible)
|
116
114
|
|
117
115
|
erb_renderer = Tilt::ErubiTemplate.new(
|
118
|
-
convertible.
|
116
|
+
convertible.path,
|
119
117
|
line_start(convertible),
|
120
118
|
outvar: "@_erbout",
|
121
119
|
bufval: "Bridgetown::OutputBuffer.new",
|
@@ -9,7 +9,7 @@ module Bridgetown
|
|
9
9
|
def convert(content, convertible)
|
10
10
|
erb_view = Bridgetown::ERBView.new(convertible)
|
11
11
|
erb_view.instance_eval(
|
12
|
-
content, convertible.
|
12
|
+
content, convertible.path.to_s, line_start(convertible)
|
13
13
|
).to_s
|
14
14
|
end
|
15
15
|
end
|
@@ -11,13 +11,10 @@ module Bridgetown
|
|
11
11
|
options.merge!(options[:locals]) if options[:locals]
|
12
12
|
options[:content] = capture(&block) if block
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Tilt::SerbeaTemplate.new(
|
19
|
-
site.in_source_dir(site.config[:partials_dir], "#{partial_name}.serb")
|
20
|
-
).render(self, options)
|
14
|
+
partial_path = _partial_path(partial_name, "serb")
|
15
|
+
tmpl = site.tmp_cache["partial-tmpl:#{partial_path}"] ||=
|
16
|
+
Tilt::SerbeaTemplate.new(partial_path)
|
17
|
+
tmpl.render(self, options)
|
21
18
|
end
|
22
19
|
end
|
23
20
|
|
@@ -39,7 +36,7 @@ module Bridgetown
|
|
39
36
|
|
40
37
|
serb_view = Bridgetown::SerbeaView.new(convertible)
|
41
38
|
|
42
|
-
serb_renderer = Tilt::SerbeaTemplate.new(convertible.
|
39
|
+
serb_renderer = Tilt::SerbeaTemplate.new(convertible.path) { content }
|
43
40
|
|
44
41
|
if convertible.is_a?(Bridgetown::Layout)
|
45
42
|
serb_renderer.render(serb_view) do
|
@@ -110,7 +110,7 @@ module Bridgetown
|
|
110
110
|
# underlying data hashes and performs a set union to ensure a list
|
111
111
|
# of unique keys for the Drop.
|
112
112
|
#
|
113
|
-
#
|
113
|
+
# @return [Array<String>]
|
114
114
|
def keys
|
115
115
|
(content_methods |
|
116
116
|
mutations.keys |
|
@@ -6,7 +6,7 @@ module Bridgetown
|
|
6
6
|
extend Forwardable
|
7
7
|
|
8
8
|
NESTED_OBJECT_FIELD_BLACKLIST = %w(
|
9
|
-
content output excerpt next previous
|
9
|
+
content output excerpt next previous next_resource previous_resource
|
10
10
|
).freeze
|
11
11
|
|
12
12
|
mutable false
|
@@ -44,13 +44,15 @@ module Bridgetown
|
|
44
44
|
cmp
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
48
|
-
@
|
47
|
+
def next_resource
|
48
|
+
@next ||= @obj.next_resource.to_liquid
|
49
49
|
end
|
50
|
+
alias_method :next, :next_resource
|
50
51
|
|
51
|
-
def
|
52
|
-
@
|
52
|
+
def previous_resource
|
53
|
+
@previous ||= @obj.previous_resource.to_liquid
|
53
54
|
end
|
55
|
+
alias_method :previous, :previous_resource
|
54
56
|
|
55
57
|
# Generate a Hash for use in generating JSON.
|
56
58
|
# This is useful if fields need to be cleared before the JSON can generate.
|
@@ -79,6 +81,27 @@ module Bridgetown
|
|
79
81
|
result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
|
80
82
|
end
|
81
83
|
end
|
84
|
+
|
85
|
+
# Generates a list of keys with user content as their values.
|
86
|
+
# This gathers up the Drop methods and keys of the mutations and
|
87
|
+
# underlying data hashes and performs a set union to ensure a list
|
88
|
+
# of unique keys for the Drop.
|
89
|
+
#
|
90
|
+
# @return [Array<String>]
|
91
|
+
def keys
|
92
|
+
keys_to_remove = %w[next_resource previous_resource]
|
93
|
+
(content_methods |
|
94
|
+
mutations.keys |
|
95
|
+
fallback_data.keys).flatten.reject do |key|
|
96
|
+
keys_to_remove.include?(key)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Inspect the drop's keys and values through a JSON representation
|
101
|
+
# of its keys and values.
|
102
|
+
def inspect
|
103
|
+
JSON.pretty_generate hash_for_json
|
104
|
+
end
|
82
105
|
end
|
83
106
|
end
|
84
107
|
end
|
@@ -14,5 +14,26 @@ module Bridgetown
|
|
14
14
|
PostURLError = Class.new(FatalException)
|
15
15
|
InvalidURLError = Class.new(FatalException)
|
16
16
|
InvalidConfigurationError = Class.new(FatalException)
|
17
|
+
|
18
|
+
def self.print_build_error(exc, trace: false)
|
19
|
+
Bridgetown.logger.error "Exception raised:", exc.class.to_s.bold
|
20
|
+
Bridgetown.logger.error exc.message.reset_ansi
|
21
|
+
|
22
|
+
trace_args = ["-t", "--trace"]
|
23
|
+
print_trace_msg = true
|
24
|
+
traces = if trace || ARGV.find { |arg| trace_args.include?(arg) }
|
25
|
+
print_trace_msg = false
|
26
|
+
exc.backtrace
|
27
|
+
else
|
28
|
+
exc.backtrace[0..4]
|
29
|
+
end
|
30
|
+
traces.each_with_index do |backtrace_line, index|
|
31
|
+
Bridgetown.logger.error "#{index + 1}:", backtrace_line.reset_ansi
|
32
|
+
end
|
33
|
+
|
34
|
+
return unless print_trace_msg
|
35
|
+
|
36
|
+
Bridgetown.logger.warn "Backtrace:", "Use the --trace option for complete information."
|
37
|
+
end
|
17
38
|
end
|
18
39
|
end
|
@@ -1,21 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Handles Generated Pages
|
4
|
-
Bridgetown::Hooks.
|
4
|
+
Bridgetown::Hooks.register_one :generated_pages, :post_init, reloadable: false do |page|
|
5
5
|
if page.class != Bridgetown::PrototypePage && page.data["prototype"].is_a?(Hash)
|
6
6
|
Bridgetown::PrototypeGenerator.add_matching_template(page)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
# Handles Resources
|
11
|
-
Bridgetown::Hooks.
|
11
|
+
Bridgetown::Hooks.register_one :resources, :post_read, reloadable: false do |resource|
|
12
12
|
if resource.data["prototype"].is_a?(Hash)
|
13
13
|
Bridgetown::PrototypeGenerator.add_matching_template(resource)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
# Ensure sites clear out templates before rebuild
|
18
|
-
Bridgetown::Hooks.
|
18
|
+
Bridgetown::Hooks.register_one :site, :after_reset, reloadable: false do |_site|
|
19
19
|
Bridgetown::PrototypeGenerator.matching_templates.clear
|
20
20
|
end
|
21
21
|
|
@@ -22,9 +22,10 @@ module Bridgetown
|
|
22
22
|
@context = Context.new({ site: site })
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
Bridgetown::Utils.
|
25
|
+
def asset_path(asset_type)
|
26
|
+
Bridgetown::Utils.parse_frontend_manifest_file(site, asset_type.to_s)
|
27
27
|
end
|
28
|
+
alias_method :webpack_path, :asset_path
|
28
29
|
|
29
30
|
def live_reload_dev_js
|
30
31
|
Bridgetown::Utils.live_reload_js(site)
|
@@ -17,34 +17,59 @@ module Bridgetown
|
|
17
17
|
|
18
18
|
DEFAULT_PRIORITY = 20
|
19
19
|
|
20
|
-
# compatibility layer for octopress-hooks users
|
21
20
|
PRIORITY_MAP = {
|
22
21
|
low: 10,
|
23
22
|
normal: 20,
|
24
23
|
high: 30,
|
25
24
|
}.freeze
|
26
25
|
|
27
|
-
# initial empty hooks
|
28
26
|
@registry = {}
|
29
27
|
|
30
28
|
NotAvailable = Class.new(RuntimeError)
|
31
29
|
Uncallable = Class.new(RuntimeError)
|
32
30
|
|
33
|
-
# Ensure the priority is a Fixnum
|
34
31
|
def self.priority_value(priority)
|
35
32
|
return priority if priority.is_a?(Integer)
|
36
33
|
|
37
34
|
PRIORITY_MAP[priority] || DEFAULT_PRIORITY
|
38
35
|
end
|
39
36
|
|
40
|
-
#
|
37
|
+
# Sort registered hooks according to priority and load order
|
38
|
+
#
|
39
|
+
# @param hooks [Array<HookRegistration>]
|
40
|
+
def self.prioritized_hooks(hooks)
|
41
|
+
grouped_hooks = hooks.group_by(&:priority)
|
42
|
+
grouped_hooks.keys.sort.reverse.map { |priority| grouped_hooks[priority] }.flatten
|
43
|
+
end
|
44
|
+
|
45
|
+
# Register one or more hooks which may be triggered later for a particular event
|
46
|
+
#
|
47
|
+
# @param owners [Symbol, Array<Symbol>] name of the owner (`:site`, `:resource`, etc.)
|
48
|
+
# @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
|
49
|
+
# @param priority [Integer, Symbol] either `:low`, `:normal`, or `:high`, or an integer.
|
50
|
+
# Default is normal (20)
|
51
|
+
# @param reloadable [Boolean] whether the hook should be removed prior to a site reload.
|
52
|
+
# Default is true.
|
53
|
+
# @yield the block will be called when the event is triggered. Typically it receives at
|
54
|
+
# least one argument.
|
55
|
+
# @yieldparam obj the object which triggered the event hook
|
41
56
|
def self.register(owners, event, priority: DEFAULT_PRIORITY, reloadable: true, &block)
|
42
57
|
Array(owners).each do |owner|
|
43
58
|
register_one(owner, event, priority: priority, reloadable: reloadable, &block)
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
47
|
-
#
|
62
|
+
# Register a hook which may be triggered later for a particular event
|
63
|
+
#
|
64
|
+
# @param owner [Symbol] name of the owner (`:site`, `:resource`, etc.)
|
65
|
+
# @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
|
66
|
+
# @param priority [Integer, Symbol] either `:low`, `:normal`, or `:high`, or an integer.
|
67
|
+
# Default is normal (20)
|
68
|
+
# @param reloadable [Boolean] whether the hook should be removed prior to a site reload.
|
69
|
+
# Default is true.
|
70
|
+
# @yield the block will be called when the event is triggered. Typically it receives at
|
71
|
+
# least one argument.
|
72
|
+
# @yieldparam obj the object which triggered the event hook
|
48
73
|
def self.register_one(owner, event, priority: DEFAULT_PRIORITY, reloadable: true, &block)
|
49
74
|
@registry[owner] ||= []
|
50
75
|
|
@@ -68,10 +93,28 @@ module Bridgetown
|
|
68
93
|
block
|
69
94
|
end
|
70
95
|
|
71
|
-
|
96
|
+
# Delete a previously-registered hook
|
97
|
+
#
|
98
|
+
# @param owners [Symbol] name of the owner (`:site`, `:resource`, etc.)
|
99
|
+
# @param block [Proc] the exact block used originally to register the hook
|
100
|
+
def self.remove_hook(owner, block)
|
72
101
|
@registry[owner].delete_if { |item| item.block == block }
|
73
102
|
end
|
74
103
|
|
104
|
+
# Clear all hooks marked as reloadable from the registry
|
105
|
+
def self.clear_reloadable_hooks
|
106
|
+
Bridgetown.logger.debug("Clearing reloadable hooks")
|
107
|
+
|
108
|
+
@registry.each_value do |hooks|
|
109
|
+
hooks.delete_if(&:reloadable)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Trigger all registered hooks for a particular owner and event.
|
114
|
+
# Any arguments after the initial two will be directly passed along to the hooks.
|
115
|
+
#
|
116
|
+
# @param owner [Symbol] name of the owner (`:site`, `:resource`, etc.)
|
117
|
+
# @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
|
75
118
|
def self.trigger(owner, event, *args) # rubocop:disable Metrics/CyclomaticComplexity
|
76
119
|
# proceed only if there are hooks to call
|
77
120
|
hooks = @registry[owner]&.select { |item| item.event == event }
|
@@ -79,25 +122,13 @@ module Bridgetown
|
|
79
122
|
|
80
123
|
prioritized_hooks(hooks).each do |hook|
|
81
124
|
if ENV["BRIDGETOWN_LOG_LEVEL"] == "debug"
|
82
|
-
hook_info = args[0].respond_to?(:
|
125
|
+
hook_info = args[0].respond_to?(:relative_path) ? args[0].relative_path : hook.block
|
83
126
|
Bridgetown.logger.debug("Triggering hook:", "#{owner}:#{event} for #{hook_info}")
|
84
127
|
end
|
85
128
|
hook.block.call(*args)
|
86
129
|
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.prioritized_hooks(hooks)
|
90
|
-
# sort hooks according to priority and load order
|
91
|
-
grouped_hooks = hooks.group_by(&:priority)
|
92
|
-
grouped_hooks.keys.sort.reverse.map { |priority| grouped_hooks[priority] }.flatten
|
93
|
-
end
|
94
130
|
|
95
|
-
|
96
|
-
Bridgetown.logger.debug("Clearing reloadable hooks")
|
97
|
-
|
98
|
-
@registry.each_value do |hooks|
|
99
|
-
hooks.delete_if(&:reloadable)
|
100
|
-
end
|
131
|
+
true
|
101
132
|
end
|
102
133
|
end
|
103
134
|
end
|
@@ -69,8 +69,23 @@ module Bridgetown
|
|
69
69
|
attributes[:_origin_]
|
70
70
|
end
|
71
71
|
|
72
|
+
def origin=(new_origin)
|
73
|
+
attributes[:_id_] = new_origin.id
|
74
|
+
attributes[:_origin_] = new_origin
|
75
|
+
end
|
76
|
+
|
72
77
|
def persisted?
|
73
|
-
id && origin
|
78
|
+
(id && origin&.exists?) == true
|
79
|
+
end
|
80
|
+
|
81
|
+
def save
|
82
|
+
unless origin.respond_to?(:write)
|
83
|
+
raise "`#{origin.class}' doesn't allow writing of model objects"
|
84
|
+
end
|
85
|
+
|
86
|
+
run_callbacks :save do
|
87
|
+
origin.write(self)
|
88
|
+
end
|
74
89
|
end
|
75
90
|
|
76
91
|
# @return [Bridgetown::Resource::Base]
|
@@ -100,11 +115,19 @@ module Bridgetown
|
|
100
115
|
attributes[:_collection_]
|
101
116
|
end
|
102
117
|
|
118
|
+
def collection=(new_collection)
|
119
|
+
attributes[:_collection_] = new_collection
|
120
|
+
end
|
121
|
+
|
103
122
|
# @return [String]
|
104
123
|
def content
|
105
124
|
attributes[:_content_]
|
106
125
|
end
|
107
126
|
|
127
|
+
def content=(new_content)
|
128
|
+
attributes[:_content_] = new_content
|
129
|
+
end
|
130
|
+
|
108
131
|
def attributes
|
109
132
|
@attributes ||= HashWithDotAccess::Hash.new
|
110
133
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# See bottom of file for specific origin requires...
|
4
|
-
|
5
3
|
module Bridgetown
|
6
4
|
module Model
|
7
5
|
# Abstract Superclass
|
8
6
|
class Origin
|
9
7
|
extend ActiveSupport::DescendantsTracker
|
10
8
|
|
9
|
+
EAGER_LOAD_DESCENDANTS = %i(BuilderOrigin RepoOrigin PluginOrigin).freeze
|
10
|
+
|
11
11
|
# @return [String]
|
12
12
|
attr_accessor :id
|
13
13
|
|
@@ -42,9 +42,7 @@ module Bridgetown
|
|
42
42
|
raise "Implement #exists? in a subclass of Bridgetown::Model::Origin"
|
43
43
|
end
|
44
44
|
end
|
45
|
+
|
46
|
+
Origin::EAGER_LOAD_DESCENDANTS.each { const_get _1 }
|
45
47
|
end
|
46
48
|
end
|
47
|
-
|
48
|
-
require "bridgetown-core/model/builder_origin"
|
49
|
-
require "bridgetown-core/model/repo_origin"
|
50
|
-
require "bridgetown-core/model/plugin_origin"
|
@@ -25,6 +25,18 @@ module Bridgetown
|
|
25
25
|
def data_file_extensions
|
26
26
|
%w(.yaml .yml .json .csv .tsv .rb).freeze
|
27
27
|
end
|
28
|
+
|
29
|
+
# Initializes a new repo object using a collection and a relative source path.
|
30
|
+
# You'll need to use this when you want to create and save a model to the source.
|
31
|
+
#
|
32
|
+
# @param collection [Bridgetown::Collection, String, Symbol] either a collection
|
33
|
+
# label or Collection object
|
34
|
+
# @param relative_path [Pathname, String] the source path of the file to save
|
35
|
+
def new_with_collection_path(collection, relative_path)
|
36
|
+
collection = collection.label if collection.is_a?(Bridgetown::Collection)
|
37
|
+
|
38
|
+
new("repo://#{collection}.collection/#{relative_path}")
|
39
|
+
end
|
28
40
|
end
|
29
41
|
|
30
42
|
def read
|
@@ -46,6 +58,23 @@ module Bridgetown
|
|
46
58
|
@data
|
47
59
|
end
|
48
60
|
|
61
|
+
def write(model)
|
62
|
+
if File.exist?(original_path) && !Bridgetown::Utils.has_yaml_header?(original_path)
|
63
|
+
raise Bridgetown::Errors::InvalidYAMLFrontMatterError,
|
64
|
+
"Only existing files containing YAML front matter can be overwritten by the model"
|
65
|
+
end
|
66
|
+
|
67
|
+
contents = "#{front_matter_to_yaml(model)}---\n\n#{model.content}"
|
68
|
+
|
69
|
+
# Create folders if necessary
|
70
|
+
dir = File.dirname(original_path)
|
71
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
72
|
+
|
73
|
+
File.write(original_path, contents)
|
74
|
+
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
49
78
|
def url
|
50
79
|
@url ||= URI.parse(id)
|
51
80
|
end
|
@@ -121,6 +150,25 @@ module Bridgetown
|
|
121
150
|
raise error
|
122
151
|
end
|
123
152
|
end
|
153
|
+
|
154
|
+
def front_matter_to_yaml(model)
|
155
|
+
data = model.data_attributes.to_h
|
156
|
+
data = data.deep_merge(data) do |_, _, v|
|
157
|
+
case v
|
158
|
+
when DateTime
|
159
|
+
v.to_time
|
160
|
+
when Symbol
|
161
|
+
v.to_s
|
162
|
+
else
|
163
|
+
v
|
164
|
+
end
|
165
|
+
end
|
166
|
+
data.each do |k, v|
|
167
|
+
data.delete(k) if v.nil?
|
168
|
+
end
|
169
|
+
|
170
|
+
data.to_yaml
|
171
|
+
end
|
124
172
|
end
|
125
173
|
end
|
126
174
|
end
|
@@ -51,15 +51,11 @@ module Bridgetown
|
|
51
51
|
loader.do_not_eager_load(File.join(server_folder, "roda_app.rb"))
|
52
52
|
|
53
53
|
unless ENV["BRIDGETOWN_ENV"] == "production"
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end.start
|
60
|
-
# interrupt isn't handled well by the listener
|
61
|
-
rescue ThreadError # rubocop:disable Lint/SuppressedException
|
62
|
-
end
|
54
|
+
Listen.to(server_folder) do |_modified, _added, _removed|
|
55
|
+
loader.reload
|
56
|
+
loader.eager_load
|
57
|
+
Bridgetown::Rack::Routes.reload_subclasses
|
58
|
+
end.start
|
63
59
|
end
|
64
60
|
end
|
65
61
|
|
@@ -23,6 +23,7 @@ module Bridgetown
|
|
23
23
|
plugin :json
|
24
24
|
plugin :json_parser
|
25
25
|
plugin :cookies
|
26
|
+
plugin :streaming
|
26
27
|
plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
|
27
28
|
plugin :not_found do
|
28
29
|
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
@@ -39,7 +40,7 @@ module Bridgetown
|
|
39
40
|
"500 Internal Server Error"
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
+
before do
|
43
44
|
if self.class.opts[:bridgetown_site]
|
44
45
|
# The site had previously been initialized via the bridgetown_ssr plugin
|
45
46
|
Bridgetown::Current.site ||= self.class.opts[:bridgetown_site]
|
@@ -47,14 +48,12 @@ module Bridgetown
|
|
47
48
|
Bridgetown::Current.preloaded_configuration ||=
|
48
49
|
self.class.opts[:bridgetown_preloaded_config]
|
49
50
|
|
50
|
-
|
51
|
+
request.public
|
51
52
|
|
52
|
-
|
53
|
+
request.root do
|
53
54
|
output_folder = Bridgetown::Current.preloaded_configuration.destination
|
54
55
|
File.read(File.join(output_folder, "index.html"))
|
55
56
|
end
|
56
|
-
|
57
|
-
super
|
58
57
|
end
|
59
58
|
|
60
59
|
# Helper shorthand for Bridgetown::Current.site
|