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
@@ -24,6 +24,14 @@ module Bridgetown
|
|
24
24
|
aliases: "-c",
|
25
25
|
banner: "CONFIGURATION(S)",
|
26
26
|
desc: "Comma separated list of bundled configurations to perform"
|
27
|
+
class_option :templates,
|
28
|
+
aliases: "-t",
|
29
|
+
banner: "liquid|erb|serbea",
|
30
|
+
desc: "Preferred template engine (defaults to Liquid)"
|
31
|
+
class_option :"frontend-bundling",
|
32
|
+
aliases: "-e",
|
33
|
+
banner: "esbuild|webpack",
|
34
|
+
desc: "Choose your frontend bundling stack (defaults to esbuild)"
|
27
35
|
class_option :force,
|
28
36
|
type: :boolean,
|
29
37
|
desc: "Force creation even if PATH already exists"
|
@@ -33,9 +41,9 @@ module Bridgetown
|
|
33
41
|
class_option :"skip-yarn",
|
34
42
|
type: :boolean,
|
35
43
|
desc: "Skip 'yarn install'"
|
36
|
-
class_option :"use-
|
44
|
+
class_option :"use-sass",
|
37
45
|
type: :boolean,
|
38
|
-
desc: "Create
|
46
|
+
desc: "(Webpack only) Create a Sass configuration instead of using PostCSS"
|
39
47
|
|
40
48
|
DOCSURL = "https://bridgetownrb.com/docs"
|
41
49
|
|
@@ -54,6 +62,11 @@ module Bridgetown
|
|
54
62
|
def new_site
|
55
63
|
raise ArgumentError, "You must specify a path." if args.empty?
|
56
64
|
|
65
|
+
if frontend_bundling_option != "webpack" && options["use-sass"]
|
66
|
+
raise ArgumentError,
|
67
|
+
"To install Sass, you must choose Webpack (-e webpack) as your frontend bundler"
|
68
|
+
end
|
69
|
+
|
57
70
|
new_site_path = File.expand_path(args.join(" "), Dir.pwd)
|
58
71
|
@site_name = new_site_path.split(File::SEPARATOR).last
|
59
72
|
|
@@ -70,6 +83,8 @@ module Bridgetown
|
|
70
83
|
say_status :create, new_site_path
|
71
84
|
create_site new_site_path
|
72
85
|
after_install new_site_path, args.join(" "), options
|
86
|
+
rescue ArgumentError => e
|
87
|
+
say_status :alert, e.message, :red
|
73
88
|
end
|
74
89
|
|
75
90
|
protected
|
@@ -78,24 +93,79 @@ module Bridgetown
|
|
78
93
|
!options["force"] && Dir.exist?(path)
|
79
94
|
end
|
80
95
|
|
96
|
+
def frontend_bundling_option
|
97
|
+
options["frontend-bundling"] == "webpack" ? "webpack" : "esbuild"
|
98
|
+
end
|
99
|
+
|
100
|
+
def postcss_option
|
101
|
+
!(frontend_bundling_option == "webpack" && options["use-sass"])
|
102
|
+
end
|
103
|
+
|
81
104
|
def create_site(new_site_path)
|
82
|
-
directory ".", ".", exclude_pattern: %r!\.erb|DS_Store$|\.(s[ac]|c)ss$!
|
105
|
+
directory ".", ".", exclude_pattern: %r!\.erb|TEMPLATES|DS_Store$|\.(s[ac]|c)ss$!
|
83
106
|
FileUtils.chmod_R "u+w", new_site_path
|
84
107
|
|
85
108
|
template(
|
86
109
|
"src/_posts/0000-00-00-welcome-to-bridgetown.md.erb",
|
87
110
|
"src/_posts/#{Time.now.strftime("%Y-%m-%d")}-welcome-to-bridgetown.md"
|
88
111
|
)
|
112
|
+
template("ruby-version.erb", ".ruby-version")
|
89
113
|
template("Gemfile.erb", "Gemfile")
|
114
|
+
template("Rakefile.erb", "Rakefile")
|
90
115
|
template("package.json.erb", "package.json")
|
91
116
|
template("frontend/javascript/index.js.erb", "frontend/javascript/index.js")
|
117
|
+
template("src/index.md.erb", "src/index.md")
|
118
|
+
template("src/posts.md.erb", "src/posts.md")
|
119
|
+
|
120
|
+
case options["templates"]
|
121
|
+
when "erb"
|
122
|
+
setup_erb_templates
|
123
|
+
when "serbea"
|
124
|
+
setup_serbea_templates
|
125
|
+
else
|
126
|
+
setup_liquid_templates
|
127
|
+
end
|
128
|
+
|
129
|
+
if frontend_bundling_option == "esbuild"
|
130
|
+
configure_postcss
|
131
|
+
invoke(Esbuild, ["setup"], {})
|
132
|
+
else
|
133
|
+
postcss_option ? configure_postcss : configure_sass
|
134
|
+
invoke(Webpack, ["setup"], {})
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def setup_erb_templates
|
139
|
+
directory "TEMPLATES/erb/_layouts", "src/_layouts"
|
140
|
+
directory "TEMPLATES/erb/_components", "src/_components"
|
141
|
+
directory "TEMPLATES/erb/_partials", "src/_partials"
|
142
|
+
gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
|
143
|
+
permalink: pretty
|
144
|
+
template_engine: erb
|
145
|
+
YML
|
146
|
+
end
|
147
|
+
|
148
|
+
def setup_serbea_templates
|
149
|
+
directory "TEMPLATES/serbea/_layouts", "src/_layouts"
|
150
|
+
directory "TEMPLATES/serbea/_components", "src/_components"
|
151
|
+
directory "TEMPLATES/serbea/_partials", "src/_partials"
|
152
|
+
gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
|
153
|
+
permalink: pretty
|
154
|
+
template_engine: serbea
|
155
|
+
YML
|
156
|
+
end
|
92
157
|
|
93
|
-
|
94
|
-
|
158
|
+
def setup_liquid_templates
|
159
|
+
directory "TEMPLATES/liquid/_layouts", "src/_layouts"
|
160
|
+
directory "TEMPLATES/liquid/_components", "src/_components"
|
161
|
+
gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
|
162
|
+
permalink: pretty
|
163
|
+
template_engine: liquid
|
164
|
+
YML
|
95
165
|
end
|
96
166
|
|
97
167
|
def configure_sass
|
98
|
-
copy_file("frontend/styles/index.scss")
|
168
|
+
copy_file("frontend/styles/index.css", "frontend/styles/index.scss")
|
99
169
|
end
|
100
170
|
|
101
171
|
def configure_postcss
|
@@ -159,9 +229,9 @@ module Bridgetown
|
|
159
229
|
end
|
160
230
|
@skipped_bundle = false
|
161
231
|
rescue LoadError
|
162
|
-
say_status :
|
232
|
+
say_status :alert, "Could not load Bundler. Bundle install skipped.", :red
|
163
233
|
rescue SystemExit
|
164
|
-
say_status :
|
234
|
+
say_status :alert, "Problem occured while running bundle install.", :red
|
165
235
|
end
|
166
236
|
|
167
237
|
def git_init(path)
|
@@ -171,7 +241,7 @@ module Bridgetown
|
|
171
241
|
end
|
172
242
|
end
|
173
243
|
rescue SystemExit
|
174
|
-
say_status :
|
244
|
+
say_status :alert, "Could not load git. git init skipped.", :red
|
175
245
|
end
|
176
246
|
|
177
247
|
def yarn_install(path)
|
@@ -182,7 +252,7 @@ module Bridgetown
|
|
182
252
|
end
|
183
253
|
@skipped_yarn = false
|
184
254
|
rescue SystemExit
|
185
|
-
say_status :
|
255
|
+
say_status :alert, "Could not load yarn. yarn install skipped.", :red
|
186
256
|
end
|
187
257
|
end
|
188
258
|
end
|
@@ -187,7 +187,7 @@ module Bridgetown
|
|
187
187
|
say_status "Done!", "Have fun writing your new #{name} plugin :)"
|
188
188
|
say_status "Remember:", "Don't forget to rename the SamplePlugin" \
|
189
189
|
" code identifiers and paths to your own" \
|
190
|
-
" indentifer, as well as update your README
|
190
|
+
" indentifer, as well as update your README" \
|
191
191
|
" and CHANGELOG files as necessary."
|
192
192
|
end
|
193
193
|
|
@@ -6,7 +6,7 @@ template default_postcss_config, "postcss.config.js"
|
|
6
6
|
template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
|
7
7
|
|
8
8
|
unless Bridgetown.environment.test?
|
9
|
-
packages = %w(postcss
|
9
|
+
packages = %w(postcss postcss-loader postcss-flexbugs-fixes postcss-preset-env)
|
10
10
|
run "yarn add -D #{packages.join(" ")}"
|
11
11
|
run "yarn remove sass sass-loader"
|
12
12
|
end
|
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
# rubocop:disable Layout/LineLength
|
4
4
|
|
5
|
-
required_packages = %w(esbuild esbuild-loader webpack@5.39.1 webpack-cli@4.7.2 webpack-manifest-plugin@3.1.1)
|
6
|
-
redundant_packages = %w(@babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime @babel/preset-env babel-loader)
|
7
|
-
|
8
5
|
template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
|
9
6
|
say "🎉 Webpack configuration updated successfully!"
|
10
7
|
|
11
8
|
return if Bridgetown.environment.test?
|
12
9
|
|
10
|
+
required_packages = %w(esbuild esbuild-loader webpack@5.39.1 webpack-cli@4.7.2 webpack-manifest-plugin@3.1.1)
|
11
|
+
redundant_packages = %w(@babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime @babel/preset-env babel-loader)
|
12
|
+
|
13
13
|
say "Installing required packages"
|
14
14
|
run "yarn add -D #{required_packages.join(" ")}"
|
15
15
|
|
@@ -119,7 +119,7 @@ module.exports = {
|
|
119
119
|
filename: "../css/[name].[contenthash].css",
|
120
120
|
}),
|
121
121
|
new WebpackManifestPlugin({
|
122
|
-
fileName: path.resolve(rootDir, ".bridgetown-
|
122
|
+
fileName: path.resolve(rootDir, ".bridgetown-cache", "frontend-bundling", "manifest.json"),
|
123
123
|
}),
|
124
124
|
],
|
125
125
|
module: {
|
@@ -13,7 +13,7 @@ module Bridgetown
|
|
13
13
|
def self.banner
|
14
14
|
"bridgetown webpack ACTION"
|
15
15
|
end
|
16
|
-
summary "Perform actions on the
|
16
|
+
summary "Perform actions on the Bridgetown Webpack configuration"
|
17
17
|
|
18
18
|
def self.exit_on_failure?
|
19
19
|
true
|
@@ -72,8 +72,8 @@ module Bridgetown
|
|
72
72
|
|
73
73
|
def supported_actions
|
74
74
|
{
|
75
|
-
setup: "Sets up a
|
76
|
-
update: "Updates the Bridgetown
|
75
|
+
setup: "Sets up a Webpack integration with Bridgetown in your project",
|
76
|
+
update: "Updates the Bridgetown Webpack defaults to the latest available version",
|
77
77
|
"enable-postcss": "Configures PostCSS in your project",
|
78
78
|
}.with_indifferent_access
|
79
79
|
end
|
@@ -91,6 +91,12 @@ module Bridgetown
|
|
91
91
|
def supported_template_extensions
|
92
92
|
%w(erb serb slim haml)
|
93
93
|
end
|
94
|
+
|
95
|
+
def path_for_errors
|
96
|
+
component_template_path
|
97
|
+
rescue RuntimeError
|
98
|
+
source_location
|
99
|
+
end
|
94
100
|
end
|
95
101
|
|
96
102
|
# If a content block was originally passed into via `render`, capture its output.
|
@@ -133,7 +139,7 @@ module Bridgetown
|
|
133
139
|
rescue StandardError => e
|
134
140
|
Bridgetown.logger.error "Component error:",
|
135
141
|
"#{self.class} encountered an error while "\
|
136
|
-
"rendering `#{self.class.
|
142
|
+
"rendering `#{self.class.path_for_errors}'"
|
137
143
|
raise e
|
138
144
|
end
|
139
145
|
|
@@ -165,7 +171,7 @@ module Bridgetown
|
|
165
171
|
end
|
166
172
|
|
167
173
|
def method_missing(method, *args, **kwargs, &block)
|
168
|
-
if helpers.respond_to?(method.to_sym)
|
174
|
+
if view_context && helpers.respond_to?(method.to_sym)
|
169
175
|
helpers.send method.to_sym, *args, **kwargs, &block
|
170
176
|
else
|
171
177
|
super
|
@@ -173,7 +179,7 @@ module Bridgetown
|
|
173
179
|
end
|
174
180
|
|
175
181
|
def respond_to_missing?(method, include_private = false)
|
176
|
-
helpers.respond_to?(method.to_sym, include_private) || super
|
182
|
+
(view_context && helpers.respond_to?(method.to_sym, include_private)) || super
|
177
183
|
end
|
178
184
|
end
|
179
185
|
end
|
@@ -91,6 +91,8 @@ class Bridgetown::Site
|
|
91
91
|
# {Bridgetown.sanitized_path} method.
|
92
92
|
# @return [Array<String>] Return an array of updated paths if multiple paths given.
|
93
93
|
def in_source_dir(*paths)
|
94
|
+
# TODO: this operation is expensive across thousands of iterations. Look for ways
|
95
|
+
# to workaround use of this wherever possible...
|
94
96
|
paths.reduce(source) do |base, path|
|
95
97
|
Bridgetown.sanitized_path(base, path.to_s)
|
96
98
|
end
|
@@ -146,6 +148,10 @@ class Bridgetown::Site
|
|
146
148
|
@collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
|
147
149
|
end
|
148
150
|
|
151
|
+
def frontend_bundling_path
|
152
|
+
in_root_dir(".bridgetown-cache", "frontend-bundling")
|
153
|
+
end
|
154
|
+
|
149
155
|
private
|
150
156
|
|
151
157
|
# Disable Marshaling cache to disk in Safe Mode
|
@@ -67,7 +67,7 @@ class Bridgetown::Site
|
|
67
67
|
|
68
68
|
# @return [Array<Bridgetown::Resource::TaxonomyType>]
|
69
69
|
def taxonomy_types
|
70
|
-
@taxonomy_types ||= config.taxonomies.
|
70
|
+
@taxonomy_types ||= config.taxonomies.to_h do |label, key_or_metadata|
|
71
71
|
key = key_or_metadata
|
72
72
|
tax_metadata = if key_or_metadata.is_a? Hash
|
73
73
|
key = key_or_metadata["key"]
|
@@ -79,7 +79,7 @@ class Bridgetown::Site
|
|
79
79
|
[label, Bridgetown::Resource::TaxonomyType.new(
|
80
80
|
site: self, label: label, key: key, metadata: tax_metadata
|
81
81
|
),]
|
82
|
-
end.
|
82
|
+
end.with_dot_access
|
83
83
|
end
|
84
84
|
|
85
85
|
# Get all loaded resources.
|
@@ -110,11 +110,11 @@ class Bridgetown::Site
|
|
110
110
|
generated_pages << generated_page
|
111
111
|
end
|
112
112
|
|
113
|
-
# Loads and memoizes the parsed
|
113
|
+
# Loads and memoizes the parsed frontend bundler manifest file (if available)
|
114
114
|
# @return [Hash]
|
115
115
|
def frontend_manifest
|
116
116
|
@frontend_manifest ||= begin
|
117
|
-
manifest_file =
|
117
|
+
manifest_file = File.join(frontend_bundling_path, "manifest.json")
|
118
118
|
|
119
119
|
JSON.parse(File.read(manifest_file)) if File.exist?(manifest_file)
|
120
120
|
end
|
@@ -56,5 +56,13 @@ class Bridgetown::Site
|
|
56
56
|
c.new(config)
|
57
57
|
end
|
58
58
|
end
|
59
|
+
|
60
|
+
# Shorthand for registering a site hook via {Bridgetown::Hooks}
|
61
|
+
# @param event [Symbol] name of the event (`:pre_read`, `:post_render`, etc.)
|
62
|
+
# @yield the block will be called when the event is triggered
|
63
|
+
# @yieldparam site the site which triggered the event hook
|
64
|
+
def on(event, reloadable: false, &block)
|
65
|
+
Bridgetown::Hooks.register_one :site, event, reloadable: reloadable, &block
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
@@ -23,9 +23,9 @@ class Bridgetown::Site
|
|
23
23
|
|
24
24
|
# Reset all in-memory data and content.
|
25
25
|
#
|
26
|
-
|
26
|
+
# @param soft [Boolean] if true, persist some state and do a light refresh of layouts and data
|
27
27
|
# @return [void]
|
28
|
-
def reset(soft: false)
|
28
|
+
def reset(soft: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
29
29
|
self.time = Time.now
|
30
30
|
if config["time"]
|
31
31
|
self.time = Bridgetown::Utils.parse_date(
|
@@ -41,12 +41,31 @@ class Bridgetown::Site
|
|
41
41
|
@documents = nil
|
42
42
|
@docs_to_write = nil
|
43
43
|
@liquid_renderer.reset
|
44
|
-
|
44
|
+
tmp_cache.clear
|
45
|
+
|
46
|
+
if soft
|
47
|
+
refresh_layouts_and_data
|
48
|
+
else
|
49
|
+
frontmatter_defaults.reset
|
50
|
+
Bridgetown::Cache.clear_if_config_changed config
|
51
|
+
end
|
45
52
|
|
46
|
-
Bridgetown::Cache.clear_if_config_changed config unless soft
|
47
53
|
Bridgetown::Hooks.trigger :site, (soft ? :after_soft_reset : :after_reset), self
|
48
54
|
end
|
49
55
|
|
56
|
+
# Read layouts and merge any new data collection contents into the site data
|
57
|
+
def refresh_layouts_and_data
|
58
|
+
reader.read_layouts
|
59
|
+
|
60
|
+
collections.data.tap do |coll|
|
61
|
+
coll.resources.clear
|
62
|
+
coll.read
|
63
|
+
coll.merge_data_resources.each do |k, v|
|
64
|
+
data[k] = v # refresh site data
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
50
69
|
# Read data from disk and load it into internal memory.
|
51
70
|
# @return [void]
|
52
71
|
def read
|
@@ -32,7 +32,7 @@ class Bridgetown::Site
|
|
32
32
|
@ssr_enabled = true
|
33
33
|
end
|
34
34
|
|
35
|
-
def ssr_setup
|
35
|
+
def ssr_setup
|
36
36
|
config.serving = true
|
37
37
|
Bridgetown::Hooks.trigger :site, :pre_read, self
|
38
38
|
defaults_reader.tap do |d|
|
@@ -46,27 +46,12 @@ class Bridgetown::Site
|
|
46
46
|
end
|
47
47
|
Bridgetown::Hooks.trigger :site, :post_read, self
|
48
48
|
|
49
|
-
|
49
|
+
yield self if block_given? # provide additional setup hook
|
50
50
|
return if Bridgetown.env.production?
|
51
51
|
|
52
|
-
@ssr_reload_hook = hook if hook.is_a?(Proc) && hook.lambda?
|
53
52
|
Bridgetown::Watcher.watch(self, config)
|
54
53
|
end
|
55
54
|
|
56
|
-
def ssr_reload
|
57
|
-
reset soft: true
|
58
|
-
reader.read_layouts
|
59
|
-
|
60
|
-
collections.data.tap do |coll|
|
61
|
-
coll.resources.clear
|
62
|
-
coll.read
|
63
|
-
coll.merge_data_resources.each do |k, v|
|
64
|
-
data[k] = v
|
65
|
-
end
|
66
|
-
end
|
67
|
-
@ssr_reload_hook.() if @ssr_reload_hook.is_a?(Proc)
|
68
|
-
end
|
69
|
-
|
70
55
|
def disable_ssr
|
71
56
|
Bridgetown.logger.info "SSR:", "now disabled."
|
72
57
|
@ssr_enabled = false
|
@@ -82,7 +82,7 @@ create_file "plugins/test_output.rb" do
|
|
82
82
|
<<~RUBY
|
83
83
|
module TestOutput
|
84
84
|
unless Bridgetown.env.development?
|
85
|
-
Bridgetown::Hooks.
|
85
|
+
Bridgetown::Hooks.register_one :site, :post_write do
|
86
86
|
# Load test suite to run on exit
|
87
87
|
require "nokogiri"
|
88
88
|
Dir["test/**/*.rb"].each { |file| require_relative("../\#{file}") }
|
@@ -22,9 +22,10 @@ create_builder "purgecss.rb" do
|
|
22
22
|
PURGE
|
23
23
|
File.write(purgecss_file, config_js.strip)
|
24
24
|
end
|
25
|
-
manifest_file =
|
25
|
+
manifest_file = File.join(site.frontend_bundling_path, "manifest.json")
|
26
26
|
if File.exist?(manifest_file)
|
27
27
|
manifest = JSON.parse(File.read(manifest_file))
|
28
|
+
# TODO: make this work with esbuild too
|
28
29
|
css_file = manifest["main.css"].split("/").last
|
29
30
|
css_path = ["output", "_bridgetown", "static", "css", css_file].join("/")
|
30
31
|
Bridgetown.logger.info "PurgeCSS", "Purging \#{css_file}"
|
@@ -4,25 +4,54 @@ require "fileutils"
|
|
4
4
|
|
5
5
|
say "Installing Stimulus...", :green
|
6
6
|
|
7
|
-
run("yarn add stimulus")
|
7
|
+
run("yarn add @hotwired/stimulus")
|
8
|
+
if Bridgetown::Utils.frontend_bundler_type == :webpack
|
9
|
+
run("yarn add @hotwired/stimulus-webpack-helpers")
|
10
|
+
end
|
8
11
|
|
9
12
|
say 'Adding Stimulus to "frontend/javascript/index.js"...', :magenta
|
10
13
|
|
11
14
|
javascript_import do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
if Bridgetown::Utils.frontend_bundler_type == :esbuild
|
16
|
+
<<~JS
|
17
|
+
import { Application } from "@hotwired/stimulus"
|
18
|
+
JS
|
19
|
+
else
|
20
|
+
<<~JS
|
21
|
+
import { Application } from "@hotwired/stimulus"
|
22
|
+
import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers"
|
23
|
+
JS
|
24
|
+
end
|
16
25
|
end
|
17
26
|
|
18
27
|
javascript_dir = File.join("frontend", "javascript")
|
19
28
|
|
20
29
|
append_to_file(File.join(javascript_dir, "index.js")) do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
if Bridgetown::Utils.frontend_bundler_type == :esbuild
|
31
|
+
<<~JS
|
32
|
+
|
33
|
+
window.Stimulus = Application.start()
|
34
|
+
|
35
|
+
import controllers from "./controllers/**/*.{js,js.rb}"
|
36
|
+
Object.entries(controllers).forEach(([filename, controller]) => {
|
37
|
+
if (filename.includes("_controller.") || filename.includes("-controller.")) {
|
38
|
+
const identifier = filename.replace("./controllers/", "")
|
39
|
+
.replace(/[_\-]controller\..*$/, "")
|
40
|
+
.replace("_", "-")
|
41
|
+
.replace("/", "--")
|
42
|
+
|
43
|
+
Stimulus.register(identifier, controller.default)
|
44
|
+
}
|
45
|
+
})
|
46
|
+
JS
|
47
|
+
else
|
48
|
+
<<~JS
|
49
|
+
|
50
|
+
window.Stimulus = Application.start()
|
51
|
+
const context = require.context("./controllers", true, /\.js$/)
|
52
|
+
Stimulus.load(definitionsFromContext(context))
|
53
|
+
JS
|
54
|
+
end
|
26
55
|
end
|
27
56
|
|
28
57
|
controller_dir = File.join(javascript_dir, "controllers")
|
@@ -33,7 +62,7 @@ FileUtils.mkdir_p(controller_dir)
|
|
33
62
|
say "Creating an example Stimulus Controller for you!...", :magenta
|
34
63
|
create_file(File.join(controller_dir, "example_controller.js")) do
|
35
64
|
<<~JS
|
36
|
-
import { Controller } from "stimulus"
|
65
|
+
import { Controller } from "@hotwired/stimulus"
|
37
66
|
export default class extends Controller {
|
38
67
|
connect() {
|
39
68
|
console.log("Hello, Stimulus!", this.element)
|
@@ -46,4 +75,4 @@ say "Stimulus successfully added", :green
|
|
46
75
|
|
47
76
|
say "To start adding controllers, visit the `./frontend/javascript/controllers/` directory", :blue
|
48
77
|
say "Make sure your controllers follow the `[name]_controller.js` convention", :blue
|
49
|
-
say 'For further reading, check out "https://stimulus.
|
78
|
+
say 'For further reading, check out "https://stimulus.hotwired.dev/"', :blue
|
@@ -11,15 +11,22 @@ unless File.exist?("postcss.config.js")
|
|
11
11
|
return
|
12
12
|
end
|
13
13
|
|
14
|
+
say_status :tailwind, "Installing Tailwind CSS..."
|
15
|
+
|
14
16
|
confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
|
15
17
|
return unless confirm.casecmp?("Y")
|
16
18
|
|
17
19
|
run "yarn add -D tailwindcss"
|
18
20
|
run "npx tailwindcss init"
|
19
21
|
|
20
|
-
|
22
|
+
gsub_file "tailwind.config.js", "content: [],", <<~JS.strip
|
23
|
+
content: [
|
24
|
+
'./src/**/*.{html,md,liquid,erb,serb}',
|
25
|
+
'./frontend/javascript/**/*.js',
|
26
|
+
],
|
27
|
+
JS
|
21
28
|
|
22
|
-
|
29
|
+
copy_file in_templates_dir("postcss.config.js"), "postcss.config.js", force: true
|
23
30
|
|
24
31
|
if File.exist?("frontend/styles/index.css")
|
25
32
|
prepend_to_file "frontend/styles/index.css",
|
@@ -29,4 +36,26 @@ else
|
|
29
36
|
say File.read(in_templates_dir("/css_imports.css"))
|
30
37
|
end
|
31
38
|
|
39
|
+
create_file "frontend/styles/jit-refresh.css", "/* #{Time.now.to_i} */"
|
40
|
+
|
41
|
+
create_builder "tailwind_jit.rb" do
|
42
|
+
<<~RUBY
|
43
|
+
class Builders::TailwindJit < SiteBuilder
|
44
|
+
def build
|
45
|
+
hook :site, :pre_reload do |_, paths|
|
46
|
+
# Don't trigger refresh if it's a frontend-only change
|
47
|
+
next if paths.length == 1 && paths.first.ends_with?("manifest.json")
|
48
|
+
|
49
|
+
# Save out a comment file to trigger Tailwind's JIT
|
50
|
+
refresh_file = site.in_root_dir("frontend", "styles", "jit-refresh.css")
|
51
|
+
File.write refresh_file, "/* \#{Time.now.to_i} */"
|
52
|
+
throw :halt # don't continue the build, wait for watcher rebuild
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
RUBY
|
57
|
+
end
|
58
|
+
|
59
|
+
say_status :tailwind, "Tailwind CSS is now configured."
|
60
|
+
|
32
61
|
# rubocop:enable all
|
@@ -0,0 +1,48 @@
|
|
1
|
+
document.addEventListener("turbo:visit", () => {
|
2
|
+
let main = document.querySelector("main");
|
3
|
+
if (main.dataset.turboTransition == "false") return;
|
4
|
+
|
5
|
+
let [movement, scale] = ["15px", "0.99"];
|
6
|
+
|
7
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
8
|
+
[movement, scale] = ["7px", "1"]
|
9
|
+
};
|
10
|
+
|
11
|
+
main.style.transformOrigin = "50% 0%";
|
12
|
+
main.dataset.animatingOut = true;
|
13
|
+
|
14
|
+
main.animate(
|
15
|
+
[
|
16
|
+
{ opacity: 1, transform: "translateY(0px) scale(1)" },
|
17
|
+
{ opacity: 0, transform: `translateY(${movement}) scale(${scale})` }
|
18
|
+
],
|
19
|
+
{ duration: 300, easing: "cubic-bezier(0.45, 0, 0.55, 1)" }
|
20
|
+
);
|
21
|
+
|
22
|
+
Promise.all(main.getAnimations().map(animation => animation.finished)).then(() => {
|
23
|
+
if (main.dataset.animatingOut) main.style.visibility = "hidden"
|
24
|
+
})
|
25
|
+
});
|
26
|
+
|
27
|
+
document.addEventListener("turbo:load", () => {
|
28
|
+
let main = document.querySelector("main");
|
29
|
+
if (main.dataset.turboTransition == "false") return;
|
30
|
+
|
31
|
+
let [movement, scale] = ["-10px", "0.99"];
|
32
|
+
|
33
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
34
|
+
[movement, scale] = ["-5px", "1"]
|
35
|
+
};
|
36
|
+
|
37
|
+
main.style.visibility = "visible";
|
38
|
+
main.style.transformOrigin = "50% 0%";
|
39
|
+
delete main.dataset.animatingOut;
|
40
|
+
|
41
|
+
main.animate(
|
42
|
+
[
|
43
|
+
{ opacity: 0, transform: `translateY(${movement}) scale(${scale})` },
|
44
|
+
{ opacity: 1, transform: "translateY(0px) scale(1)" }
|
45
|
+
],
|
46
|
+
{ duration: 150, easing: "cubic-bezier(0.45, 0, 0.55, 1)" }
|
47
|
+
)
|
48
|
+
})
|