bridgetown-core 0.21.1 → 1.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bridgetown +2 -0
  3. data/bridgetown-core.gemspec +3 -0
  4. data/lib/bridgetown-core/cleaner.rb +0 -8
  5. data/lib/bridgetown-core/collection.rb +59 -81
  6. data/lib/bridgetown-core/commands/base.rb +60 -1
  7. data/lib/bridgetown-core/commands/build.rb +26 -6
  8. data/lib/bridgetown-core/commands/concerns/build_options.rb +3 -10
  9. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +3 -1
  10. data/lib/bridgetown-core/commands/doctor.rb +3 -3
  11. data/lib/bridgetown-core/commands/new.rb +9 -3
  12. data/lib/bridgetown-core/commands/plugins.rb +1 -2
  13. data/lib/bridgetown-core/commands/serve.rb +14 -12
  14. data/lib/bridgetown-core/commands/start.rb +106 -0
  15. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +2 -2
  16. data/lib/bridgetown-core/concerns/site/configurable.rb +0 -12
  17. data/lib/bridgetown-core/concerns/site/content.rb +16 -117
  18. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -1
  19. data/lib/bridgetown-core/concerns/site/processable.rb +9 -20
  20. data/lib/bridgetown-core/concerns/site/renderable.rb +19 -30
  21. data/lib/bridgetown-core/concerns/site/ssr.rb +53 -0
  22. data/lib/bridgetown-core/concerns/site/writable.rb +5 -8
  23. data/lib/bridgetown-core/configuration.rb +18 -47
  24. data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
  25. data/lib/bridgetown-core/configurations/turbo.rb +1 -1
  26. data/lib/bridgetown-core/converters/erb_templates.rb +2 -1
  27. data/lib/bridgetown-core/converters/liquid_templates.rb +3 -2
  28. data/lib/bridgetown-core/current.rb +4 -0
  29. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  30. data/lib/bridgetown-core/drops/generated_page_drop.rb +23 -0
  31. data/lib/bridgetown-core/drops/resource_drop.rb +3 -3
  32. data/lib/bridgetown-core/drops/site_drop.rb +3 -47
  33. data/lib/bridgetown-core/errors.rb +0 -2
  34. data/lib/bridgetown-core/filters/url_filters.rb +3 -1
  35. data/lib/bridgetown-core/frontmatter_defaults.rb +52 -88
  36. data/lib/bridgetown-core/{page.rb → generated_page.rb} +34 -58
  37. data/lib/bridgetown-core/generators/prototype_generator.rb +13 -24
  38. data/lib/bridgetown-core/helpers.rb +7 -2
  39. data/lib/bridgetown-core/layout.rb +15 -4
  40. data/lib/bridgetown-core/log_writer.rb +6 -0
  41. data/lib/bridgetown-core/model/base.rb +10 -2
  42. data/lib/bridgetown-core/model/builder_origin.rb +22 -10
  43. data/lib/bridgetown-core/model/origin.rb +3 -0
  44. data/lib/bridgetown-core/model/plugin_origin.rb +34 -0
  45. data/lib/bridgetown-core/model/repo_origin.rb +1 -1
  46. data/lib/bridgetown-core/plugin_manager.rb +8 -8
  47. data/lib/bridgetown-core/rack/boot.rb +47 -0
  48. data/lib/bridgetown-core/rack/logger.rb +22 -0
  49. data/lib/bridgetown-core/rack/roda.rb +66 -0
  50. data/lib/bridgetown-core/rack/routes.rb +92 -0
  51. data/lib/bridgetown-core/rack/static_indexes.rb +30 -0
  52. data/lib/bridgetown-core/reader.rb +20 -47
  53. data/lib/bridgetown-core/readers/plugin_content_reader.rb +8 -7
  54. data/lib/bridgetown-core/renderer.rb +1 -11
  55. data/lib/bridgetown-core/resource/base.rb +50 -26
  56. data/lib/bridgetown-core/resource/permalink_processor.rb +20 -10
  57. data/lib/bridgetown-core/resource/relations.rb +2 -3
  58. data/lib/bridgetown-core/resource/transformer.rb +1 -1
  59. data/lib/bridgetown-core/ruby_template_view.rb +5 -5
  60. data/lib/bridgetown-core/site.rb +4 -8
  61. data/lib/bridgetown-core/static_file.rb +10 -15
  62. data/lib/bridgetown-core/tags/include.rb +0 -13
  63. data/lib/bridgetown-core/tags/link.rb +4 -0
  64. data/lib/bridgetown-core/tags/live_reload_dev_js.rb +13 -0
  65. data/lib/bridgetown-core/tags/post_url.rb +4 -9
  66. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +54 -0
  67. data/lib/bridgetown-core/url.rb +2 -1
  68. data/lib/bridgetown-core/utils/aux.rb +57 -0
  69. data/lib/bridgetown-core/utils/ruby_exec.rb +3 -45
  70. data/lib/bridgetown-core/utils/ruby_front_matter.rb +22 -7
  71. data/lib/bridgetown-core/utils.rb +53 -24
  72. data/lib/bridgetown-core/version.rb +2 -2
  73. data/lib/bridgetown-core/watcher.rb +2 -4
  74. data/lib/bridgetown-core.rb +14 -22
  75. data/lib/site_template/Gemfile.erb +6 -2
  76. data/lib/site_template/README.md +6 -6
  77. data/lib/site_template/Rakefile +49 -0
  78. data/lib/site_template/bridgetown.config.yml +2 -3
  79. data/lib/site_template/config/puma.rb +27 -0
  80. data/lib/site_template/config.ru +7 -0
  81. data/lib/site_template/frontend/javascript/index.js.erb +3 -3
  82. data/lib/site_template/package.json.erb +8 -13
  83. data/lib/site_template/server/roda_app.rb +22 -0
  84. data/lib/site_template/server/routes/hello.rb.sample +10 -0
  85. data/lib/site_template/src/_components/head.liquid +2 -1
  86. data/lib/site_template/src/about.md +0 -1
  87. data/lib/site_template/src/posts.md +2 -3
  88. metadata +62 -18
  89. data/lib/bridgetown-core/concerns/data_accessible.rb +0 -20
  90. data/lib/bridgetown-core/concerns/validatable.rb +0 -56
  91. data/lib/bridgetown-core/document.rb +0 -437
  92. data/lib/bridgetown-core/drops/document_drop.rb +0 -80
  93. data/lib/bridgetown-core/drops/excerpt_drop.rb +0 -19
  94. data/lib/bridgetown-core/drops/page_drop.rb +0 -18
  95. data/lib/bridgetown-core/excerpt.rb +0 -200
  96. data/lib/bridgetown-core/readers/data_reader.rb +0 -89
  97. data/lib/bridgetown-core/readers/page_reader.rb +0 -26
  98. data/lib/bridgetown-core/readers/post_reader.rb +0 -109
  99. data/lib/bridgetown-core/regenerator.rb +0 -202
  100. data/lib/bridgetown-core/related_posts.rb +0 -55
  101. data/lib/site_template/config/.keep +0 -0
  102. data/lib/site_template/start.js +0 -17
  103. data/lib/site_template/sync.js +0 -35
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Rack
5
+ class Routes
6
+ class << self
7
+ attr_accessor :tracked_subclasses
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
+ attr_accessor :router_block
28
+
29
+ def route(&block)
30
+ self.router_block = block
31
+ end
32
+
33
+ def merge(roda_app)
34
+ return unless router_block
35
+
36
+ new(roda_app).handle_routes
37
+ end
38
+
39
+ def start!(roda_app)
40
+ if Bridgetown.env.development? &&
41
+ !Bridgetown::Current.preloaded_configuration.skip_live_reload
42
+ setup_live_reload roda_app.request
43
+ end
44
+
45
+ Bridgetown::Rack::Routes.tracked_subclasses&.each_value do |klass|
46
+ klass.merge roda_app
47
+ end
48
+
49
+ if defined?(Bridgetown::Routes::RodaRouter)
50
+ Bridgetown::Routes::RodaRouter.start!(roda_app)
51
+ end
52
+
53
+ nil
54
+ end
55
+
56
+ def setup_live_reload(request)
57
+ request.get "_bridgetown/live_reload" do
58
+ {
59
+ last_mod: File.stat(
60
+ File.join(Bridgetown::Current.preloaded_configuration.destination, "index.html")
61
+ ).mtime.to_i,
62
+ }
63
+ rescue StandardError => e
64
+ { last_mod: 0, error: e.message }
65
+ end
66
+ end
67
+ end
68
+
69
+ def initialize(roda_app)
70
+ @_roda_app = roda_app
71
+ end
72
+
73
+ def handle_routes
74
+ instance_exec(@_roda_app.request, &self.class.router_block)
75
+ end
76
+
77
+ # rubocop:disable Style/MissingRespondToMissing
78
+ ruby2_keywords def method_missing(method_name, *args, &block)
79
+ if @_roda_app.respond_to?(method_name.to_sym)
80
+ @_roda_app.send method_name.to_sym, *args, &block
81
+ else
82
+ super
83
+ end
84
+ end
85
+
86
+ def respond_to_missing?(method_name, include_private = false)
87
+ @_roda_app.respond_to?(method_name.to_sym, include_private) || super
88
+ end
89
+ # rubocop:enable Style/MissingRespondToMissing
90
+ end
91
+ end
92
+ 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)
7
+ def public_path_segments(path) # rubocop:disable Metrics/CyclomaticComplexity
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
@@ -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)
@@ -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 &&
@@ -30,9 +30,9 @@ module Bridgetown
30
30
  def initialize(model:)
31
31
  @model = model
32
32
  @site = model.site
33
- self.data = HashWithDotAccess::Hash.new
33
+ @data = front_matter_defaults
34
34
 
35
- trigger_hooks(:post_init)
35
+ trigger_hooks :post_init
36
36
  end
37
37
 
38
38
  # Collection associated with this resource
@@ -75,20 +75,21 @@ module Bridgetown
75
75
  @relations ||= Bridgetown::Resource::Relations.new(self)
76
76
  end
77
77
 
78
+ # Loads in any default front matter associated with the resource.
79
+ #
80
+ # @return [HashWithDotAccess::Hash]
81
+ def front_matter_defaults
82
+ site.frontmatter_defaults.all(
83
+ relative_path.to_s,
84
+ collection.label.to_sym
85
+ ).with_dot_access
86
+ end
87
+
88
+ # Merges new data into the existing data hash.
89
+ #
78
90
  # @param new_data [HashWithDotAccess::Hash]
79
91
  def data=(new_data)
80
- unless new_data.is_a?(HashWithDotAccess::Hash)
81
- raise "#{self.class} data should be of type HashWithDotAccess::Hash"
82
- end
83
-
84
- @data = new_data
85
- @data.default_proc = proc do |_, key|
86
- site.frontmatter_defaults.find(
87
- relative_path.to_s,
88
- collection.label.to_sym,
89
- key.to_s
90
- )
91
- end
92
+ @data = @data.merge(new_data)
92
93
  end
93
94
 
94
95
  # @return [Bridgetown::Resource::Base]
@@ -107,7 +108,7 @@ module Bridgetown
107
108
 
108
109
  @destination = Destination.new(self) if requires_destination?
109
110
 
110
- trigger_hooks(:post_read)
111
+ trigger_hooks :post_read
111
112
 
112
113
  self
113
114
  end
@@ -115,6 +116,8 @@ module Bridgetown
115
116
 
116
117
  def transform!
117
118
  transformer.process! unless collection.data?
119
+
120
+ self
118
121
  end
119
122
 
120
123
  def trigger_hooks(hook_name, *args)
@@ -188,7 +191,7 @@ module Bridgetown
188
191
  def summary
189
192
  return summary_extension_output if respond_to?(:summary_extension_output)
190
193
 
191
- content.to_s.strip.lines.first.to_s.strip
194
+ content.to_s.strip.lines.first.to_s.strip.html_safe
192
195
  end
193
196
 
194
197
  # @return [Hash<String, Hash<String => Bridgetown::Resource::TaxonomyType,
@@ -260,19 +263,18 @@ module Bridgetown
260
263
  "#<#{self.class} #{id}>"
261
264
  end
262
265
 
263
- # Compare this document against another document.
264
- # 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.
265
268
  #
266
- # Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
267
- # equal or greater than the other doc's path. See String#<=> for more details.
268
- def <=>(other) # rubocop:todo Metrics/AbcSize
269
+ # @return [Integer] -1, 0, or +1
270
+ def <=>(other) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity
269
271
  return nil unless other.respond_to?(:data)
270
272
 
271
- if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
272
- return data.date.to_datetime <=> other.data.date.to_datetime
273
- 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
274
276
 
275
- cmp = data["date"] <=> other.data["date"]
277
+ cmp = data["date"] <=> other.data["date"] if cmp.nil?
276
278
  cmp = path <=> other.path if cmp.nil? || cmp.zero?
277
279
  cmp
278
280
  end
@@ -292,6 +294,8 @@ module Bridgetown
292
294
  private
293
295
 
294
296
  def ensure_default_data
297
+ determine_locale
298
+
295
299
  slug = if matches = relative_path.to_s.match(DATE_FILENAME_MATCHER) # rubocop:disable Lint/AssignmentInCondition
296
300
  set_date_from_string(matches[1]) unless data.date
297
301
  matches[2]
@@ -299,6 +303,8 @@ module Bridgetown
299
303
  basename_without_ext
300
304
  end
301
305
 
306
+ slug.chomp!(".#{data.locale}") if data.locale && slug.ends_with?(".#{data.locale}")
307
+
302
308
  data.slug ||= slug
303
309
  data.title ||= Bridgetown::Utils.titleize_slug(slug)
304
310
  end
@@ -308,7 +314,7 @@ module Bridgetown
308
314
 
309
315
  data.date = Bridgetown::Utils.parse_date(
310
316
  new_date,
311
- "Document '#{relative_path}' does not have a valid date in the #{model}."
317
+ "Resource '#{relative_path}' does not have a valid date."
312
318
  )
313
319
  end
314
320
 
@@ -331,6 +337,24 @@ module Bridgetown
331
337
  end
332
338
  end
333
339
 
340
+ def determine_locale
341
+ unless data.locale
342
+ data.locale = locale_from_alt_data_or_filename.presence || site.config.default_locale
343
+ end
344
+
345
+ if data.locale_overrides&.is_a?(Hash) && data.locale_overrides&.key?(data.locale)
346
+ data.merge!(data.locale_overrides[data.locale])
347
+ end
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
+
334
358
  def format_url(url)
335
359
  url.to_s.sub(%r{index\.html?$}, "").sub(%r{\.html?$}, "")
336
360
  end
@@ -36,11 +36,10 @@ module Bridgetown
36
36
  new_url = url_segments.map do |segment|
37
37
  segment.starts_with?(":") ? process_segment(segment.sub(%r{^:}, "")) : segment
38
38
  end.select(&:present?).join("/")
39
-
40
39
  # No relative URLs should ever end in /index.html
41
40
  new_url.sub!(%r{/index$}, "") if final_ext == ".html"
42
41
 
43
- add_base_path finalize_permalink(new_url, permalink)
42
+ ensure_base_path finalize_permalink(new_url, permalink)
44
43
  end
45
44
 
46
45
  def process_segment(segment)
@@ -66,13 +65,13 @@ module Bridgetown
66
65
 
67
66
  case permalink_style.to_sym
68
67
  when :pretty
69
- "#{collection_prefix}/:categories/:year/:month/:day/:slug/"
68
+ "/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug/"
70
69
  when :pretty_ext, :date
71
- "#{collection_prefix}/:categories/:year/:month/:day/:slug.*"
70
+ "/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug.*"
72
71
  when :simple
73
- "#{collection_prefix}/:categories/:slug/"
72
+ "/:locale/#{collection_prefix}/:categories/:slug/"
74
73
  when :simple_ext
75
- "#{collection_prefix}/:categories/:slug.*"
74
+ "/:locale/#{collection_prefix}/:categories/:slug.*"
76
75
  else
77
76
  permalink_style.to_s
78
77
  end
@@ -96,7 +95,7 @@ module Bridgetown
96
95
  end
97
96
  end
98
97
 
99
- def add_base_path(permalink)
98
+ def ensure_base_path(permalink)
100
99
  if resource.site.base_path.present?
101
100
  return "#{resource.site.base_path(strip_slash_only: true)}#{permalink}"
102
101
  end
@@ -108,7 +107,16 @@ module Bridgetown
108
107
 
109
108
  # @param resource [Bridgetown::Resource::Base]
110
109
  register_placeholder :path, ->(resource) do
111
- { raw_value: resource.relative_path_basename_without_prefix }
110
+ {
111
+ raw_value: resource.relative_path_basename_without_prefix.tap do |path|
112
+ if resource.site.config["collections_dir"].present?
113
+ path.delete_prefix! "#{resource.site.config["collections_dir"]}/"
114
+ end
115
+ if resource.data.locale && path.ends_with?(".#{resource.data.locale}")
116
+ path.chomp!(".#{resource.data.locale}")
117
+ end
118
+ end,
119
+ }
112
120
  end
113
121
 
114
122
  # @param resource [Bridgetown::Resource::Base]
@@ -128,8 +136,10 @@ module Bridgetown
128
136
 
129
137
  # @param resource [Bridgetown::Resource::Base]
130
138
  register_placeholder :locale, ->(resource) do
131
- locale_data = resource.data.locale
132
- resource.site.config.available_locales.include?(locale_data) ? locale_data : nil
139
+ next nil if resource.data.locale&.to_sym == resource.site.config.default_locale
140
+
141
+ locale_data = resource.data.locale&.to_sym
142
+ resource.site.config.available_locales.include?(locale_data) ? locale_data.to_s : nil
133
143
  end
134
144
  register_placeholder :lang, placeholder_processors[:locale]
135
145
 
@@ -94,9 +94,8 @@ module Bridgetown
94
94
  # @return [Bridgetown::Resource::Base, Array<Bridgetown::Resource::Base>]
95
95
  def belongs_to_relation_for_type(type)
96
96
  if resource.data[type].is_a?(Array)
97
- other_collection_for_type(type).resources.select do |other_resource|
98
- other_resource.data.slug.in?(resource.data[type])
99
- end
97
+ other_slugs = other_collection_for_type(type).resources_by_slug
98
+ resource.data[type].map { |slug| other_slugs[slug] }.compact
100
99
  else
101
100
  other_collection_for_type(type).resources.find do |other_resource|
102
101
  other_resource.data.slug == resource.data[type]
@@ -41,7 +41,7 @@ module Bridgetown
41
41
  def execute_inline_ruby!
42
42
  return unless site.config.should_execute_inline_ruby?
43
43
 
44
- Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource, self)
44
+ Bridgetown::Utils::RubyExec.search_data_for_ruby_code(resource)
45
45
  end
46
46
 
47
47
  def inspect
@@ -62,16 +62,16 @@ module Bridgetown
62
62
  end
63
63
 
64
64
  # rubocop:disable Style/MissingRespondToMissing
65
- ruby2_keywords def method_missing(method, *args, &block)
66
- if helpers.respond_to?(method.to_sym)
67
- helpers.send method.to_sym, *args, &block
65
+ ruby2_keywords def method_missing(method_name, *args, &block)
66
+ if helpers.respond_to?(method_name.to_sym)
67
+ helpers.send method_name.to_sym, *args, &block
68
68
  else
69
69
  super
70
70
  end
71
71
  end
72
72
 
73
- def respond_to_missing?(method, include_private = false)
74
- helpers.respond_to?(method.to_sym, include_private) || super
73
+ def respond_to_missing?(method_name, include_private = false)
74
+ helpers.respond_to?(method_name.to_sym, include_private) || super
75
75
  end
76
76
  # rubocop:enable Style/MissingRespondToMissing
77
77
 
@@ -10,10 +10,11 @@ module Bridgetown
10
10
  include Localizable
11
11
  include Processable
12
12
  include Renderable
13
+ include SSR
13
14
  include Writable
14
15
 
15
16
  attr_reader :root_dir, :source, :dest, :cache_dir, :config,
16
- :regenerator, :liquid_renderer, :components_load_paths,
17
+ :liquid_renderer, :components_load_paths,
17
18
  :includes_load_paths
18
19
 
19
20
  # All files not pages/documents or structured data in the source folder
@@ -23,12 +24,8 @@ module Bridgetown
23
24
  # @return [Array<Layout>]
24
25
  attr_accessor :layouts
25
26
 
26
- # @return [Array<Page>]
27
- attr_accessor :pages
28
-
29
- # NOTE: Eventually pages will be deprecated once the Resource content engine
30
- # is default
31
- alias_method :generated_pages, :pages
27
+ # @return [Array<GeneratedPage>]
28
+ attr_accessor :generated_pages
32
29
 
33
30
  attr_accessor :permalink_style, :time, :data,
34
31
  :file_read_opts, :plugin_manager, :converters,
@@ -44,7 +41,6 @@ module Bridgetown
44
41
  @plugin_manager = PluginManager.new(self)
45
42
  @cleaner = Cleaner.new(self)
46
43
  @reader = Reader.new(self)
47
- @regenerator = Regenerator.new(self)
48
44
  @liquid_renderer = LiquidRenderer.new(self)
49
45
 
50
46
  ensure_not_in_dest
@@ -21,10 +21,11 @@ module Bridgetown
21
21
 
22
22
  # Initialize a new StaticFile.
23
23
  #
24
- # site - The Site.
25
- # base - The String path to the <source>.
26
- # dir - The String path between <source> and the file.
27
- # name - The String filename of the file.
24
+ # @param site [Bridgetown::Site]
25
+ # @param base [String] path to the <source>.
26
+ # @param dir [String] path between <source> and the file.
27
+ # @param name [String] filename of the file.
28
+ # @param collection [Bridgetown::Collection] optional collection the file is attached to
28
29
  def initialize(site, base, dir, name, collection = nil) # rubocop:disable Metrics/ParameterLists
29
30
  @site = site
30
31
  @base = base
@@ -34,13 +35,11 @@ module Bridgetown
34
35
  @relative_path = File.join(*[@dir, @name].compact)
35
36
  @extname = File.extname(@name)
36
37
  @data = @site.frontmatter_defaults.all(relative_path, type).with_dot_access
37
- if site.uses_resource? && !data.permalink
38
- data.permalink = if collection && !collection.builtin?
39
- "/:collection/:path.*"
38
+ data.permalink ||= if collection && !collection.builtin?
39
+ collection.default_permalink.chomp("/").chomp(".*") + ".*"
40
40
  else
41
41
  "/:path.*"
42
42
  end
43
- end
44
43
  end
45
44
 
46
45
  # Returns source file path.
@@ -58,7 +57,7 @@ module Bridgetown
58
57
  def destination(dest)
59
58
  dest = site.in_dest_dir(dest)
60
59
  dest_url = url
61
- if site.uses_resource? && site.base_path.present? && collection
60
+ if site.base_path.present? && collection
62
61
  dest_url = dest_url.delete_prefix site.base_path(strip_slash_only: true)
63
62
  end
64
63
  site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
@@ -112,6 +111,7 @@ module Bridgetown
112
111
 
113
112
  FileUtils.mkdir_p(File.dirname(dest_path))
114
113
  FileUtils.rm(dest_path) if File.exist?(dest_path)
114
+ Bridgetown.logger.debug "Saving file:", dest_path
115
115
  copy_file(dest_path)
116
116
 
117
117
  true
@@ -177,14 +177,9 @@ module Bridgetown
177
177
  site.config.content_engine != "resource"
178
178
  base = if @collection.nil? || special_posts_case
179
179
  cleaned_relative_path
180
- elsif site.uses_resource?
180
+ else
181
181
  newly_processed = true
182
182
  Bridgetown::Resource::PermalinkProcessor.new(self).transform
183
- else
184
- Bridgetown::URL.new(
185
- template: @collection.url_template,
186
- placeholders: placeholders
187
- )
188
183
  end.to_s.chomp("/")
189
184
  newly_processed ? base : "#{base}#{extname}"
190
185
  end