bridgetown-core 1.0.0.alpha6 → 1.0.0.alpha10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/bin/bridgetown +8 -1
  4. data/bridgetown-core.gemspec +3 -3
  5. data/lib/bridgetown-core/cache.rb +1 -1
  6. data/lib/bridgetown-core/collection.rb +1 -1
  7. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +7 -0
  8. data/lib/bridgetown-core/commands/configure.rb +7 -0
  9. data/lib/bridgetown-core/commands/console.rb +38 -12
  10. data/lib/bridgetown-core/commands/doctor.rb +8 -5
  11. data/lib/bridgetown-core/commands/new.rb +1 -0
  12. data/lib/bridgetown-core/commands/plugins.rb +1 -1
  13. data/lib/bridgetown-core/component.rb +2 -2
  14. data/lib/bridgetown-core/concerns/front_matter_importer.rb +1 -1
  15. data/lib/bridgetown-core/concerns/site/configurable.rb +6 -3
  16. data/lib/bridgetown-core/concerns/site/extensible.rb +2 -1
  17. data/lib/bridgetown-core/concerns/site/ssr.rb +38 -16
  18. data/lib/bridgetown-core/configuration.rb +77 -46
  19. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -3
  20. data/lib/bridgetown-core/configurations/cypress/cypress.json +4 -0
  21. data/lib/bridgetown-core/configurations/cypress/cypress_dir/fixtures/example.json +5 -0
  22. data/lib/bridgetown-core/configurations/cypress/cypress_dir/integration/navbar.spec.js +17 -0
  23. data/lib/bridgetown-core/configurations/cypress/cypress_dir/plugins/index.js +21 -0
  24. data/lib/bridgetown-core/configurations/cypress/cypress_dir/support/commands.js +25 -0
  25. data/lib/bridgetown-core/configurations/cypress/cypress_dir/support/index.js +20 -0
  26. data/lib/bridgetown-core/configurations/cypress/cypress_tasks +33 -0
  27. data/lib/bridgetown-core/configurations/cypress.rb +13 -0
  28. data/lib/bridgetown-core/configurations/minitesting.rb +19 -15
  29. data/lib/bridgetown-core/configurations/netlify.rb +2 -4
  30. data/lib/bridgetown-core/configurations/purgecss.rb +2 -2
  31. data/lib/bridgetown-core/configurations/render/render.yaml.erb +26 -0
  32. data/lib/bridgetown-core/configurations/render.rb +6 -0
  33. data/lib/bridgetown-core/configurations/tailwindcss.rb +3 -5
  34. data/lib/bridgetown-core/converters/erb_templates.rb +1 -1
  35. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  36. data/lib/bridgetown-core/converters/serbea_templates.rb +71 -0
  37. data/lib/bridgetown-core/core_ext/psych.rb +1 -5
  38. data/lib/bridgetown-core/frontmatter_defaults.rb +2 -2
  39. data/lib/bridgetown-core/liquid_renderer/file_system.rb +1 -3
  40. data/lib/bridgetown-core/liquid_renderer.rb +1 -1
  41. data/lib/bridgetown-core/model/base.rb +23 -26
  42. data/lib/bridgetown-core/model/builder_origin.rb +8 -6
  43. data/lib/bridgetown-core/model/origin.rb +10 -1
  44. data/lib/bridgetown-core/model/plugin_origin.rb +1 -1
  45. data/lib/bridgetown-core/plugin_manager.rb +9 -36
  46. data/lib/bridgetown-core/rack/boot.rb +46 -23
  47. data/lib/bridgetown-core/rack/roda.rb +2 -1
  48. data/lib/bridgetown-core/rack/routes.rb +2 -2
  49. data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
  50. data/lib/bridgetown-core/readers/plugin_content_reader.rb +1 -1
  51. data/lib/bridgetown-core/renderer.rb +2 -2
  52. data/lib/bridgetown-core/resource/base.rb +3 -3
  53. data/lib/bridgetown-core/resource/relations.rb +1 -1
  54. data/lib/bridgetown-core/resource/taxonomy_term.rb +2 -2
  55. data/lib/bridgetown-core/resource/taxonomy_type.rb +2 -2
  56. data/lib/bridgetown-core/ruby_template_view.rb +2 -2
  57. data/lib/bridgetown-core/site.rb +15 -5
  58. data/lib/bridgetown-core/utils/loaders_manager.rb +83 -0
  59. data/lib/bridgetown-core/utils.rb +13 -14
  60. data/lib/bridgetown-core/version.rb +1 -1
  61. data/lib/bridgetown-core/watcher.rb +16 -7
  62. data/lib/bridgetown-core/yaml_parser.rb +1 -5
  63. data/lib/bridgetown-core.rb +0 -1
  64. data/lib/site_template/README.md +1 -1
  65. data/lib/site_template/Rakefile +3 -3
  66. 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, package.json scripts, and examples"
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
- unless Bridgetown.environment == "development"
82
- Bridgetown::Hooks.register :site, :post_write do
83
- # Load test suite to run on exit
84
- require "nokogiri"
85
- Dir["test/**/*.rb"].each { |file| require_relative("../\#{file}") }
86
- rescue LoadError
87
- Bridgetown.logger.warn "Testing:", "To run tests, you must first run \`bundle install --with test\`"
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 \`yarn test\`"
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
- TEMPLATE_PATH = File.expand_path("./netlify", __dir__)
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 "purgecss_builder.rb" do
9
+ create_builder "purgecss.rb" do
10
10
  <<~RUBY
11
- class PurgeCSS < SiteBuilder
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"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ @render_service_name = ask "What would like to call your Render service?"
4
+ template in_templates_dir("render.yaml.erb"), "render.yaml"
5
+
6
+ say "All done. Just create a new blueprint from the Render dashboard and connect this repo."
@@ -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 "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js", force: true
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("#{TEMPLATE_PATH}/css_imports.css")
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("#{TEMPLATE_PATH}/css_imports.css")
29
+ say File.read(in_templates_dir("/css_imports.css"))
32
30
  end
33
31
 
34
32
  # rubocop:enable all
@@ -38,7 +38,7 @@ module Bridgetown
38
38
  return if text.empty?
39
39
 
40
40
  src << bufvar << ".safe_append='"
41
- src << text.gsub(%r{['\\]}, '\\\\\&') # rubocop:disable Style/StringLiterals
41
+ src << text.gsub(%r{['\\]}, '\\\\\&')
42
42
  src << "'.freeze;"
43
43
  end
44
44
 
@@ -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..-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
- if RUBY_VERSION.start_with?("2.5")
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.map do |set|
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.compact
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
- LiquidComponent.parse(
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
- def self.loads_id?(id)
13
- name == ActiveSupport::Inflector.classify(
14
- URI.parse(id).host.chomp(".collection")
15
- )
16
- end
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
- def self.find(id)
19
- unless Bridgetown::Current.site
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
- model_klass = klass_for_id(id)
24
- model_klass.new(read_data_for_id(id))
25
- end
26
-
27
- def self.klass_for_id(id)
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
- def self.read_data_for_id(id)
34
- origin_for_id(id).read
35
- end
28
+ raise "No origin could be found for #{id}" unless origin_klass
36
29
 
37
- def self.origin_for_id(id)
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
- raise "No origin could be found for #{id}" unless origin_klass
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
- origin_klass.new(id)
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
- def self.handle_scheme?(scheme)
10
- scheme == "builder"
11
- end
12
-
13
- def self.id_for_builder_path(builder, path)
14
- "builder://#{builder.class.name.gsub("::", ".")}/#{path}"
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
- # Override in subclass
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..-1].join("/")
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, :component_loaders
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
- @component_loaders = {}
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 PLUGINS_GROUP
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