bridgetown-core 1.0.0.alpha6 → 1.0.0.alpha10
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 +8 -1
- data/bridgetown-core.gemspec +3 -3
- data/lib/bridgetown-core/cache.rb +1 -1
- data/lib/bridgetown-core/collection.rb +1 -1
- data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +7 -0
- data/lib/bridgetown-core/commands/configure.rb +7 -0
- data/lib/bridgetown-core/commands/console.rb +38 -12
- data/lib/bridgetown-core/commands/doctor.rb +8 -5
- data/lib/bridgetown-core/commands/new.rb +1 -0
- data/lib/bridgetown-core/commands/plugins.rb +1 -1
- data/lib/bridgetown-core/component.rb +2 -2
- data/lib/bridgetown-core/concerns/front_matter_importer.rb +1 -1
- data/lib/bridgetown-core/concerns/site/configurable.rb +6 -3
- data/lib/bridgetown-core/concerns/site/extensible.rb +2 -1
- data/lib/bridgetown-core/concerns/site/ssr.rb +38 -16
- data/lib/bridgetown-core/configuration.rb +77 -46
- data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -3
- data/lib/bridgetown-core/configurations/cypress/cypress.json +4 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_dir/fixtures/example.json +5 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_dir/integration/navbar.spec.js +17 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_dir/plugins/index.js +21 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_dir/support/commands.js +25 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_dir/support/index.js +20 -0
- data/lib/bridgetown-core/configurations/cypress/cypress_tasks +33 -0
- data/lib/bridgetown-core/configurations/cypress.rb +13 -0
- data/lib/bridgetown-core/configurations/minitesting.rb +19 -15
- data/lib/bridgetown-core/configurations/netlify.rb +2 -4
- data/lib/bridgetown-core/configurations/purgecss.rb +2 -2
- data/lib/bridgetown-core/configurations/render/render.yaml.erb +26 -0
- data/lib/bridgetown-core/configurations/render.rb +6 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +3 -5
- data/lib/bridgetown-core/converters/erb_templates.rb +1 -1
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
- data/lib/bridgetown-core/converters/serbea_templates.rb +71 -0
- data/lib/bridgetown-core/core_ext/psych.rb +1 -5
- data/lib/bridgetown-core/frontmatter_defaults.rb +2 -2
- data/lib/bridgetown-core/liquid_renderer/file_system.rb +1 -3
- data/lib/bridgetown-core/liquid_renderer.rb +1 -1
- data/lib/bridgetown-core/model/base.rb +23 -26
- data/lib/bridgetown-core/model/builder_origin.rb +8 -6
- data/lib/bridgetown-core/model/origin.rb +10 -1
- data/lib/bridgetown-core/model/plugin_origin.rb +1 -1
- data/lib/bridgetown-core/plugin_manager.rb +9 -36
- data/lib/bridgetown-core/rack/boot.rb +46 -23
- data/lib/bridgetown-core/rack/roda.rb +2 -1
- data/lib/bridgetown-core/rack/routes.rb +2 -2
- data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
- data/lib/bridgetown-core/readers/plugin_content_reader.rb +1 -1
- data/lib/bridgetown-core/renderer.rb +2 -2
- data/lib/bridgetown-core/resource/base.rb +3 -3
- data/lib/bridgetown-core/resource/relations.rb +1 -1
- data/lib/bridgetown-core/resource/taxonomy_term.rb +2 -2
- data/lib/bridgetown-core/resource/taxonomy_type.rb +2 -2
- data/lib/bridgetown-core/ruby_template_view.rb +2 -2
- data/lib/bridgetown-core/site.rb +15 -5
- data/lib/bridgetown-core/utils/loaders_manager.rb +83 -0
- data/lib/bridgetown-core/utils.rb +13 -14
- data/lib/bridgetown-core/version.rb +1 -1
- data/lib/bridgetown-core/watcher.rb +16 -7
- data/lib/bridgetown-core/yaml_parser.rb +1 -5
- data/lib/bridgetown-core.rb +0 -1
- data/lib/site_template/README.md +1 -1
- data/lib/site_template/Rakefile +3 -3
- metadata +45 -19
@@ -0,0 +1,25 @@
|
|
1
|
+
// ***********************************************
|
2
|
+
// This example commands.js shows you how to
|
3
|
+
// create various custom commands and overwrite
|
4
|
+
// existing commands.
|
5
|
+
//
|
6
|
+
// For more comprehensive examples of custom
|
7
|
+
// commands please read more here:
|
8
|
+
// https://on.cypress.io/custom-commands
|
9
|
+
// ***********************************************
|
10
|
+
//
|
11
|
+
//
|
12
|
+
// -- This is a parent command --
|
13
|
+
// Cypress.Commands.add("login", (email, password) => { ... })
|
14
|
+
//
|
15
|
+
//
|
16
|
+
// -- This is a child command --
|
17
|
+
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
18
|
+
//
|
19
|
+
//
|
20
|
+
// -- This is a dual command --
|
21
|
+
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
22
|
+
//
|
23
|
+
//
|
24
|
+
// -- This will overwrite an existing command --
|
25
|
+
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
@@ -0,0 +1,20 @@
|
|
1
|
+
// ***********************************************************
|
2
|
+
// This example support/index.js is processed and
|
3
|
+
// loaded automatically before your test files.
|
4
|
+
//
|
5
|
+
// This is a great place to put global configuration and
|
6
|
+
// behavior that modifies Cypress.
|
7
|
+
//
|
8
|
+
// You can change the location of this file or turn off
|
9
|
+
// automatically serving support files with the
|
10
|
+
// 'supportFile' configuration option.
|
11
|
+
//
|
12
|
+
// You can read more here:
|
13
|
+
// https://on.cypress.io/configuration
|
14
|
+
// ***********************************************************
|
15
|
+
|
16
|
+
// Import commands.js using ES2015 syntax:
|
17
|
+
import './commands'
|
18
|
+
|
19
|
+
// Alternatively you can use CommonJS syntax:
|
20
|
+
// require('./commands')
|
@@ -0,0 +1,33 @@
|
|
1
|
+
namespace :cy do
|
2
|
+
desc "Open Cypress test runner"
|
3
|
+
task :open do
|
4
|
+
system "yarn run cypress open"
|
5
|
+
end
|
6
|
+
|
7
|
+
desc "Run Cypress tests headless"
|
8
|
+
task :run do
|
9
|
+
system "yarn run cypress run"
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Start server and open Cypress test runner"
|
13
|
+
task :test do
|
14
|
+
ENV["BRIDGETOWN_ENV"] = "test"
|
15
|
+
server_pid = fork { Bridgetown::Commands::Start.start }
|
16
|
+
Rake::Task["cy:open"].execute
|
17
|
+
Process.kill "SIGTERM", server_pid
|
18
|
+
sleep 1 # give processes time to clean up
|
19
|
+
puts
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :test do
|
23
|
+
desc "Start server and run Cypress tests headless"
|
24
|
+
task :ci do
|
25
|
+
ENV["BRIDGETOWN_ENV"] = "test"
|
26
|
+
server_pid = fork { Bridgetown::Commands::Start.start }
|
27
|
+
Rake::Task["cy:run"].execute
|
28
|
+
Process.kill "SIGTERM", server_pid
|
29
|
+
sleep 1 # give processes time to clean up
|
30
|
+
puts
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Install packages
|
4
|
+
|
5
|
+
say "Installing Cypress...", :green
|
6
|
+
run "yarn add -D cypress"
|
7
|
+
|
8
|
+
# Copy cypress files and tasks into place
|
9
|
+
cypress_tasks = File.read(in_templates_dir("cypress_tasks"))
|
10
|
+
|
11
|
+
copy_file in_templates_dir("cypress.json"), "cypress.json"
|
12
|
+
inject_into_file("Rakefile", "\n#{cypress_tasks}")
|
13
|
+
directory in_templates_dir("cypress_dir"), "cypress"
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# rubocop:disable all
|
4
4
|
|
5
|
-
say_status :minitesting, "Adding test gems
|
5
|
+
say_status :minitesting, "Adding test gems and examples"
|
6
6
|
|
7
7
|
append_to_file "Gemfile" do
|
8
8
|
<<~GEMS
|
@@ -18,12 +18,6 @@ append_to_file "Gemfile" do
|
|
18
18
|
GEMS
|
19
19
|
end
|
20
20
|
|
21
|
-
new_scripts = ' "test": "BRIDGETOWN_ENV=test yarn build",'
|
22
|
-
new_scripts += "\n" + ' "deploy:test": "bundle install --with test && yarn deploy"'
|
23
|
-
package_json = "package.json"
|
24
|
-
script_regex = %r{"scripts": \{(\s+".*,?)*}
|
25
|
-
inject_into_file(package_json, ",\n" + new_scripts, after: script_regex)
|
26
|
-
|
27
21
|
create_file "test/helper.rb" do
|
28
22
|
<<~RUBY
|
29
23
|
require "nokogiri"
|
@@ -32,23 +26,29 @@ create_file "test/helper.rb" do
|
|
32
26
|
require "minitest/profile"
|
33
27
|
require "shoulda"
|
34
28
|
require "rails-dom-testing"
|
29
|
+
|
35
30
|
# Report with color.
|
36
31
|
Minitest::Reporters.use! [
|
37
32
|
Minitest::Reporters::DefaultReporter.new(
|
38
33
|
color: true
|
39
34
|
),
|
40
35
|
]
|
36
|
+
|
41
37
|
Minitest::Test.class_eval do
|
42
38
|
include Rails::Dom::Testing::Assertions
|
39
|
+
|
43
40
|
def site
|
44
41
|
@site ||= Bridgetown.sites.first
|
45
42
|
end
|
43
|
+
|
46
44
|
def nokogiri(input)
|
47
45
|
input.respond_to?(:output) ? Nokogiri::HTML(input.output) : Nokogiri::HTML(input)
|
48
46
|
end
|
47
|
+
|
49
48
|
def document_root(root)
|
50
49
|
@document_root = root.is_a?(Nokogiri::XML::Document) ? root : nokogiri(root)
|
51
50
|
end
|
51
|
+
|
52
52
|
def document_root_element
|
53
53
|
if @document_root.nil?
|
54
54
|
raise "Call `document_root' with a Nokogiri document before testing your assertions"
|
@@ -62,12 +62,14 @@ end
|
|
62
62
|
create_file "test/test_homepage.rb" do
|
63
63
|
<<~RUBY
|
64
64
|
require_relative "./helper"
|
65
|
+
|
65
66
|
class TestHomepage < Minitest::Test
|
66
67
|
context "homepage" do
|
67
68
|
setup do
|
68
69
|
page = site.collections.pages.resources.find { |doc| doc.relative_url == "/" }
|
69
70
|
document_root page
|
70
71
|
end
|
72
|
+
|
71
73
|
should "exist" do
|
72
74
|
assert_select "body"
|
73
75
|
end
|
@@ -78,18 +80,20 @@ end
|
|
78
80
|
|
79
81
|
create_file "plugins/test_output.rb" do
|
80
82
|
<<~RUBY
|
81
|
-
|
82
|
-
Bridgetown
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
module TestOutput
|
84
|
+
unless Bridgetown.env.development?
|
85
|
+
Bridgetown::Hooks.register :site, :post_write do
|
86
|
+
# Load test suite to run on exit
|
87
|
+
require "nokogiri"
|
88
|
+
Dir["test/**/*.rb"].each { |file| require_relative("../\#{file}") }
|
89
|
+
rescue LoadError
|
90
|
+
Bridgetown.logger.warn "Testing:", "To run tests, you must first run \`bundle install --with test\`"
|
91
|
+
end
|
88
92
|
end
|
89
93
|
end
|
90
94
|
RUBY
|
91
95
|
end
|
92
96
|
|
93
|
-
say_status :minitesting, "All set! To get started, look at test/test_homepage.rb and then run \`
|
97
|
+
say_status :minitesting, "All set! To get started, look at test/test_homepage.rb and then run \`bin/bridgetown test\`"
|
94
98
|
|
95
99
|
# rubocop:enable all
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
copy_file "#{TEMPLATE_PATH}/netlify.toml", "netlify.toml"
|
6
|
-
copy_file "#{TEMPLATE_PATH}/netlify.sh", "bin/netlify.sh"
|
3
|
+
copy_file in_templates_dir("netlify.toml"), "netlify.toml"
|
4
|
+
copy_file in_templates_dir("netlify.sh"), "bin/netlify.sh"
|
7
5
|
`chmod a+x ./bin/netlify.sh`
|
@@ -6,9 +6,9 @@ say_status :purgecss, "Installing PurgeCSS"
|
|
6
6
|
|
7
7
|
run "yarn add -D purgecss"
|
8
8
|
|
9
|
-
create_builder "
|
9
|
+
create_builder "purgecss.rb" do
|
10
10
|
<<~RUBY
|
11
|
-
class
|
11
|
+
class Builders::Purgecss < SiteBuilder
|
12
12
|
def build
|
13
13
|
unless config[:watch] # don't run in "watch mode"
|
14
14
|
hook :site, :post_write do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
services:
|
2
|
+
- type: web
|
3
|
+
name: <%= @render_service_name %>
|
4
|
+
env: static
|
5
|
+
buildCommand: bin/bridgetown deploy
|
6
|
+
staticPublishPath: ./output
|
7
|
+
pullRequestPreviewsEnabled: true
|
8
|
+
headers:
|
9
|
+
- path: /*
|
10
|
+
name: X-Frame-Options
|
11
|
+
value: DENY
|
12
|
+
- path: /*
|
13
|
+
name: X-XSS-Protection
|
14
|
+
value: "1; mode=block"
|
15
|
+
- path: /*
|
16
|
+
name: X-Content-Type-Options
|
17
|
+
value: "nosniff"
|
18
|
+
- path: /*
|
19
|
+
name: Strict-Transport-Security
|
20
|
+
value: "max-age=15552000; includeSubDomains"
|
21
|
+
- path: /*
|
22
|
+
name: Referrer-Policy
|
23
|
+
value: "no-referrer-when-downgrade"
|
24
|
+
- path: /*
|
25
|
+
name: Cache-Control
|
26
|
+
value: "public, max-age=86400, s-max-age=86400"
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
# rubocop:disable all
|
4
4
|
|
5
|
-
TEMPLATE_PATH = File.expand_path("./tailwindcss", __dir__)
|
6
|
-
|
7
5
|
unless File.exist?("postcss.config.js")
|
8
6
|
error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."
|
9
7
|
|
@@ -19,16 +17,16 @@ return unless confirm.casecmp?("Y")
|
|
19
17
|
run "yarn add -D tailwindcss"
|
20
18
|
run "npx tailwindcss init"
|
21
19
|
|
22
|
-
copy_file "
|
20
|
+
copy_file in_templates_dir("postcss.config.js"), "postcss.config.js", force: true
|
23
21
|
|
24
22
|
run "bundle exec bridgetown configure purgecss"
|
25
23
|
|
26
24
|
if File.exist?("frontend/styles/index.css")
|
27
25
|
prepend_to_file "frontend/styles/index.css",
|
28
|
-
File.read("
|
26
|
+
File.read(in_templates_dir("css_imports.css"))
|
29
27
|
else
|
30
28
|
say "\nPlease add the following lines to your CSS index file:"
|
31
|
-
say File.read("
|
29
|
+
say File.read(in_templates_dir("/css_imports.css"))
|
32
30
|
end
|
33
31
|
|
34
32
|
# rubocop:enable all
|
@@ -23,7 +23,7 @@ module Kramdown
|
|
23
23
|
@options ||= Options.merge(options).freeze
|
24
24
|
@parser ||= begin
|
25
25
|
parser_name = (@options[:input] || "kramdown").to_s
|
26
|
-
parser_name = parser_name[0..0].upcase + parser_name[1
|
26
|
+
parser_name = parser_name[0..0].upcase + parser_name[1..]
|
27
27
|
try_require("parser", parser_name)
|
28
28
|
|
29
29
|
if Parser.const_defined?(parser_name)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "serbea"
|
4
|
+
require "rouge/lexers/serbea"
|
5
|
+
|
6
|
+
module Bridgetown
|
7
|
+
class SerbeaView < ERBView
|
8
|
+
include Serbea::Helpers
|
9
|
+
|
10
|
+
def partial(partial_name, options = {}, &block)
|
11
|
+
options.merge!(options[:locals]) if options[:locals]
|
12
|
+
options[:content] = capture(&block) if block
|
13
|
+
|
14
|
+
partial_segments = partial_name.split("/")
|
15
|
+
partial_segments.last.sub!(%r!^!, "_")
|
16
|
+
partial_name = partial_segments.join("/")
|
17
|
+
|
18
|
+
Tilt::SerbeaTemplate.new(
|
19
|
+
site.in_source_dir(site.config[:partials_dir], "#{partial_name}.serb")
|
20
|
+
).render(self, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Converters
|
25
|
+
class SerbeaTemplates < Converter
|
26
|
+
priority :highest
|
27
|
+
input :serb
|
28
|
+
|
29
|
+
# Logic to do the Serbea content conversion.
|
30
|
+
#
|
31
|
+
# @param content [String] Content of the file (without front matter).
|
32
|
+
# @param convertible [
|
33
|
+
# Bridgetown::GeneratedPage, Bridgetown::Resource::Base, Bridgetown::Layout]
|
34
|
+
# The instantiated object which is processing the file.
|
35
|
+
#
|
36
|
+
# @return [String] The converted content.
|
37
|
+
def convert(content, convertible)
|
38
|
+
return content if convertible.data[:template_engine].to_s != "serbea"
|
39
|
+
|
40
|
+
serb_view = Bridgetown::SerbeaView.new(convertible)
|
41
|
+
|
42
|
+
serb_renderer = Tilt::SerbeaTemplate.new(convertible.relative_path) { content }
|
43
|
+
|
44
|
+
if convertible.is_a?(Bridgetown::Layout)
|
45
|
+
serb_renderer.render(serb_view) do
|
46
|
+
convertible.current_document_output
|
47
|
+
end
|
48
|
+
else
|
49
|
+
serb_renderer.render(serb_view)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def matches(ext, convertible)
|
54
|
+
if convertible.data[:template_engine].to_s == "serbea" ||
|
55
|
+
(convertible.data[:template_engine].nil? &&
|
56
|
+
@config[:template_engine].to_s == "serbea")
|
57
|
+
convertible.data[:template_engine] = "serbea"
|
58
|
+
return true
|
59
|
+
end
|
60
|
+
|
61
|
+
super(ext).tap do |ext_matches|
|
62
|
+
convertible.data[:template_engine] = "serbea" if ext_matches
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def output_ext(ext)
|
67
|
+
ext == ".serb" ? ".html" : ext
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -6,11 +6,7 @@ module Bridgetown
|
|
6
6
|
module SafeLoadFile
|
7
7
|
def safe_load_file(filename, **kwargs)
|
8
8
|
File.open(filename, "r:bom|utf-8") do |f|
|
9
|
-
|
10
|
-
safe_load f, kwargs[:permitted_classes], [], false, filename
|
11
|
-
else
|
12
|
-
safe_load f, filename: filename, **kwargs
|
13
|
-
end
|
9
|
+
safe_load f, filename: filename, **kwargs
|
14
10
|
end
|
15
11
|
end
|
16
12
|
end
|
@@ -181,7 +181,7 @@ module Bridgetown
|
|
181
181
|
sets = site.config["defaults"]
|
182
182
|
return [] unless sets.is_a?(Array)
|
183
183
|
|
184
|
-
sets.
|
184
|
+
sets.filter_map do |set|
|
185
185
|
if valid?(set)
|
186
186
|
massage_scope!(set)
|
187
187
|
# TODO: is this trip really necessary?
|
@@ -191,7 +191,7 @@ module Bridgetown
|
|
191
191
|
Bridgetown.logger.warn set.to_s
|
192
192
|
nil
|
193
193
|
end
|
194
|
-
end
|
194
|
+
end
|
195
195
|
end
|
196
196
|
|
197
197
|
# Set path to blank if not specified and alias older type to collection
|
@@ -31,9 +31,7 @@ module Bridgetown
|
|
31
31
|
raise Liquid::FileSystemError, "No such template '#{template_path}'" if found_paths.empty?
|
32
32
|
|
33
33
|
# Last path in the list wins
|
34
|
-
|
35
|
-
::File.read(found_paths.last, **site.file_read_opts)
|
36
|
-
).content
|
34
|
+
::File.read(found_paths.last, **site.file_read_opts)
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
@@ -15,7 +15,7 @@ module Bridgetown
|
|
15
15
|
|
16
16
|
# Set up Liquid file system access to components for the Render tag
|
17
17
|
Liquid::Template.file_system = LiquidRenderer::FileSystem.new(
|
18
|
-
@site.components_load_paths, "%s.liquid"
|
18
|
+
@site.config.components_load_paths, "%s.liquid"
|
19
19
|
)
|
20
20
|
Liquid::Template.file_system.site = site
|
21
21
|
|
@@ -9,40 +9,37 @@ module Bridgetown
|
|
9
9
|
extend ActiveModel::Callbacks # also extends with DescendantsTracker
|
10
10
|
define_model_callbacks :load, :save, :destroy
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
class << self
|
13
|
+
def find(id)
|
14
|
+
unless Bridgetown::Current.site
|
15
|
+
raise "A Bridgetown site must be initialized and added to Current"
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
raise "A Bridgetown site must be initialized and added to Current"
|
18
|
+
origin = origin_for_id(id)
|
19
|
+
klass_for_id(id, origin: origin).new(origin.read)
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
descendants.find do |klass|
|
29
|
-
klass.loads_id?(id)
|
30
|
-
end || self
|
31
|
-
end
|
22
|
+
def origin_for_id(id)
|
23
|
+
scheme = URI.parse(id).scheme
|
24
|
+
origin_klass = Origin.descendants.find do |klass|
|
25
|
+
klass.handle_scheme?(scheme)
|
26
|
+
end
|
32
27
|
|
33
|
-
|
34
|
-
origin_for_id(id).read
|
35
|
-
end
|
28
|
+
raise "No origin could be found for #{id}" unless origin_klass
|
36
29
|
|
37
|
-
|
38
|
-
scheme = URI.parse(id).scheme
|
39
|
-
origin_klass = Origin.descendants.find do |klass|
|
40
|
-
klass.handle_scheme?(scheme)
|
30
|
+
origin_klass.new(id)
|
41
31
|
end
|
42
32
|
|
43
|
-
|
33
|
+
def klass_for_id(id, origin: nil)
|
34
|
+
Bridgetown::Model::Base.descendants.find do |klass|
|
35
|
+
klass.will_load_id?(id, origin: origin)
|
36
|
+
end || Bridgetown::Model::Base
|
37
|
+
end
|
44
38
|
|
45
|
-
|
39
|
+
def will_load_id?(id, origin: nil)
|
40
|
+
origin ||= origin_for_id(id)
|
41
|
+
origin.verify_model?(self)
|
42
|
+
end
|
46
43
|
end
|
47
44
|
|
48
45
|
class << self
|
@@ -6,12 +6,14 @@ module Bridgetown
|
|
6
6
|
# @return [Pathname]
|
7
7
|
attr_reader :relative_path
|
8
8
|
|
9
|
-
|
10
|
-
scheme
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
class << self
|
10
|
+
def handle_scheme?(scheme)
|
11
|
+
scheme == "builder"
|
12
|
+
end
|
13
|
+
|
14
|
+
def id_for_builder_path(builder, path)
|
15
|
+
"builder://#{builder.class.name.gsub("::", ".")}/#{path}"
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
def initialize(id)
|
@@ -11,7 +11,7 @@ module Bridgetown
|
|
11
11
|
# @return [String]
|
12
12
|
attr_accessor :id
|
13
13
|
|
14
|
-
#
|
14
|
+
# You must implement in subclasses
|
15
15
|
def self.handle_scheme?(_scheme)
|
16
16
|
false
|
17
17
|
end
|
@@ -20,6 +20,15 @@ module Bridgetown
|
|
20
20
|
self.id = id
|
21
21
|
end
|
22
22
|
|
23
|
+
# You can override in subclass
|
24
|
+
def verify_model?(klass)
|
25
|
+
collection_name = URI.parse(id).host.chomp(".collection")
|
26
|
+
|
27
|
+
return klass.collection_name.to_s == collection_name if klass.respond_to?(:collection_name)
|
28
|
+
|
29
|
+
klass.name == ActiveSupport::Inflector.classify(collection_name)
|
30
|
+
end
|
31
|
+
|
23
32
|
def read
|
24
33
|
raise "Implement #read in a subclass of Bridgetown::Model::Origin"
|
25
34
|
end
|
@@ -22,7 +22,7 @@ module Bridgetown
|
|
22
22
|
|
23
23
|
def relative_path
|
24
24
|
@relative_path ||= Pathname.new(
|
25
|
-
Addressable::URI.unescape(url.path.delete_prefix("/")).split("/")[1
|
25
|
+
Addressable::URI.unescape(url.path.delete_prefix("/")).split("/")[1..].join("/")
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
@@ -5,7 +5,7 @@ module Bridgetown
|
|
5
5
|
PLUGINS_GROUP = :bridgetown_plugins
|
6
6
|
YARN_DEPENDENCY_REGEXP = %r!(.+)@([^@]*)$!.freeze
|
7
7
|
|
8
|
-
attr_reader :site, :
|
8
|
+
attr_reader :site, :loaders_manager
|
9
9
|
|
10
10
|
@source_manifests = Set.new
|
11
11
|
@registered_plugins = Set.new
|
@@ -18,8 +18,8 @@ module Bridgetown
|
|
18
18
|
@source_manifests << source_manifest
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.new_source_manifest(*args)
|
22
|
-
add_source_manifest(Bridgetown::Plugin::SourceManifest.new(*args))
|
21
|
+
def self.new_source_manifest(*args, **kwargs)
|
22
|
+
add_source_manifest(Bridgetown::Plugin::SourceManifest.new(*args, **kwargs))
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.add_registered_plugin(gem_or_plugin_file)
|
@@ -37,15 +37,14 @@ module Bridgetown
|
|
37
37
|
# Returns nothing
|
38
38
|
def initialize(site)
|
39
39
|
@site = site
|
40
|
-
@
|
40
|
+
@loaders_manager = Bridgetown::Utils::LoadersManager.new(site.config)
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.require_from_bundler
|
44
44
|
if !ENV["BRIDGETOWN_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
|
45
45
|
require "bundler"
|
46
46
|
|
47
|
-
required_gems = Bundler.require
|
48
|
-
required_gems.select! do |dep|
|
47
|
+
required_gems = Bundler.require(PLUGINS_GROUP).select do |dep|
|
49
48
|
(dep.groups & [PLUGINS_GROUP]).any? && dep.should_include?
|
50
49
|
end
|
51
50
|
|
@@ -133,12 +132,16 @@ module Bridgetown
|
|
133
132
|
sorted_plugin_files.each do |plugin_file|
|
134
133
|
self.class.add_registered_plugin plugin_file
|
135
134
|
end
|
135
|
+
next if site.config[:plugins_use_zeitwerk]
|
136
|
+
|
136
137
|
Bridgetown::Utils::RequireGems.require_with_graceful_fail(sorted_plugin_files)
|
137
138
|
end
|
138
139
|
end
|
139
140
|
|
140
141
|
# Reload .rb plugin files via the watcher
|
141
142
|
def reload_plugin_files
|
143
|
+
return if site.config[:plugins_use_zeitwerk]
|
144
|
+
|
142
145
|
plugins_path.each do |plugin_search_path|
|
143
146
|
plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
|
144
147
|
Array(plugin_files).each do |name|
|
@@ -159,35 +162,5 @@ module Bridgetown
|
|
159
162
|
Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
|
160
163
|
end
|
161
164
|
end
|
162
|
-
|
163
|
-
def setup_component_loaders
|
164
|
-
unless @component_loaders.keys.empty?
|
165
|
-
@component_loaders.each do |_path, loader|
|
166
|
-
loader.unload
|
167
|
-
end
|
168
|
-
@component_loaders = {}
|
169
|
-
end
|
170
|
-
|
171
|
-
# Because "first constant wins" in Zeitwerk, we need to load the local
|
172
|
-
# source components _before_ we load any from plugins
|
173
|
-
site.components_load_paths.reverse_each do |load_path|
|
174
|
-
next unless Dir.exist? load_path
|
175
|
-
|
176
|
-
begin
|
177
|
-
@component_loaders[load_path] = Zeitwerk::Loader.new
|
178
|
-
@component_loaders[load_path].push_dir(load_path)
|
179
|
-
@component_loaders[load_path].enable_reloading if load_path.start_with?(site.root_dir)
|
180
|
-
@component_loaders[load_path].ignore(File.join(load_path, "**", "*.js.rb"))
|
181
|
-
@component_loaders[load_path].setup
|
182
|
-
rescue Zeitwerk::Error # rubocop:disable Lint/SuppressedException
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def reload_component_loaders
|
188
|
-
@component_loaders.each do |path, loader|
|
189
|
-
loader.reload if path.start_with?(site.root_dir)
|
190
|
-
end
|
191
|
-
end
|
192
165
|
end
|
193
166
|
end
|