bridgetown-core 0.18.4 → 0.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bridgetown +6 -0
- data/bridgetown-core.gemspec +3 -3
- data/lib/bridgetown-core.rb +24 -2
- data/lib/bridgetown-core/commands/apply.rb +4 -3
- data/lib/bridgetown-core/commands/concerns/actions.rb +0 -5
- data/lib/bridgetown-core/commands/configure.rb +62 -0
- data/lib/bridgetown-core/commands/new.rb +28 -1
- data/lib/bridgetown-core/commands/plugins.rb +1 -0
- data/lib/bridgetown-core/configurations/.keep +0 -0
- data/lib/bridgetown-core/configurations/bt-postcss.rb +26 -0
- data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +21 -0
- data/lib/bridgetown-core/configurations/minitesting.rb +95 -0
- data/lib/bridgetown-core/configurations/netlify.rb +6 -0
- data/lib/bridgetown-core/configurations/netlify/netlify.sh +14 -0
- data/lib/bridgetown-core/configurations/netlify/netlify.toml +44 -0
- data/lib/bridgetown-core/configurations/purgecss.rb +49 -0
- data/lib/bridgetown-core/configurations/stimulus.rb +49 -0
- data/lib/bridgetown-core/configurations/swup.rb +37 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +29 -0
- data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +4 -0
- data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +12 -0
- data/lib/bridgetown-core/configurations/turbo.rb +16 -0
- data/lib/bridgetown-core/converters/erb_templates.rb +6 -13
- data/lib/bridgetown-core/filters.rb +3 -3
- data/lib/bridgetown-core/generator.rb +2 -1
- data/lib/bridgetown-core/page_without_a_file.rb +3 -0
- data/lib/bridgetown-core/plugin.rb +2 -26
- data/lib/bridgetown-core/ruby_template_view.rb +9 -2
- data/lib/bridgetown-core/utils/ruby_exec.rb +4 -4
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/site_template/README.md +70 -0
- data/lib/site_template/frontend/javascript/index.js.erb +11 -0
- data/lib/site_template/frontend/styles/index.css +19 -0
- data/lib/site_template/{package.json → package.json.erb} +16 -9
- data/lib/site_template/postcss.config.js.erb +11 -0
- data/lib/site_template/src/_components/footer.liquid +1 -1
- data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
- data/lib/site_template/{webpack.config.js → webpack.config.js.erb} +24 -0
- metadata +41 -23
- data/lib/site_template/frontend/javascript/index.js +0 -3
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
# Taken from https://docs.netlify.com/configure-builds/file-based-configuration/#inject-environment-variable-values
|
3
|
+
|
4
|
+
echo "Updating netlify.toml with references to our built files"
|
5
|
+
|
6
|
+
CSS_PATH=`find output/_bridgetown/static/css/*.css -type f | sed -e 's,output\/,/,g'`
|
7
|
+
JS_PATH=`find output/_bridgetown/static/js/*.js -type f | sed -e 's,output\/,/,g'`
|
8
|
+
|
9
|
+
echo "CSS Path: ${CSS_PATH}"
|
10
|
+
echo "JS Path: ${JS_PATH}"
|
11
|
+
|
12
|
+
sed -i s,CSS_PATH,${CSS_PATH},g netlify.toml
|
13
|
+
sed -i s,JS_PATH,${JS_PATH},g netlify.toml
|
14
|
+
sed -i s,NETLIFY_IMAGES_CDN_DOMAIN,${NETLIFY_IMAGES_CDN_DOMAIN},g netlify.toml
|
@@ -0,0 +1,44 @@
|
|
1
|
+
[build]
|
2
|
+
command = "yarn deploy && ./bin/netlify.sh"
|
3
|
+
publish = "output"
|
4
|
+
|
5
|
+
[build.environment]
|
6
|
+
NODE_ENV = "development"
|
7
|
+
BRIDGETOWN_ENV = "production"
|
8
|
+
|
9
|
+
[build.processing]
|
10
|
+
skip_processing = false
|
11
|
+
[build.processing.css]
|
12
|
+
bundle = false
|
13
|
+
minify = true
|
14
|
+
[build.processing.js]
|
15
|
+
bundle = false
|
16
|
+
minify = true
|
17
|
+
[build.processing.html]
|
18
|
+
pretty_urls = true
|
19
|
+
[build.processing.images]
|
20
|
+
compress = true
|
21
|
+
|
22
|
+
[[headers]]
|
23
|
+
for = "*"
|
24
|
+
[headers.values]
|
25
|
+
X-Frame-Options = "DENY"
|
26
|
+
X-XSS-Protection = "1; mode=block"
|
27
|
+
X-Content-Type-Options = "nosniff"
|
28
|
+
Strict-Transport-Security = "max-age=15552000; includeSubDomains"
|
29
|
+
Referrer-Policy = "no-referrer-when-downgrade"
|
30
|
+
Cache-Control = "public, max-age=604800, s-max-age=604800"
|
31
|
+
|
32
|
+
[[headers]]
|
33
|
+
for = "/"
|
34
|
+
[headers.values]
|
35
|
+
Link = [
|
36
|
+
"<CSS_PATH>; rel=preload; as=style",
|
37
|
+
"<JS_PATH>; rel=preload; as=script",
|
38
|
+
"<https://NETLIFY_IMAGES_CDN_DOMAIN>; rel=preconnect"
|
39
|
+
]
|
40
|
+
|
41
|
+
[[headers]]
|
42
|
+
for = "/*.(png|jpg|js|css|svg|woff|ttf|eot|ico|woff2)"
|
43
|
+
[headers.values]
|
44
|
+
Cache-Control = "public, max-age=31536000, s-max-age=31536000"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable all
|
4
|
+
|
5
|
+
say_status :purgecss, "Installing PurgeCSS"
|
6
|
+
|
7
|
+
run "yarn add -D purgecss"
|
8
|
+
|
9
|
+
create_builder "purgecss_builder.rb" do
|
10
|
+
<<~RUBY
|
11
|
+
class PurgeCSS < SiteBuilder
|
12
|
+
def build
|
13
|
+
unless config[:watch] # don't run in "watch mode"
|
14
|
+
hook :site, :post_write do
|
15
|
+
purgecss_file = site.in_root_dir("purgecss.config.js")
|
16
|
+
unless File.exist?(purgecss_file)
|
17
|
+
config_js = <<~PURGE
|
18
|
+
module.exports = {
|
19
|
+
content: ['frontend/javascript/*.js','./output/**/*.html'],
|
20
|
+
output: "./output/_bridgetown/static/css"
|
21
|
+
}
|
22
|
+
PURGE
|
23
|
+
File.write(purgecss_file, config_js.strip)
|
24
|
+
end
|
25
|
+
manifest_file = site.in_root_dir(".bridgetown-webpack", "manifest.json")
|
26
|
+
if File.exist?(manifest_file)
|
27
|
+
manifest = JSON.parse(File.read(manifest_file))
|
28
|
+
css_file = manifest["main.css"].split("/").last
|
29
|
+
css_path = ["output", "_bridgetown", "static", "css", css_file].join("/")
|
30
|
+
Bridgetown.logger.info "PurgeCSS", "Purging \#{css_file}"
|
31
|
+
oldsize = File.stat(css_path).size / 1000
|
32
|
+
system "./node_modules/.bin/purgecss -c purgecss.config.js -css \#{css_path}"
|
33
|
+
newsize = File.stat(css_path).size / 1000
|
34
|
+
if newsize < oldsize
|
35
|
+
Bridgetown.logger.info "PurgeCSS", "Done! File size reduced from \#{oldsize}kB to \#{newsize}kB"
|
36
|
+
else
|
37
|
+
Bridgetown.logger.info "PurgeCSS", "Done. No apparent change in file size (\#{newsize}kB)."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
RUBY
|
45
|
+
end
|
46
|
+
|
47
|
+
say_status :purgecss, "All set! Open plugins/builders/purgecss_builder.rb if you'd like to customize the PurgeCSS config."
|
48
|
+
|
49
|
+
# rubocop:enable all
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
say "Installing Stimulus...", :green
|
6
|
+
|
7
|
+
run("yarn add stimulus")
|
8
|
+
|
9
|
+
say 'Adding Stimulus to "frontend/javascript/index.js"...', :magenta
|
10
|
+
|
11
|
+
javascript_import do
|
12
|
+
<<~JS
|
13
|
+
import { Application } from "stimulus"
|
14
|
+
import { definitionsFromContext } from "stimulus/webpack-helpers"
|
15
|
+
JS
|
16
|
+
end
|
17
|
+
|
18
|
+
javascript_dir = File.join("frontend", "javascript")
|
19
|
+
|
20
|
+
append_to_file(File.join(javascript_dir, "index.js")) do
|
21
|
+
<<~JS
|
22
|
+
const application = Application.start()
|
23
|
+
const context = require.context("./controllers", true, /\.js$/)
|
24
|
+
application.load(definitionsFromContext(context))
|
25
|
+
JS
|
26
|
+
end
|
27
|
+
|
28
|
+
controller_dir = File.join(javascript_dir, "controllers")
|
29
|
+
|
30
|
+
say "Creating a `./#{controller_dir}` directory...", :magenta
|
31
|
+
FileUtils.mkdir_p(controller_dir)
|
32
|
+
|
33
|
+
say "Creating an example Stimulus Controller for you!...", :magenta
|
34
|
+
create_file(File.join(controller_dir, "example_controller.js")) do
|
35
|
+
<<~JS
|
36
|
+
import { Controller } from "stimulus"
|
37
|
+
export default class extends Controller {
|
38
|
+
connect() {
|
39
|
+
console.log("Hello, Stimulus!", this.element)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
JS
|
43
|
+
end
|
44
|
+
|
45
|
+
say "Stimulus successfully added", :green
|
46
|
+
|
47
|
+
say "To start adding controllers, visit the `./frontend/javascript/controllers/` directory", :blue
|
48
|
+
say "Make sure your controllers follow the `[name]_controller.js` convention", :blue
|
49
|
+
say 'For further reading, check out "https://stimulus.hotwire.dev/"', :blue
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable all
|
4
|
+
|
5
|
+
packages = "swup @swup/body-class-plugin @swup/scroll-plugin @swup/fade-theme"
|
6
|
+
say_status :swup, "Adding the following yarn packages: #{packages}"
|
7
|
+
system("yarn add #{packages}")
|
8
|
+
|
9
|
+
javascript_import do
|
10
|
+
<<~JS
|
11
|
+
import Swup from "swup"
|
12
|
+
import SwupBodyClassPlugin from "@swup/body-class-plugin"
|
13
|
+
import SwupScrollPlugin from "@swup/scroll-plugin"
|
14
|
+
import SwupFadeTheme from "@swup/fade-theme"
|
15
|
+
const swup = new Swup({
|
16
|
+
plugins: [
|
17
|
+
new SwupBodyClassPlugin(),
|
18
|
+
new SwupScrollPlugin(),
|
19
|
+
new SwupFadeTheme(),
|
20
|
+
]
|
21
|
+
})
|
22
|
+
JS
|
23
|
+
end
|
24
|
+
|
25
|
+
css_index = File.exist?(File.expand_path("frontend/styles/index.scss", destination_root)) ? "frontend/styles/index.scss" : "frontend/styles/index.css"
|
26
|
+
append_to_file css_index do
|
27
|
+
<<~CSS
|
28
|
+
.swup-transition-main {
|
29
|
+
transition: opacity .2s;
|
30
|
+
}
|
31
|
+
CSS
|
32
|
+
end
|
33
|
+
|
34
|
+
say_status :swup, "All done! Edit .swup-transition-main in #{css_index} if you wish to adjust the transition animation"
|
35
|
+
say_status :swup, "Make sure you add id=\"swup\" to the primary container of your HTML layout (perhaps <main>)"
|
36
|
+
|
37
|
+
# rubocop:enable all
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable all
|
4
|
+
|
5
|
+
TEMPLATE_PATH = File.expand_path("./tailwindcss", __dir__)
|
6
|
+
|
7
|
+
begin
|
8
|
+
find_in_source_paths("postcss.config.js")
|
9
|
+
rescue Thor::Error
|
10
|
+
error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."
|
11
|
+
|
12
|
+
@logger.error "\nError:".red, "🚨 #{error_message}"
|
13
|
+
@logger.info "\nFor new projects, you can use #{"bridgetown new my_project --use-postcss".bold.blue}\n"
|
14
|
+
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
run "yarn add -D tailwindcss"
|
19
|
+
run "npx tailwindcss init"
|
20
|
+
|
21
|
+
remove_file "postcss.config.js"
|
22
|
+
copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js"
|
23
|
+
|
24
|
+
prepend_to_file "frontend/styles/index.css",
|
25
|
+
File.read("#{TEMPLATE_PATH}/css_imports.css")
|
26
|
+
|
27
|
+
run "bundle exec bridgetown configure purgecss"
|
28
|
+
|
29
|
+
# rubocop:enable all
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
say "Installing Turbo...", :green
|
4
|
+
|
5
|
+
run("yarn add @hotwired/turbo")
|
6
|
+
|
7
|
+
say 'Adding Turbo to "frontend/javascript/index.js"...', :magenta
|
8
|
+
|
9
|
+
javascript_import do
|
10
|
+
<<~JS
|
11
|
+
import Turbo from "@hotwired/turbo"
|
12
|
+
JS
|
13
|
+
end
|
14
|
+
|
15
|
+
say "Turbo successfully added", :green
|
16
|
+
say 'For further reading, check out "https://turbo.hotwire.dev/"', :blue
|
@@ -65,24 +65,17 @@ module Bridgetown
|
|
65
65
|
block.nil? ? input.to_s : capture(&block)
|
66
66
|
)
|
67
67
|
converter = site.find_converter_instance(Bridgetown::Converters::Markdown)
|
68
|
-
converter.convert(content).strip
|
68
|
+
result = converter.convert(content).strip
|
69
|
+
result.respond_to?(:html_safe) ? result.html_safe : result
|
69
70
|
end
|
70
71
|
|
71
|
-
def capture(
|
72
|
+
def capture(*args, &block)
|
73
|
+
return capture_in_view_component(*args, &block) if @in_view_component
|
74
|
+
|
72
75
|
previous_buffer_state = @_erbout
|
73
76
|
@_erbout = ERBBuffer.new
|
74
|
-
|
75
|
-
# For compatibility with ActionView, not used by Bridgetown normally
|
76
|
-
previous_ob_state = @output_buffer
|
77
|
-
@output_buffer = ERBBuffer.new
|
78
|
-
|
79
|
-
result = instance_exec(obj, &block)
|
80
|
-
if @output_buffer != ""
|
81
|
-
# use Rails' ActionView buffer if present
|
82
|
-
result = @output_buffer
|
83
|
-
end
|
77
|
+
result = yield(*args)
|
84
78
|
@_erbout = previous_buffer_state
|
85
|
-
@output_buffer = previous_ob_state
|
86
79
|
|
87
80
|
result.respond_to?(:html_safe) ? result.html_safe : result
|
88
81
|
end
|
@@ -126,8 +126,8 @@ module Bridgetown
|
|
126
126
|
# @return [String] a link unreadable for bots but will be recovered on focus or mouseover
|
127
127
|
def obfuscate_link(input, prefix = "mailto")
|
128
128
|
link = "<a href=\"#{prefix}:#{input}\">#{input}</a>"
|
129
|
-
script = "<script type=\"text/javascript\">document.currentScript.insertAdjacentHTML("
|
130
|
-
script += "beforebegin', '#{rot47(link)}'.replace(/[!-~]/g,"
|
129
|
+
script = "<script type=\"text/javascript\">document.currentScript.insertAdjacentHTML('"
|
130
|
+
script += "beforebegin', '#{rot47(link).gsub(%r!\\!, '\\\\\\')}'.replace(/[!-~]/g,"
|
131
131
|
script += "function(c){{var j=c.charCodeAt(0);if((j>=33)&&(j<=126)){"
|
132
132
|
script += "return String.fromCharCode(33+((j+ 14)%94));}"
|
133
133
|
script += "else{return String.fromCharCode(j);}}}));</script>"
|
@@ -375,7 +375,7 @@ module Bridgetown
|
|
375
375
|
case target
|
376
376
|
when NilClass
|
377
377
|
return true if property.nil?
|
378
|
-
when
|
378
|
+
when "" # aka `empty` or `blank`
|
379
379
|
target = target.to_s
|
380
380
|
return true if property == target || Array(property).join == target
|
381
381
|
else
|
@@ -7,6 +7,9 @@ module Bridgetown
|
|
7
7
|
# The class instance is basically just a bare-bones entity with just
|
8
8
|
# attributes "dir", "name", "path", "url" defined on it.
|
9
9
|
class PageWithoutAFile < Page
|
10
|
+
Bridgetown.logger.warn "NOTICE: the PageWithoutAFile class is deprecated and" \
|
11
|
+
" will be removed in Bridgetown 0.20."
|
12
|
+
|
10
13
|
def read_yaml(*)
|
11
14
|
@data ||= {}
|
12
15
|
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Bridgetown
|
4
4
|
class Plugin
|
5
|
+
extend ActiveSupport::DescendantsTracker
|
6
|
+
|
5
7
|
PRIORITIES = {
|
6
8
|
low: -10,
|
7
9
|
highest: 100,
|
@@ -12,32 +14,6 @@ module Bridgetown
|
|
12
14
|
|
13
15
|
SourceManifest = Struct.new(:origin, :components, :content, :layouts, keyword_init: true)
|
14
16
|
|
15
|
-
#
|
16
|
-
|
17
|
-
def self.inherited(const)
|
18
|
-
catch_inheritance(const) do |const_|
|
19
|
-
catch_inheritance(const_)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
|
25
|
-
def self.catch_inheritance(const)
|
26
|
-
const.define_singleton_method :inherited do |const_|
|
27
|
-
(@children ||= Set.new).add const_
|
28
|
-
yield const_ if block_given?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
#
|
33
|
-
|
34
|
-
def self.descendants
|
35
|
-
@children ||= Set.new
|
36
|
-
out = @children.map(&:descendants)
|
37
|
-
out << self unless superclass == Plugin
|
38
|
-
Set.new(out).flatten
|
39
|
-
end
|
40
|
-
|
41
17
|
# Get or set the priority of this plugin. When called without an
|
42
18
|
# argument it returns the priority. When an argument is given, it will
|
43
19
|
# set the priority.
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "digest"
|
4
|
-
require "active_support/core_ext/hash/keys"
|
5
4
|
|
6
5
|
module Bridgetown
|
7
6
|
class RubyTemplateView
|
@@ -28,7 +27,15 @@ module Bridgetown
|
|
28
27
|
|
29
28
|
def render(item, options = {}, &block)
|
30
29
|
if item.respond_to?(:render_in)
|
31
|
-
|
30
|
+
previous_buffer_state = @_erbout
|
31
|
+
@_erbout = Bridgetown::ERBBuffer.new
|
32
|
+
|
33
|
+
@in_view_component ||= defined?(::ViewComponent::Base) && item.is_a?(::ViewComponent::Base)
|
34
|
+
result = item.render_in(self, &block)
|
35
|
+
@in_view_component = false
|
36
|
+
|
37
|
+
@_erbout = previous_buffer_state
|
38
|
+
result
|
32
39
|
else
|
33
40
|
partial(item, options, &block)
|
34
41
|
end
|
@@ -20,14 +20,14 @@ module Bridgetown
|
|
20
20
|
v.each do |nested_k, nested_v|
|
21
21
|
next unless nested_v.is_a?(Rb)
|
22
22
|
|
23
|
-
Bridgetown.logger.
|
23
|
+
Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
|
24
24
|
convertible.data[k][nested_k] = run(nested_v, convertible, renderer)
|
25
|
-
Bridgetown.logger.
|
25
|
+
Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
|
26
26
|
end
|
27
27
|
else
|
28
|
-
Bridgetown.logger.
|
28
|
+
Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
|
29
29
|
convertible.data[k] = run(v, convertible, renderer)
|
30
|
-
Bridgetown.logger.
|
30
|
+
Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|