bridgetown-core 0.21.3 → 1.0.0.alpha3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +35 -0
  3. data/Rakefile +5 -5
  4. data/bin/bridgetown +2 -0
  5. data/bridgetown-core.gemspec +3 -0
  6. data/lib/bridgetown-core/cache.rb +3 -5
  7. data/lib/bridgetown-core/cleaner.rb +2 -10
  8. data/lib/bridgetown-core/collection.rb +62 -86
  9. data/lib/bridgetown-core/commands/base.rb +62 -2
  10. data/lib/bridgetown-core/commands/build.rb +33 -12
  11. data/lib/bridgetown-core/commands/concerns/actions.rb +2 -2
  12. data/lib/bridgetown-core/commands/concerns/build_options.rb +3 -10
  13. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +3 -1
  14. data/lib/bridgetown-core/commands/console.rb +3 -3
  15. data/lib/bridgetown-core/commands/doctor.rb +13 -11
  16. data/lib/bridgetown-core/commands/new.rb +14 -6
  17. data/lib/bridgetown-core/commands/plugins.rb +8 -11
  18. data/lib/bridgetown-core/commands/serve/servlet.rb +4 -4
  19. data/lib/bridgetown-core/commands/serve.rb +37 -37
  20. data/lib/bridgetown-core/commands/start.rb +106 -0
  21. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +2 -2
  22. data/lib/bridgetown-core/commands/webpack.rb +1 -1
  23. data/lib/bridgetown-core/component.rb +2 -6
  24. data/lib/bridgetown-core/concerns/liquid_renderable.rb +2 -2
  25. data/lib/bridgetown-core/concerns/site/configurable.rb +1 -13
  26. data/lib/bridgetown-core/concerns/site/content.rb +17 -118
  27. data/lib/bridgetown-core/concerns/site/extensible.rb +3 -4
  28. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -1
  29. data/lib/bridgetown-core/concerns/site/processable.rb +9 -20
  30. data/lib/bridgetown-core/concerns/site/renderable.rb +19 -30
  31. data/lib/bridgetown-core/concerns/site/ssr.rb +53 -0
  32. data/lib/bridgetown-core/concerns/site/writable.rb +6 -9
  33. data/lib/bridgetown-core/configuration.rb +19 -48
  34. data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
  35. data/lib/bridgetown-core/configurations/turbo.rb +1 -1
  36. data/lib/bridgetown-core/converter.rb +1 -0
  37. data/lib/bridgetown-core/converters/erb_templates.rb +8 -5
  38. data/lib/bridgetown-core/converters/liquid_templates.rb +5 -2
  39. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  40. data/lib/bridgetown-core/converters/smartypants.rb +1 -0
  41. data/lib/bridgetown-core/current.rb +4 -0
  42. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  43. data/lib/bridgetown-core/drops/drop.rb +4 -4
  44. data/lib/bridgetown-core/drops/generated_page_drop.rb +23 -0
  45. data/lib/bridgetown-core/drops/resource_drop.rb +3 -3
  46. data/lib/bridgetown-core/drops/site_drop.rb +3 -47
  47. data/lib/bridgetown-core/entry_filter.rb +1 -0
  48. data/lib/bridgetown-core/errors.rb +0 -2
  49. data/lib/bridgetown-core/filters/url_filters.rb +2 -0
  50. data/lib/bridgetown-core/filters.rb +11 -12
  51. data/lib/bridgetown-core/frontmatter_defaults.rb +44 -82
  52. data/lib/bridgetown-core/{page.rb → generated_page.rb} +34 -60
  53. data/lib/bridgetown-core/generators/prototype_generator.rb +49 -61
  54. data/lib/bridgetown-core/helpers.rb +8 -3
  55. data/lib/bridgetown-core/hooks.rb +2 -2
  56. data/lib/bridgetown-core/layout.rb +15 -4
  57. data/lib/bridgetown-core/liquid_renderer.rb +1 -3
  58. data/lib/bridgetown-core/log_adapter.rb +1 -1
  59. data/lib/bridgetown-core/log_writer.rb +7 -1
  60. data/lib/bridgetown-core/model/base.rb +12 -4
  61. data/lib/bridgetown-core/model/builder_origin.rb +23 -11
  62. data/lib/bridgetown-core/model/origin.rb +3 -0
  63. data/lib/bridgetown-core/model/plugin_origin.rb +34 -0
  64. data/lib/bridgetown-core/model/repo_origin.rb +1 -1
  65. data/lib/bridgetown-core/plugin_manager.rb +10 -10
  66. data/lib/bridgetown-core/publisher.rb +1 -1
  67. data/lib/bridgetown-core/rack/boot.rb +47 -0
  68. data/lib/bridgetown-core/rack/logger.rb +22 -0
  69. data/lib/bridgetown-core/rack/roda.rb +66 -0
  70. data/lib/bridgetown-core/rack/routes.rb +88 -0
  71. data/lib/bridgetown-core/rack/static_indexes.rb +30 -0
  72. data/lib/bridgetown-core/reader.rb +20 -47
  73. data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
  74. data/lib/bridgetown-core/readers/plugin_content_reader.rb +8 -7
  75. data/lib/bridgetown-core/renderer.rb +2 -12
  76. data/lib/bridgetown-core/resource/base.rb +34 -11
  77. data/lib/bridgetown-core/resource/permalink_processor.rb +23 -12
  78. data/lib/bridgetown-core/resource/relations.rb +2 -3
  79. data/lib/bridgetown-core/resource/taxonomy_term.rb +1 -5
  80. data/lib/bridgetown-core/resource/transformer.rb +8 -6
  81. data/lib/bridgetown-core/ruby_template_view.rb +6 -8
  82. data/lib/bridgetown-core/site.rb +4 -8
  83. data/lib/bridgetown-core/static_file.rb +14 -21
  84. data/lib/bridgetown-core/tags/find.rb +6 -6
  85. data/lib/bridgetown-core/tags/highlight.rb +5 -5
  86. data/lib/bridgetown-core/tags/include.rb +22 -32
  87. data/lib/bridgetown-core/tags/link.rb +4 -0
  88. data/lib/bridgetown-core/tags/live_reload_dev_js.rb +13 -0
  89. data/lib/bridgetown-core/tags/post_url.rb +9 -14
  90. data/lib/bridgetown-core/tags/render_content.rb +2 -2
  91. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +54 -0
  92. data/lib/bridgetown-core/url.rb +5 -4
  93. data/lib/bridgetown-core/utils/aux.rb +57 -0
  94. data/lib/bridgetown-core/utils/ruby_exec.rb +3 -45
  95. data/lib/bridgetown-core/utils/ruby_front_matter.rb +22 -7
  96. data/lib/bridgetown-core/utils.rb +60 -33
  97. data/lib/bridgetown-core/version.rb +2 -2
  98. data/lib/bridgetown-core/watcher.rb +4 -6
  99. data/lib/bridgetown-core.rb +16 -23
  100. data/lib/site_template/Gemfile.erb +6 -2
  101. data/lib/site_template/README.md +6 -6
  102. data/lib/site_template/Rakefile +49 -0
  103. data/lib/site_template/bridgetown.config.yml +2 -3
  104. data/lib/site_template/config/puma.rb +27 -0
  105. data/lib/site_template/config.ru +7 -0
  106. data/lib/site_template/frontend/javascript/index.js.erb +3 -3
  107. data/lib/site_template/package.json.erb +7 -12
  108. data/lib/site_template/server/roda_app.rb +22 -0
  109. data/lib/site_template/server/routes/hello.rb.sample +10 -0
  110. data/lib/site_template/src/_components/head.liquid +2 -1
  111. data/lib/site_template/src/about.md +0 -1
  112. data/lib/site_template/src/posts.md +2 -3
  113. metadata +63 -18
  114. data/lib/bridgetown-core/concerns/data_accessible.rb +0 -20
  115. data/lib/bridgetown-core/concerns/validatable.rb +0 -56
  116. data/lib/bridgetown-core/document.rb +0 -437
  117. data/lib/bridgetown-core/drops/document_drop.rb +0 -80
  118. data/lib/bridgetown-core/drops/excerpt_drop.rb +0 -19
  119. data/lib/bridgetown-core/drops/page_drop.rb +0 -18
  120. data/lib/bridgetown-core/excerpt.rb +0 -200
  121. data/lib/bridgetown-core/readers/data_reader.rb +0 -89
  122. data/lib/bridgetown-core/readers/page_reader.rb +0 -26
  123. data/lib/bridgetown-core/readers/post_reader.rb +0 -109
  124. data/lib/bridgetown-core/regenerator.rb +0 -202
  125. data/lib/bridgetown-core/related_posts.rb +0 -55
  126. data/lib/site_template/config/.keep +0 -0
  127. data/lib/site_template/start.js +0 -17
  128. data/lib/site_template/sync.js +0 -35
@@ -104,7 +104,7 @@ module Bridgetown
104
104
 
105
105
  # check matching version number is see if it's already installed
106
106
  if package_json["dependencies"]
107
- current_version = package_json["dependencies"].dig(yarn_dependency.first)
107
+ current_version = package_json["dependencies"][yarn_dependency.first]
108
108
  package_requires_updating?(current_version, yarn_dependency.last)
109
109
  else
110
110
  true
@@ -112,7 +112,7 @@ module Bridgetown
112
112
  end
113
113
 
114
114
  def self.package_requires_updating?(current_version, dep_version)
115
- current_version.nil? || current_version != dep_version && !current_version.include?("/")
115
+ current_version.nil? || (current_version != dep_version && !current_version.include?("/"))
116
116
  end
117
117
 
118
118
  # Require all .rb files
@@ -160,7 +160,6 @@ module Bridgetown
160
160
  end
161
161
  end
162
162
 
163
- # rubocop:disable Metrics/AbcSize
164
163
  def setup_component_loaders
165
164
  unless @component_loaders.keys.empty?
166
165
  @component_loaders.each do |_path, loader|
@@ -173,16 +172,17 @@ module Bridgetown
173
172
  # source components _before_ we load any from plugins
174
173
  site.components_load_paths.reverse_each do |load_path|
175
174
  next unless Dir.exist? load_path
176
- next if Zeitwerk::Registry.loaders.find { |loader| loader.manages?(load_path) }
177
175
 
178
- @component_loaders[load_path] = Zeitwerk::Loader.new
179
- @component_loaders[load_path].push_dir(load_path)
180
- @component_loaders[load_path].enable_reloading if load_path.start_with?(site.root_dir)
181
- @component_loaders[load_path].ignore(File.join(load_path, "**", "*.js.rb"))
182
- @component_loaders[load_path].setup
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
183
184
  end
184
185
  end
185
- # rubocop:enable Metrics/AbcSize
186
186
 
187
187
  def reload_component_loaders
188
188
  @component_loaders.each do |path, loader|
@@ -15,7 +15,7 @@ module Bridgetown
15
15
  return false unless thing.respond_to?(:date)
16
16
 
17
17
  future_allowed =
18
- thing.respond_to?(:collection) && thing.collection.metadata.future || @site.config.future
18
+ (thing.respond_to?(:collection) && thing.collection.metadata.future) || @site.config.future
19
19
  thing_time = thing.date.is_a?(Date) ? thing.date.to_time.to_i : thing.date.to_i
20
20
  !future_allowed && thing_time > @site.time.to_i
21
21
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zeitwerk"
4
+ require "roda"
5
+ require "json"
6
+ require "roda/plugins/public"
7
+
8
+ Bridgetown::Current.preloaded_configuration ||= Bridgetown.configuration
9
+
10
+ require_relative "logger"
11
+ require_relative "roda"
12
+ require_relative "routes"
13
+ require_relative "static_indexes"
14
+
15
+ module Bridgetown
16
+ module Rack
17
+ def self.boot
18
+ autoload_server_folder(root: Dir.pwd)
19
+ RodaApp.opts[:bridgetown_preloaded_config] = Bridgetown::Current.preloaded_configuration
20
+ end
21
+
22
+ def self.autoload_server_folder(root:)
23
+ server_folder = File.join(root, "server")
24
+ loader = Zeitwerk::Loader.new
25
+ loader.push_dir server_folder
26
+ loader.enable_reloading unless ENV["BRIDGETOWN_ENV"] == "production"
27
+ loader.setup
28
+ loader.eager_load
29
+ loader.do_not_eager_load(File.join(server_folder, "roda_app.rb"))
30
+
31
+ unless ENV["BRIDGETOWN_ENV"] == "production"
32
+ begin
33
+ Listen.to(server_folder) do |_modified, _added, _removed|
34
+ loader.reload
35
+ loader.eager_load
36
+ Bridgetown::Rack::Routes.reload_subclasses
37
+ end.start
38
+ # interrupt isn't handled well by the listener
39
+ rescue ThreadError # rubocop:disable Lint/SuppressedException
40
+ end
41
+ end
42
+ rescue Zeitwerk::Error
43
+ # We assume if there's an error it's because Zeitwerk already registered this folder,
44
+ # so it's fine to swallow the error
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+
5
+ module Bridgetown
6
+ module Rack
7
+ class Logger < Logger
8
+ def self.message_with_prefix(msg)
9
+ return if msg.include?("/_bridgetown/live_reload")
10
+
11
+ "\e[35m[Server]\e[0m #{msg}"
12
+ end
13
+
14
+ def initialize(*)
15
+ super
16
+ @formatter = proc do |_, _, _, msg|
17
+ self.class.message_with_prefix(msg)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack/indifferent"
4
+
5
+ class Roda
6
+ module RodaPlugins
7
+ module BridgetownSSR
8
+ def self.configure(app, _opts = {}, &block)
9
+ app.opts[:bridgetown_site] = Bridgetown::Site.start_ssr!(&block)
10
+ end
11
+ end
12
+
13
+ register_plugin :bridgetown_ssr, BridgetownSSR
14
+ end
15
+ end
16
+
17
+ module Bridgetown
18
+ module Rack
19
+ class Roda < ::Roda
20
+ plugin :hooks
21
+ plugin :common_logger, Bridgetown::Rack::Logger.new($stdout), method: :info
22
+ plugin :json
23
+ plugin :json_parser
24
+ plugin :cookies
25
+ plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
26
+ plugin :not_found do
27
+ output_folder = Bridgetown::Current.preloaded_configuration.destination
28
+ File.read(File.join(output_folder, "404.html"))
29
+ rescue Errno::ENOENT
30
+ "404 Not Found"
31
+ end
32
+ plugin :error_handler do |e|
33
+ puts "\n#{e.class} (#{e.message}):\n\n"
34
+ puts e.backtrace
35
+ output_folder = Bridgetown::Current.preloaded_configuration.destination
36
+ File.read(File.join(output_folder, "500.html"))
37
+ rescue Errno::ENOENT
38
+ "500 Internal Server Error"
39
+ end
40
+
41
+ def _roda_run_main_route(r) # rubocop:disable Naming/MethodParameterName
42
+ if self.class.opts[:bridgetown_site]
43
+ # The site had previously been initialized via the bridgetown_ssr plugin
44
+ Bridgetown::Current.site ||= self.class.opts[:bridgetown_site]
45
+ end
46
+ Bridgetown::Current.preloaded_configuration ||=
47
+ self.class.opts[:bridgetown_preloaded_config]
48
+
49
+ r.public
50
+
51
+ r.root do
52
+ output_folder = Bridgetown::Current.preloaded_configuration.destination
53
+ File.read(File.join(output_folder, "index.html"))
54
+ end
55
+
56
+ super
57
+ end
58
+
59
+ # Helper shorthand for Bridgetown::Current.site
60
+ # @return [Bridgetown::Site]
61
+ def bridgetown_site
62
+ Bridgetown::Current.site
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Rack
5
+ class Routes
6
+ class << self
7
+ attr_accessor :tracked_subclasses, :router_block
8
+
9
+ def inherited(base)
10
+ Bridgetown::Rack::Routes.track_subclass base
11
+ super
12
+ end
13
+
14
+ def track_subclass(klass)
15
+ Bridgetown::Rack::Routes.tracked_subclasses ||= {}
16
+ Bridgetown::Rack::Routes.tracked_subclasses[klass.name] = klass
17
+ end
18
+
19
+ def reload_subclasses
20
+ Bridgetown::Rack::Routes.tracked_subclasses&.each_key do |klassname|
21
+ Kernel.const_get(klassname)
22
+ rescue NameError
23
+ Bridgetown::Rack::Routes.tracked_subclasses.delete klassname
24
+ end
25
+ end
26
+
27
+ def route(&block)
28
+ self.router_block = block
29
+ end
30
+
31
+ def merge(roda_app)
32
+ return unless router_block
33
+
34
+ new(roda_app).handle_routes
35
+ end
36
+
37
+ def start!(roda_app)
38
+ if Bridgetown.env.development? &&
39
+ !Bridgetown::Current.preloaded_configuration.skip_live_reload
40
+ setup_live_reload roda_app.request
41
+ end
42
+
43
+ Bridgetown::Rack::Routes.tracked_subclasses&.each_value do |klass|
44
+ klass.merge roda_app
45
+ end
46
+
47
+ if defined?(Bridgetown::Routes::RodaRouter)
48
+ Bridgetown::Routes::RodaRouter.start!(roda_app)
49
+ end
50
+
51
+ nil
52
+ end
53
+
54
+ def setup_live_reload(request)
55
+ request.get "_bridgetown/live_reload" do
56
+ {
57
+ last_mod: File.stat(
58
+ File.join(Bridgetown::Current.preloaded_configuration.destination, "index.html")
59
+ ).mtime.to_i,
60
+ }
61
+ rescue StandardError => e
62
+ { last_mod: 0, error: e.message }
63
+ end
64
+ end
65
+ end
66
+
67
+ def initialize(roda_app)
68
+ @_roda_app = roda_app
69
+ end
70
+
71
+ def handle_routes
72
+ instance_exec(@_roda_app.request, &self.class.router_block)
73
+ end
74
+
75
+ ruby2_keywords def method_missing(method_name, *args, &block)
76
+ if @_roda_app.respond_to?(method_name.to_sym)
77
+ @_roda_app.send method_name.to_sym, *args, &block
78
+ else
79
+ super
80
+ end
81
+ end
82
+
83
+ def respond_to_missing?(method_name, include_private = false)
84
+ @_roda_app.respond_to?(method_name.to_sym, include_private) || super
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "roda/plugins/public"
4
+
5
+ Roda::RodaPlugins::Public::RequestMethods.module_eval do
6
+ SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact) # rubocop:disable Lint/ConstantDefinitionInBlock
7
+ def public_path_segments(path) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
8
+ segments = []
9
+
10
+ path.split(SPLIT).each do |seg|
11
+ next if seg.empty? || seg == "."
12
+
13
+ seg == ".." ? segments.pop : segments << seg
14
+ end
15
+
16
+ path = ::File.join(roda_class.opts[:public_root], *segments)
17
+ unless ::File.file?(path)
18
+ path = ::File.join(path, "index.html")
19
+ if ::File.file?(path)
20
+ segments << "index.html"
21
+ else
22
+ segments[segments.size - 1] = "#{segments.last}.html"
23
+ end
24
+ end
25
+
26
+ segments
27
+ rescue IndexError
28
+ nil
29
+ end
30
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Bridgetown
4
4
  class Reader
5
+ # @return [Bridgetown::Site]
5
6
  attr_reader :site
6
7
 
7
8
  def initialize(site)
@@ -11,34 +12,34 @@ module Bridgetown
11
12
  # Read Site data from disk and load it into internal data structures.
12
13
  #
13
14
  # Returns nothing.
14
- def read # rubocop:todo Metrics/AbcSize
15
+ def read
15
16
  site.defaults_reader.read
16
- site.layouts = LayoutReader.new(site).read
17
+ read_layouts
17
18
  read_directories
18
- read_included_excludes
19
+ read_includes
19
20
  sort_files!
21
+ site.data = site.collections.data.read.merge_data_resources
20
22
  read_collections
21
- site.data = if site.uses_resource?
22
- site.collections.data.merge_data_resources
23
- else
24
- DataReader.new(site).read
25
- end
26
- Bridgetown::PluginManager.source_manifests.map(&:content).compact.each do |plugin_content_dir|
27
- PluginContentReader.new(site, plugin_content_dir).read
23
+ Bridgetown::PluginManager.source_manifests.select(&:content).each do |manifest|
24
+ PluginContentReader.new(site, manifest).read
28
25
  end
29
26
  end
30
27
 
28
+ def read_layouts
29
+ site.layouts = LayoutReader.new(site).read
30
+ end
31
+
31
32
  def read_collections
32
33
  site.collections.each_value do |collection|
33
- collection.read unless !site.uses_resource? &&
34
- collection.legacy_reader?
34
+ next if collection.data?
35
+
36
+ collection.read
35
37
  end
36
38
  end
37
39
 
38
- # Sorts posts, pages, and static files.
40
+ # Sorts generated pages and static files.
39
41
  def sort_files!
40
- site.collections.each_value { |c| c.docs.sort! }
41
- site.pages.sort_by!(&:name)
42
+ site.generated_pages.sort_by!(&:name)
42
43
  site.static_files.sort_by!(&:relative_path)
43
44
  end
44
45
 
@@ -70,24 +71,11 @@ module Bridgetown
70
71
  end
71
72
  end
72
73
 
73
- retrieve_posts(dir) unless site.uses_resource?
74
74
  retrieve_dirs(base, dir, dot_dirs)
75
75
  retrieve_pages(dir, dot_pages)
76
76
  retrieve_static_files(dir, dot_static_files)
77
77
  end
78
78
 
79
- # Retrieves all the posts(posts) from the given directory
80
- # and add them to the site and sort them.
81
- #
82
- # dir - The String representing the directory to retrieve the posts from.
83
- #
84
- # Returns nothing.
85
- def retrieve_posts(dir)
86
- return if outside_configured_directory?(dir)
87
-
88
- post_reader.read_posts(dir)
89
- end
90
-
91
79
  # Recursively traverse directories with the read_directories function.
92
80
  #
93
81
  # base - The String representing the site's base directory.
@@ -111,14 +99,9 @@ module Bridgetown
111
99
  #
112
100
  # Returns nothing.
113
101
  def retrieve_pages(dir, dot_pages)
114
- if site.uses_resource?
115
- dot_pages.each do |page_path|
116
- site.collections.pages.read_resource(site.in_source_dir(dir, page_path))
117
- end
118
- return
102
+ dot_pages.each do |page_path|
103
+ site.collections.pages.read_resource(site.in_source_dir(dir, page_path))
119
104
  end
120
-
121
- site.pages.concat(PageReader.new(site, dir).read(dot_pages))
122
105
  end
123
106
 
124
107
  # Retrieve all the static files from the current directory,
@@ -176,13 +159,7 @@ module Bridgetown
176
159
  !collections_dir.empty? && !dir.start_with?("/#{collections_dir}")
177
160
  end
178
161
 
179
- # Create a single PostReader instance to retrieve posts from all valid
180
- # directories in current site.
181
- def post_reader
182
- @post_reader ||= PostReader.new(site)
183
- end
184
-
185
- def read_included_excludes
162
+ def read_includes
186
163
  site.config.include.each do |entry|
187
164
  next if entry == ".htaccess"
188
165
 
@@ -196,11 +173,7 @@ module Bridgetown
196
173
  def read_included_file(entry_path)
197
174
  dir = File.dirname(entry_path).sub(site.source, "")
198
175
  file = Array(File.basename(entry_path))
199
- if Utils.has_yaml_header?(entry_path)
200
- site.pages.concat(PageReader.new(site, dir).read(file))
201
- else
202
- retrieve_static_files(dir, file)
203
- end
176
+ retrieve_static_files(dir, file)
204
177
  end
205
178
  end
206
179
  end
@@ -47,10 +47,10 @@ module Bridgetown
47
47
  Layout.label_for_file(file)
48
48
  end
49
49
 
50
- def within(directory)
50
+ def within(directory, &block)
51
51
  return unless File.exist?(directory)
52
52
 
53
- Dir.chdir(directory) { yield }
53
+ Dir.chdir(directory, &block)
54
54
  end
55
55
  end
56
56
  end
@@ -2,11 +2,14 @@
2
2
 
3
3
  module Bridgetown
4
4
  class PluginContentReader
5
- attr_reader :site, :content_dir
5
+ attr_reader :site, :manifest, :content_dir
6
6
 
7
- def initialize(site, plugin_content_dir)
7
+ # @param site [Bridgetown::Site]
8
+ # @param manifest [Bridgetown::Plugin::SourceManifest]
9
+ def initialize(site, manifest)
8
10
  @site = site
9
- @content_dir = plugin_content_dir
11
+ @manifest = manifest
12
+ @content_dir = manifest.content
10
13
  @content_files = Set.new
11
14
  end
12
15
 
@@ -28,13 +31,11 @@ module Bridgetown
28
31
  dir = File.dirname(path.sub("#{content_dir}/", ""))
29
32
  name = File.basename(path)
30
33
 
31
- @content_files << if Utils.has_yaml_header?(path)
32
- Bridgetown::Page.new(site, content_dir, dir, name, from_plugin: true)
34
+ @content_files << if Utils.has_yaml_header?(path) || Utils.has_rbfm_header?(path)
35
+ site.collections.pages.read_resource(path, manifest: manifest)
33
36
  else
34
37
  Bridgetown::StaticFile.new(site, content_dir, "/#{dir}", name)
35
38
  end
36
-
37
- add_to(site.pages, Bridgetown::Page)
38
39
  add_to(site.static_files, Bridgetown::StaticFile)
39
40
  end
40
41
 
@@ -65,7 +65,7 @@ module Bridgetown
65
65
  def execute_inline_ruby!
66
66
  return unless site.config.should_execute_inline_ruby?
67
67
 
68
- Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document, self)
68
+ Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document)
69
69
  end
70
70
 
71
71
  # Convert the document using the converters which match this renderer's document.
@@ -98,7 +98,6 @@ module Bridgetown
98
98
 
99
99
  while layout
100
100
  output = render_layout(output, layout)
101
- add_regenerator_dependencies(layout)
102
101
 
103
102
  next unless (layout = site.layouts[layout.data["layout"]])
104
103
  break if used.include?(layout)
@@ -120,7 +119,7 @@ module Bridgetown
120
119
  !(document.is_a? Bridgetown::Excerpt)
121
120
 
122
121
  Bridgetown.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
123
- "in #{document.relative_path} does not exist."
122
+ "in #{document.relative_path} does not exist."
124
123
  end
125
124
 
126
125
  # Render layout content into document.output
@@ -144,15 +143,6 @@ module Bridgetown
144
143
  end
145
144
  end
146
145
 
147
- def add_regenerator_dependencies(layout)
148
- return unless document.write?
149
-
150
- site.regenerator.add_dependency(
151
- site.in_source_dir(document.path),
152
- layout.path
153
- )
154
- end
155
-
156
146
  def permalink_ext
157
147
  document_permalink = document.permalink
158
148
  if document_permalink &&
@@ -53,7 +53,7 @@ module Bridgetown
53
53
  @layout = site.layouts[data.layout].tap do |layout|
54
54
  unless layout
55
55
  Bridgetown.logger.warn "Resource:", "Layout '#{data.layout}' " \
56
- "requested via #{relative_path} does not exist."
56
+ "requested via #{relative_path} does not exist."
57
57
  end
58
58
  end
59
59
  end
@@ -116,6 +116,8 @@ module Bridgetown
116
116
 
117
117
  def transform!
118
118
  transformer.process! unless collection.data?
119
+
120
+ self
119
121
  end
120
122
 
121
123
  def trigger_hooks(hook_name, *args)
@@ -261,19 +263,18 @@ module Bridgetown
261
263
  "#<#{self.class} #{id}>"
262
264
  end
263
265
 
264
- # Compare this document against another document.
265
- # Comparison is a comparison between the 2 paths of the documents.
266
+ # Compare this resource against another resource.
267
+ # Comparison is a comparison between the 2 dates or paths of the resources.
266
268
  #
267
- # Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
268
- # equal or greater than the other doc's path. See String#<=> for more details.
269
+ # @return [Integer] -1, 0, or +1
269
270
  def <=>(other) # rubocop:todo Metrics/AbcSize
270
271
  return nil unless other.respond_to?(:data)
271
272
 
272
- if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
273
- return data.date.to_datetime <=> other.data.date.to_datetime
274
- end
273
+ cmp = if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
274
+ data.date.to_datetime <=> other.data.date.to_datetime
275
+ end
275
276
 
276
- cmp = data["date"] <=> other.data["date"]
277
+ cmp = data["date"] <=> other.data["date"] if cmp.nil?
277
278
  cmp = path <=> other.path if cmp.nil? || cmp.zero?
278
279
  cmp
279
280
  end
@@ -292,7 +293,9 @@ module Bridgetown
292
293
 
293
294
  private
294
295
 
295
- def ensure_default_data
296
+ def ensure_default_data # rubocop:todo Metrics/AbcSize
297
+ determine_locale
298
+
296
299
  slug = if matches = relative_path.to_s.match(DATE_FILENAME_MATCHER) # rubocop:disable Lint/AssignmentInCondition
297
300
  set_date_from_string(matches[1]) unless data.date
298
301
  matches[2]
@@ -300,6 +303,8 @@ module Bridgetown
300
303
  basename_without_ext
301
304
  end
302
305
 
306
+ slug.chomp!(".#{data.locale}") if data.locale && slug.ends_with?(".#{data.locale}")
307
+
303
308
  data.slug ||= slug
304
309
  data.title ||= Bridgetown::Utils.titleize_slug(slug)
305
310
  end
@@ -309,7 +314,7 @@ module Bridgetown
309
314
 
310
315
  data.date = Bridgetown::Utils.parse_date(
311
316
  new_date,
312
- "Document '#{relative_path}' does not have a valid date in the #{model}."
317
+ "Resource '#{relative_path}' does not have a valid date."
313
318
  )
314
319
  end
315
320
 
@@ -332,6 +337,24 @@ module Bridgetown
332
337
  end
333
338
  end
334
339
 
340
+ def determine_locale # rubocop:todo Metrics/AbcSize
341
+ unless data.locale
342
+ data.locale = locale_from_alt_data_or_filename.presence || site.config.default_locale
343
+ end
344
+
345
+ return unless data.locale_overrides.is_a?(Hash) && data.locale_overrides&.key?(data.locale)
346
+
347
+ data.merge!(data.locale_overrides[data.locale])
348
+ end
349
+
350
+ # Look for alternative front matter or look at the filename pattern: slug.locale.ext
351
+ def locale_from_alt_data_or_filename
352
+ found_locale = data.language || data.lang || basename_without_ext.split(".")[1..-1].last
353
+ return unless found_locale && site.config.available_locales.include?(found_locale.to_sym)
354
+
355
+ found_locale
356
+ end
357
+
335
358
  def format_url(url)
336
359
  url.to_s.sub(%r{index\.html?$}, "").sub(%r{\.html?$}, "")
337
360
  end