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
@@ -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
|
+
})
|
@@ -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
|
@@ -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
|
@@ -5,6 +5,7 @@ module Bridgetown
|
|
5
5
|
include LayoutPlaceable
|
6
6
|
include LiquidRenderable
|
7
7
|
include Publishable
|
8
|
+
include Transformable
|
8
9
|
|
9
10
|
attr_writer :dir
|
10
11
|
attr_accessor :site, :paginator, :name, :ext, :basename, :data, :content, :output
|
@@ -12,7 +13,7 @@ module Bridgetown
|
|
12
13
|
alias_method :extname, :ext
|
13
14
|
|
14
15
|
# A set of extensions that are considered HTML or HTML-like so we
|
15
|
-
# should not alter them
|
16
|
+
# should not alter them
|
16
17
|
|
17
18
|
HTML_EXTENSIONS = %w(
|
18
19
|
.html
|
@@ -54,11 +55,11 @@ module Bridgetown
|
|
54
55
|
output || content || ""
|
55
56
|
end
|
56
57
|
|
57
|
-
# Accessor for data properties by Liquid
|
58
|
+
# Accessor for data properties by Liquid
|
58
59
|
#
|
59
|
-
# property
|
60
|
+
# @param property [String] name of the property to retrieve
|
60
61
|
#
|
61
|
-
#
|
62
|
+
# @return [Object]
|
62
63
|
def [](property)
|
63
64
|
data[property]
|
64
65
|
end
|
@@ -67,7 +68,7 @@ module Bridgetown
|
|
67
68
|
# upon generation. This is derived from the permalink or, if
|
68
69
|
# permalink is absent, will be '/'
|
69
70
|
#
|
70
|
-
#
|
71
|
+
# @return [String]
|
71
72
|
def dir
|
72
73
|
if url.end_with?("/")
|
73
74
|
url
|
@@ -78,6 +79,8 @@ module Bridgetown
|
|
78
79
|
end
|
79
80
|
|
80
81
|
# Liquid representation of current page
|
82
|
+
#
|
83
|
+
# @return [Bridgetown::Drops::GeneratedPageDrop]
|
81
84
|
def to_liquid
|
82
85
|
@liquid_drop ||= Drops::GeneratedPageDrop.new(self)
|
83
86
|
end
|
@@ -90,7 +93,7 @@ module Bridgetown
|
|
90
93
|
|
91
94
|
# The template of the permalink.
|
92
95
|
#
|
93
|
-
#
|
96
|
+
# @return [String]
|
94
97
|
def template
|
95
98
|
if !html?
|
96
99
|
"/:path/:basename:output_ext"
|
@@ -103,7 +106,7 @@ module Bridgetown
|
|
103
106
|
|
104
107
|
# The generated relative url of this page. e.g. /about.html.
|
105
108
|
#
|
106
|
-
#
|
109
|
+
# @return [String]
|
107
110
|
def url
|
108
111
|
@url ||= URL.new(
|
109
112
|
template: template,
|
@@ -123,6 +126,22 @@ module Bridgetown
|
|
123
126
|
}
|
124
127
|
end
|
125
128
|
|
129
|
+
# Layout associated with this resource
|
130
|
+
# This will output a warning if the layout can't be found.
|
131
|
+
#
|
132
|
+
# @return [Bridgetown::Layout]
|
133
|
+
def layout
|
134
|
+
return @layout if @layout
|
135
|
+
return if no_layout?
|
136
|
+
|
137
|
+
@layout = site.layouts[data.layout].tap do |layout|
|
138
|
+
unless layout
|
139
|
+
Bridgetown.logger.warn "Generated Page:", "Layout '#{data.layout}' " \
|
140
|
+
"requested via #{relative_path} does not exist."
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
126
145
|
# Overide this in subclasses for custom initialization behavior
|
127
146
|
def process
|
128
147
|
# no-op by default
|
@@ -139,21 +158,68 @@ module Bridgetown
|
|
139
158
|
@relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).delete_prefix("/")
|
140
159
|
end
|
141
160
|
|
142
|
-
# FIXME: spinning up a new Renderer object just to get an extension
|
143
|
-
# seems excessive
|
144
|
-
#
|
145
161
|
# The output extension of the page.
|
146
162
|
#
|
147
|
-
#
|
163
|
+
# @return [String]
|
148
164
|
def output_ext
|
149
|
-
@output_ext ||=
|
165
|
+
@output_ext ||= (permalink_ext || converter_output_ext)
|
166
|
+
end
|
167
|
+
|
168
|
+
def permalink_ext
|
169
|
+
page_permalink = permalink
|
170
|
+
if page_permalink &&
|
171
|
+
!page_permalink.end_with?("/")
|
172
|
+
permalink_ext = File.extname(page_permalink)
|
173
|
+
permalink_ext unless permalink_ext.empty?
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def converter_output_ext
|
178
|
+
if output_exts.size == 1
|
179
|
+
output_exts.last
|
180
|
+
else
|
181
|
+
output_exts[-2]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def output_exts
|
186
|
+
@output_exts ||= converters.filter_map do |c|
|
187
|
+
c.output_ext(extname)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# @return [Array<Bridgetown::Converter>]
|
192
|
+
def converters
|
193
|
+
@converters ||= site.matched_converters_for_convertible(self)
|
194
|
+
end
|
195
|
+
|
196
|
+
def transform!
|
197
|
+
Bridgetown.logger.debug "Transforming:", relative_path
|
198
|
+
|
199
|
+
trigger_hooks :pre_render
|
200
|
+
self.content = transform_content(self)
|
201
|
+
place_in_layout? ? place_into_layouts : self.output = content.dup
|
202
|
+
trigger_hooks :post_render
|
203
|
+
|
204
|
+
self
|
205
|
+
end
|
206
|
+
|
207
|
+
def place_into_layouts
|
208
|
+
Bridgetown.logger.debug "Placing in Layouts:", relative_path
|
209
|
+
rendered_output = content.dup
|
210
|
+
|
211
|
+
site.validated_layouts_for(self, data.layout).each do |layout|
|
212
|
+
rendered_output = transform_with_layout(layout, rendered_output, self)
|
213
|
+
end
|
214
|
+
|
215
|
+
self.output = rendered_output
|
150
216
|
end
|
151
217
|
|
152
218
|
# Obtain destination path.
|
153
219
|
#
|
154
|
-
# dest
|
220
|
+
# @param dest [String] path to the destination dir
|
155
221
|
#
|
156
|
-
#
|
222
|
+
# @return [String]
|
157
223
|
def destination(dest)
|
158
224
|
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
159
225
|
path = File.join(path, "index") if url.end_with?("/")
|
@@ -163,9 +229,7 @@ module Bridgetown
|
|
163
229
|
|
164
230
|
# Write the generated page file to the destination directory.
|
165
231
|
#
|
166
|
-
# dest
|
167
|
-
#
|
168
|
-
# Returns nothing.
|
232
|
+
# @param dest [String] path to the destination dir
|
169
233
|
def write(dest)
|
170
234
|
path = destination(dest)
|
171
235
|
FileUtils.mkdir_p(File.dirname(path))
|
@@ -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)
|