bridgetown-core 1.0.0.alpha10 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/bin/bridgetown +6 -1
- data/bridgetown-core.gemspec +3 -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/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/renderable.rb +27 -16
- data/lib/bridgetown-core/concerns/site/ssr.rb +2 -17
- data/lib/bridgetown-core/concerns/transformable.rb +62 -0
- 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 +6 -8
- 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/generated_page.rb +81 -17
- 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/resource/transformer.rb +21 -85
- 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 +6 -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 +2 -1
- 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 +57 -23
- data/lib/bridgetown-core/configurations/swup.rb +0 -37
- data/lib/bridgetown-core/renderer.rb +0 -169
- 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
@@ -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
|
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
module Bridgetown
|
4
4
|
module Rack
|
5
|
+
@interrupted = false
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :interrupted
|
9
|
+
end
|
10
|
+
|
5
11
|
class Routes
|
6
12
|
class << self
|
7
13
|
attr_accessor :tracked_subclasses, :router_block
|
@@ -37,7 +43,7 @@ module Bridgetown
|
|
37
43
|
def start!(roda_app)
|
38
44
|
if Bridgetown.env.development? &&
|
39
45
|
!Bridgetown::Current.preloaded_configuration.skip_live_reload
|
40
|
-
setup_live_reload roda_app
|
46
|
+
setup_live_reload roda_app
|
41
47
|
end
|
42
48
|
|
43
49
|
Bridgetown::Rack::Routes.tracked_subclasses&.each_value do |klass|
|
@@ -51,15 +57,31 @@ module Bridgetown
|
|
51
57
|
nil
|
52
58
|
end
|
53
59
|
|
54
|
-
def setup_live_reload(
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
def setup_live_reload(app) # rubocop:disable Metrics/AbcSize
|
61
|
+
sleep_interval = 0.2
|
62
|
+
file_to_check = File.join(app.class.opts[:bridgetown_preloaded_config].destination,
|
63
|
+
"index.html")
|
64
|
+
|
65
|
+
app.request.get "_bridgetown/live_reload" do
|
66
|
+
app.response["Content-Type"] = "text/event-stream"
|
67
|
+
|
68
|
+
@_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0
|
69
|
+
app.stream async: true do |out|
|
70
|
+
# 5 second intervals so Puma's threads aren't all exausted
|
71
|
+
(5 / sleep_interval).to_i.times do
|
72
|
+
break if Bridgetown::Rack.interrupted
|
73
|
+
|
74
|
+
new_mod = File.exist?(file_to_check) ? File.stat(file_to_check).mtime.to_i : 0
|
75
|
+
if @_mod < new_mod
|
76
|
+
out << "data: reloaded!\n\n"
|
77
|
+
break
|
78
|
+
else
|
79
|
+
out << "data: #{new_mod}\n\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
sleep sleep_interval
|
83
|
+
end
|
84
|
+
end
|
63
85
|
end
|
64
86
|
end
|
65
87
|
end
|
@@ -86,3 +108,15 @@ module Bridgetown
|
|
86
108
|
end
|
87
109
|
end
|
88
110
|
end
|
111
|
+
|
112
|
+
if Bridgetown.env.development? &&
|
113
|
+
!Bridgetown::Current.preloaded_configuration.skip_live_reload
|
114
|
+
Puma::Launcher.class_eval do
|
115
|
+
alias_method :_old_stop, :stop
|
116
|
+
def stop
|
117
|
+
Bridgetown::Rack.interrupted = true
|
118
|
+
|
119
|
+
_old_stop
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "roda/plugins/public"
|
4
4
|
|
5
|
+
# NOTE: once this upstreamed PR is merged in we can remove this file.
|
6
|
+
# https://github.com/jeremyevans/roda/pull/215
|
5
7
|
Roda::RodaPlugins::Public::RequestMethods.module_eval do
|
6
8
|
SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact) # rubocop:disable Lint/ConstantDefinitionInBlock
|
7
9
|
def public_path_segments(path) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
@@ -30,7 +30,7 @@ module Bridgetown
|
|
30
30
|
def initialize(model:)
|
31
31
|
@model = model
|
32
32
|
@site = model.site
|
33
|
-
@data = front_matter_defaults
|
33
|
+
@data = collection.data? ? HashWithDotAccess::Hash.new : front_matter_defaults
|
34
34
|
|
35
35
|
trigger_hooks :post_init
|
36
36
|
end
|
@@ -284,12 +284,14 @@ module Bridgetown
|
|
284
284
|
collection.resources[pos + 1] if pos && pos < collection.resources.length - 1
|
285
285
|
end
|
286
286
|
alias_method :next_doc, :next_resource
|
287
|
+
alias_method :next, :next_resource
|
287
288
|
|
288
289
|
def previous_resource
|
289
290
|
pos = collection.resources.index { |item| item.equal?(self) }
|
290
291
|
collection.resources[pos - 1] if pos&.positive?
|
291
292
|
end
|
292
293
|
alias_method :previous_doc, :previous_resource
|
294
|
+
alias_method :previous, :previous_resource
|
293
295
|
|
294
296
|
private
|
295
297
|
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Bridgetown
|
4
4
|
module Resource
|
5
5
|
class Transformer
|
6
|
+
include Transformable
|
7
|
+
|
6
8
|
# @return [Array<Hash>]
|
7
9
|
attr_reader :conversions
|
8
10
|
|
@@ -30,10 +32,18 @@ module Bridgetown
|
|
30
32
|
permalink_ext || output_ext
|
31
33
|
end
|
32
34
|
|
33
|
-
def process!
|
35
|
+
def process! # rubocop:disable Metrics/AbcSize
|
34
36
|
Bridgetown.logger.debug "Transforming:", resource.relative_path
|
35
37
|
resource.around_hook :render do
|
36
|
-
|
38
|
+
resource.content = transform_content(resource) do |converter, index, output|
|
39
|
+
conversions[index] = {
|
40
|
+
type: :content,
|
41
|
+
converter: converter,
|
42
|
+
output: Bridgetown.env.production? ? nil : output,
|
43
|
+
output_ext: conversions[index]&.dig(:output_ext) ||
|
44
|
+
converter.output_ext(resource.extname),
|
45
|
+
}
|
46
|
+
end
|
37
47
|
resource.place_in_layout? ? place_into_layouts : resource.output = resource.content.dup
|
38
48
|
end
|
39
49
|
end
|
@@ -85,95 +95,21 @@ module Bridgetown
|
|
85
95
|
.fetch(:output_ext)
|
86
96
|
end
|
87
97
|
|
88
|
-
# @return [Array<Bridgetown::Layout>]
|
89
|
-
def validated_layouts
|
90
|
-
layout = site.layouts[resource.data.layout]
|
91
|
-
warn_on_missing_layout layout, resource.data.layout
|
92
|
-
|
93
|
-
layout_list = Set.new([layout])
|
94
|
-
while layout
|
95
|
-
layout_name = layout.data.layout
|
96
|
-
layout = site.layouts[layout_name]
|
97
|
-
warn_on_missing_layout layout, layout_name
|
98
|
-
|
99
|
-
layout_list << layout
|
100
|
-
end
|
101
|
-
|
102
|
-
layout_list.to_a.compact
|
103
|
-
end
|
104
|
-
|
105
|
-
def warn_on_missing_layout(layout, layout_name)
|
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
|
-
)
|
112
|
-
end
|
113
|
-
|
114
|
-
### Transformation Actions
|
115
|
-
|
116
|
-
def run_conversions # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
117
|
-
input = resource.content.to_s
|
118
|
-
|
119
|
-
# @param content [String]
|
120
|
-
# @param converter [Bridgetown::Converter]
|
121
|
-
resource.content = converters.each_with_index.inject(input) do |content, (converter, index)|
|
122
|
-
output = if converter.method(:convert).arity == 1
|
123
|
-
converter.convert content
|
124
|
-
else
|
125
|
-
converter.convert content, resource
|
126
|
-
end
|
127
|
-
conversions[index] = {
|
128
|
-
type: :content,
|
129
|
-
converter: converter,
|
130
|
-
output: Bridgetown.env.production? ? nil : output,
|
131
|
-
output_ext: conversions[index]&.dig(:output_ext) ||
|
132
|
-
converter.output_ext(resource.extname),
|
133
|
-
}
|
134
|
-
output.html_safe
|
135
|
-
rescue StandardError => e
|
136
|
-
Bridgetown.logger.error "Conversion error:",
|
137
|
-
"#{converter.class} encountered an error while "\
|
138
|
-
"converting `#{resource.relative_path}'"
|
139
|
-
raise e
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
98
|
def place_into_layouts
|
144
99
|
Bridgetown.logger.debug "Placing in Layouts:", resource.relative_path
|
145
100
|
output = resource.content.dup
|
146
|
-
|
147
|
-
output =
|
101
|
+
site.validated_layouts_for(resource, resource.data.layout).each do |layout|
|
102
|
+
output = transform_with_layout(layout, output, resource) do |converter, layout_output|
|
103
|
+
conversions << {
|
104
|
+
type: :layout,
|
105
|
+
layout: layout,
|
106
|
+
converter: converter,
|
107
|
+
output: Bridgetown.env.production? ? nil : layout_output,
|
108
|
+
}
|
109
|
+
end
|
148
110
|
end
|
149
111
|
resource.output = output
|
150
112
|
end
|
151
|
-
|
152
|
-
def run_layout_conversions(layout, output)
|
153
|
-
layout_converters = site.matched_converters_for_convertible(layout)
|
154
|
-
layout_input = layout.content.dup
|
155
|
-
|
156
|
-
layout_converters.inject(layout_input) do |content, converter|
|
157
|
-
next(content) unless [2, -2].include?(converter.method(:convert).arity) # rubocop:disable Performance/CollectionLiteralInLoop
|
158
|
-
|
159
|
-
layout.current_document = resource
|
160
|
-
layout.current_document_output = output
|
161
|
-
layout_output = converter.convert content, layout
|
162
|
-
|
163
|
-
conversions << {
|
164
|
-
type: :layout,
|
165
|
-
layout: layout,
|
166
|
-
converter: converter,
|
167
|
-
output: Bridgetown.env.production? ? nil : layout_output,
|
168
|
-
}
|
169
|
-
layout_output
|
170
|
-
rescue StandardError => e
|
171
|
-
Bridgetown.logger.error "Conversion error:",
|
172
|
-
"#{converter.class} encountered an error while "\
|
173
|
-
"converting `#{resource.relative_path}'"
|
174
|
-
raise e
|
175
|
-
end
|
176
|
-
end
|
177
113
|
end
|
178
114
|
end
|
179
115
|
end
|
@@ -73,6 +73,10 @@ module Bridgetown
|
|
73
73
|
helpers.respond_to?(method_name.to_sym, include_private) || super
|
74
74
|
end
|
75
75
|
|
76
|
+
def inspect
|
77
|
+
"#<#{self.class} layout=#{layout&.label} resource=#{resource.relative_path}>"
|
78
|
+
end
|
79
|
+
|
76
80
|
private
|
77
81
|
|
78
82
|
def _render_statement(component, options)
|
@@ -103,5 +107,12 @@ module Bridgetown
|
|
103
107
|
strict_variables: site.config["liquid"]["strict_variables"],
|
104
108
|
}
|
105
109
|
end
|
110
|
+
|
111
|
+
def _partial_path(partial_name, ext)
|
112
|
+
partial_name = partial_name.split("/").tap { _1.last.prepend("_") }.join("/")
|
113
|
+
|
114
|
+
# TODO: see if there's a workaround for this to speed up performance
|
115
|
+
site.in_source_dir(site.config[:partials_dir], "#{partial_name}.#{ext}")
|
116
|
+
end
|
106
117
|
end
|
107
118
|
end
|
data/lib/bridgetown-core/site.rb
CHANGED
@@ -53,6 +53,7 @@ module Bridgetown
|
|
53
53
|
@reader = Reader.new(self)
|
54
54
|
@liquid_renderer = LiquidRenderer.new(self)
|
55
55
|
|
56
|
+
Bridgetown::Cache.base_cache["site_tmp"] = {}.with_dot_access
|
56
57
|
ensure_not_in_dest
|
57
58
|
|
58
59
|
Bridgetown::Current.site = self
|
@@ -74,6 +75,10 @@ module Bridgetown
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
78
|
+
def tmp_cache
|
79
|
+
Bridgetown::Cache.base_cache["site_tmp"]
|
80
|
+
end
|
81
|
+
|
77
82
|
def inspect
|
78
83
|
"#<Bridgetown::Site #{metadata.inspect.delete_prefix("{").delete_suffix("}")}>"
|
79
84
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module Bridgetown
|
4
4
|
module Tags
|
5
|
-
# A helper class to help find the path to
|
5
|
+
# A helper class to help find the path to assets inside of a webpack or esbuild
|
6
6
|
# manifest file.
|
7
|
-
class
|
7
|
+
class AssetPath < Liquid::Tag
|
8
8
|
# @param tag_name [String] Name of the tag
|
9
9
|
# @param asset_type [String] The type of asset to parse (js, css)
|
10
10
|
# @param options [Hash] An options hash
|
@@ -17,23 +17,21 @@ module Bridgetown
|
|
17
17
|
@asset_type = asset_type.strip
|
18
18
|
end
|
19
19
|
|
20
|
-
# Render an asset path based on the
|
20
|
+
# Render an asset path based on the frontend manifest file
|
21
21
|
# @param context [Liquid::Context] Context passed to the tag
|
22
22
|
#
|
23
23
|
# @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
|
24
|
-
#
|
24
|
+
# file isn't found
|
25
25
|
# @return [String] Returns a blank string if the asset isn't found
|
26
26
|
# @return [String] Returns the path to the asset if no issues parsing
|
27
|
-
#
|
28
|
-
# @raise [WebpackAssetError] if unable to find css or js in the manifest
|
29
|
-
# file
|
30
27
|
def render(context)
|
31
28
|
@context = context
|
32
29
|
site = context.registers[:site]
|
33
|
-
Bridgetown::Utils.
|
30
|
+
Bridgetown::Utils.parse_frontend_manifest_file(site, @asset_type) || ""
|
34
31
|
end
|
35
32
|
end
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
39
|
-
Liquid::Template.register_tag("
|
36
|
+
Liquid::Template.register_tag("asset_path", Bridgetown::Tags::AssetPath)
|
37
|
+
Liquid::Template.register_tag("webpack_path", Bridgetown::Tags::AssetPath)
|
@@ -15,7 +15,8 @@ namespace :frontend do
|
|
15
15
|
run_process "Frontend", :yellow, "bundle exec bridgetown frontend:dev"
|
16
16
|
end
|
17
17
|
if sidecar
|
18
|
-
|
18
|
+
# give FE bundler time to boot before returning control to the start command
|
19
|
+
sleep Bridgetown::Utils.frontend_bundler_type == :esbuild ? 3 : 4
|
19
20
|
else
|
20
21
|
trap("INT") do
|
21
22
|
Bridgetown::Utils::Aux.kill_processes
|
@@ -33,6 +33,12 @@ module Bridgetown
|
|
33
33
|
return
|
34
34
|
end
|
35
35
|
|
36
|
+
if defined?(ActiveSupport::RubyFeatures) && ActiveSupport::RubyFeatures::CLASS_SUBCLASSES
|
37
|
+
ActiveSupport::DescendantsTracker.clear([value.superclass])
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO: this could probably be refactored to work like the above
|
36
42
|
ActiveSupport::DescendantsTracker.class_variable_get(
|
37
43
|
:@@direct_descendants
|
38
44
|
)[value.superclass]&.reject! { _1 == value }
|