bridgetown-core 0.21.2 → 1.0.0.alpha2

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 (127) 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 +1 -5
  24. data/lib/bridgetown-core/concerns/site/configurable.rb +1 -13
  25. data/lib/bridgetown-core/concerns/site/content.rb +17 -118
  26. data/lib/bridgetown-core/concerns/site/extensible.rb +3 -4
  27. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -1
  28. data/lib/bridgetown-core/concerns/site/processable.rb +9 -20
  29. data/lib/bridgetown-core/concerns/site/renderable.rb +19 -30
  30. data/lib/bridgetown-core/concerns/site/ssr.rb +53 -0
  31. data/lib/bridgetown-core/concerns/site/writable.rb +6 -9
  32. data/lib/bridgetown-core/configuration.rb +19 -48
  33. data/lib/bridgetown-core/configurations/minitesting.rb +1 -1
  34. data/lib/bridgetown-core/configurations/turbo.rb +1 -1
  35. data/lib/bridgetown-core/converter.rb +1 -0
  36. data/lib/bridgetown-core/converters/erb_templates.rb +3 -2
  37. data/lib/bridgetown-core/converters/liquid_templates.rb +3 -2
  38. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  39. data/lib/bridgetown-core/converters/smartypants.rb +1 -0
  40. data/lib/bridgetown-core/current.rb +4 -0
  41. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  42. data/lib/bridgetown-core/drops/drop.rb +4 -4
  43. data/lib/bridgetown-core/drops/generated_page_drop.rb +23 -0
  44. data/lib/bridgetown-core/drops/resource_drop.rb +3 -3
  45. data/lib/bridgetown-core/drops/site_drop.rb +3 -47
  46. data/lib/bridgetown-core/entry_filter.rb +1 -0
  47. data/lib/bridgetown-core/errors.rb +0 -2
  48. data/lib/bridgetown-core/filters/url_filters.rb +2 -0
  49. data/lib/bridgetown-core/filters.rb +11 -12
  50. data/lib/bridgetown-core/frontmatter_defaults.rb +52 -90
  51. data/lib/bridgetown-core/{page.rb → generated_page.rb} +34 -60
  52. data/lib/bridgetown-core/generators/prototype_generator.rb +49 -61
  53. data/lib/bridgetown-core/helpers.rb +8 -3
  54. data/lib/bridgetown-core/hooks.rb +2 -2
  55. data/lib/bridgetown-core/layout.rb +15 -4
  56. data/lib/bridgetown-core/liquid_renderer.rb +1 -3
  57. data/lib/bridgetown-core/log_adapter.rb +1 -1
  58. data/lib/bridgetown-core/log_writer.rb +7 -1
  59. data/lib/bridgetown-core/model/base.rb +12 -4
  60. data/lib/bridgetown-core/model/builder_origin.rb +23 -11
  61. data/lib/bridgetown-core/model/origin.rb +3 -0
  62. data/lib/bridgetown-core/model/plugin_origin.rb +34 -0
  63. data/lib/bridgetown-core/model/repo_origin.rb +1 -1
  64. data/lib/bridgetown-core/plugin_manager.rb +10 -10
  65. data/lib/bridgetown-core/publisher.rb +1 -1
  66. data/lib/bridgetown-core/rack/boot.rb +47 -0
  67. data/lib/bridgetown-core/rack/logger.rb +22 -0
  68. data/lib/bridgetown-core/rack/roda.rb +66 -0
  69. data/lib/bridgetown-core/rack/routes.rb +88 -0
  70. data/lib/bridgetown-core/rack/static_indexes.rb +30 -0
  71. data/lib/bridgetown-core/reader.rb +20 -47
  72. data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
  73. data/lib/bridgetown-core/readers/plugin_content_reader.rb +8 -7
  74. data/lib/bridgetown-core/renderer.rb +2 -12
  75. data/lib/bridgetown-core/resource/base.rb +51 -27
  76. data/lib/bridgetown-core/resource/permalink_processor.rb +23 -12
  77. data/lib/bridgetown-core/resource/relations.rb +2 -3
  78. data/lib/bridgetown-core/resource/taxonomy_term.rb +1 -5
  79. data/lib/bridgetown-core/resource/transformer.rb +8 -6
  80. data/lib/bridgetown-core/ruby_template_view.rb +6 -8
  81. data/lib/bridgetown-core/site.rb +4 -8
  82. data/lib/bridgetown-core/static_file.rb +14 -21
  83. data/lib/bridgetown-core/tags/find.rb +6 -6
  84. data/lib/bridgetown-core/tags/highlight.rb +5 -5
  85. data/lib/bridgetown-core/tags/include.rb +22 -32
  86. data/lib/bridgetown-core/tags/link.rb +4 -0
  87. data/lib/bridgetown-core/tags/live_reload_dev_js.rb +13 -0
  88. data/lib/bridgetown-core/tags/post_url.rb +9 -14
  89. data/lib/bridgetown-core/tags/render_content.rb +2 -2
  90. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +54 -0
  91. data/lib/bridgetown-core/url.rb +5 -4
  92. data/lib/bridgetown-core/utils/aux.rb +57 -0
  93. data/lib/bridgetown-core/utils/ruby_exec.rb +3 -45
  94. data/lib/bridgetown-core/utils/ruby_front_matter.rb +22 -7
  95. data/lib/bridgetown-core/utils.rb +60 -33
  96. data/lib/bridgetown-core/version.rb +2 -2
  97. data/lib/bridgetown-core/watcher.rb +4 -6
  98. data/lib/bridgetown-core.rb +16 -23
  99. data/lib/site_template/Gemfile.erb +6 -2
  100. data/lib/site_template/README.md +6 -6
  101. data/lib/site_template/Rakefile +49 -0
  102. data/lib/site_template/bridgetown.config.yml +2 -3
  103. data/lib/site_template/config/puma.rb +27 -0
  104. data/lib/site_template/config.ru +7 -0
  105. data/lib/site_template/frontend/javascript/index.js.erb +3 -3
  106. data/lib/site_template/package.json.erb +7 -12
  107. data/lib/site_template/server/roda_app.rb +22 -0
  108. data/lib/site_template/server/routes/hello.rb.sample +10 -0
  109. data/lib/site_template/src/_components/head.liquid +2 -1
  110. data/lib/site_template/src/about.md +0 -1
  111. data/lib/site_template/src/posts.md +2 -3
  112. metadata +63 -18
  113. data/lib/bridgetown-core/concerns/data_accessible.rb +0 -20
  114. data/lib/bridgetown-core/concerns/validatable.rb +0 -56
  115. data/lib/bridgetown-core/document.rb +0 -437
  116. data/lib/bridgetown-core/drops/document_drop.rb +0 -80
  117. data/lib/bridgetown-core/drops/excerpt_drop.rb +0 -19
  118. data/lib/bridgetown-core/drops/page_drop.rb +0 -18
  119. data/lib/bridgetown-core/excerpt.rb +0 -200
  120. data/lib/bridgetown-core/readers/data_reader.rb +0 -89
  121. data/lib/bridgetown-core/readers/page_reader.rb +0 -26
  122. data/lib/bridgetown-core/readers/post_reader.rb +0 -109
  123. data/lib/bridgetown-core/regenerator.rb +0 -202
  124. data/lib/bridgetown-core/related_posts.rb +0 -55
  125. data/lib/site_template/config/.keep +0 -0
  126. data/lib/site_template/start.js +0 -17
  127. data/lib/site_template/sync.js +0 -35
@@ -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
@@ -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
@@ -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.
269
+ # @return [Integer] -1, 0, or +1
268
270
  def <=>(other) # rubocop:todo Metrics/AbcSize
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
@@ -291,7 +293,9 @@ module Bridgetown
291
293
 
292
294
  private
293
295
 
294
- def ensure_default_data
296
+ def ensure_default_data # rubocop:todo Metrics/AbcSize
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 # 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
+
334
358
  def format_url(url)
335
359
  url.to_s.sub(%r{index\.html?$}, "").sub(%r{\.html?$}, "")
336
360
  end
@@ -36,20 +36,20 @@ 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)
47
46
  segment = segment.to_sym
48
47
  if self.class.placeholder_processors[segment]
49
48
  segment_value = self.class.placeholder_processors[segment].(resource)
50
- if segment_value.is_a?(Hash)
49
+ case segment_value
50
+ when Hash
51
51
  segment_value[:raw_value]
52
- elsif segment_value.is_a?(Array)
52
+ when Array
53
53
  segment_value.map do |subsegment|
54
54
  Utils.slugify(subsegment, mode: slugify_mode)
55
55
  end.join("/")
@@ -66,13 +66,13 @@ module Bridgetown
66
66
 
67
67
  case permalink_style.to_sym
68
68
  when :pretty
69
- "#{collection_prefix}/:categories/:year/:month/:day/:slug/"
69
+ "/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug/"
70
70
  when :pretty_ext, :date
71
- "#{collection_prefix}/:categories/:year/:month/:day/:slug.*"
71
+ "/:locale/#{collection_prefix}/:categories/:year/:month/:day/:slug.*"
72
72
  when :simple
73
- "#{collection_prefix}/:categories/:slug/"
73
+ "/:locale/#{collection_prefix}/:categories/:slug/"
74
74
  when :simple_ext
75
- "#{collection_prefix}/:categories/:slug.*"
75
+ "/:locale/#{collection_prefix}/:categories/:slug.*"
76
76
  else
77
77
  permalink_style.to_s
78
78
  end
@@ -96,7 +96,7 @@ module Bridgetown
96
96
  end
97
97
  end
98
98
 
99
- def add_base_path(permalink)
99
+ def ensure_base_path(permalink)
100
100
  if resource.site.base_path.present?
101
101
  return "#{resource.site.base_path(strip_slash_only: true)}#{permalink}"
102
102
  end
@@ -108,7 +108,16 @@ module Bridgetown
108
108
 
109
109
  # @param resource [Bridgetown::Resource::Base]
110
110
  register_placeholder :path, ->(resource) do
111
- { raw_value: resource.relative_path_basename_without_prefix }
111
+ {
112
+ raw_value: resource.relative_path_basename_without_prefix.tap do |path|
113
+ if resource.site.config["collections_dir"].present?
114
+ path.delete_prefix! "#{resource.site.config["collections_dir"]}/"
115
+ end
116
+ if resource.data.locale && path.ends_with?(".#{resource.data.locale}")
117
+ path.chomp!(".#{resource.data.locale}")
118
+ end
119
+ end,
120
+ }
112
121
  end
113
122
 
114
123
  # @param resource [Bridgetown::Resource::Base]
@@ -128,8 +137,10 @@ module Bridgetown
128
137
 
129
138
  # @param resource [Bridgetown::Resource::Base]
130
139
  register_placeholder :locale, ->(resource) do
131
- locale_data = resource.data.locale
132
- resource.site.config.available_locales.include?(locale_data) ? locale_data : nil
140
+ next nil if resource.data.locale&.to_sym == resource.site.config.default_locale
141
+
142
+ locale_data = resource.data.locale&.to_sym
143
+ resource.site.config.available_locales.include?(locale_data) ? locale_data.to_s : nil
133
144
  end
134
145
  register_placeholder :lang, placeholder_processors[:locale]
135
146
 
@@ -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]
@@ -3,11 +3,7 @@
3
3
  module Bridgetown
4
4
  module Resource
5
5
  class TaxonomyTerm
6
- attr_reader :resource
7
-
8
- attr_reader :label
9
-
10
- attr_reader :type
6
+ attr_reader :resource, :label, :type
11
7
 
12
8
  def initialize(resource:, label:, type:)
13
9
  @resource = resource
@@ -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
@@ -103,10 +103,12 @@ module Bridgetown
103
103
  end
104
104
 
105
105
  def warn_on_missing_layout(layout, layout_name)
106
- if layout.nil? && layout_name
107
- Bridgetown.logger.warn "Build Warning:", "Layout '#{layout_name}' " \
108
- "requested via #{resource.relative_path} does not exist."
109
- end
106
+ return unless layout.nil? && layout_name
107
+
108
+ Bridgetown.logger.warn(
109
+ "Build Warning:",
110
+ "Layout '#{layout_name}' requested via #{resource.relative_path} does not exist."
111
+ )
110
112
  end
111
113
 
112
114
  ### Transformation Actions
@@ -152,7 +154,7 @@ module Bridgetown
152
154
  layout_input = layout.content.dup
153
155
 
154
156
  layout_converters.inject(layout_input) do |content, converter|
155
- next(content) unless [2, -2].include?(converter.method(:convert).arity)
157
+ next(content) unless [2, -2].include?(converter.method(:convert).arity) # rubocop:disable Performance/CollectionLiteralInLoop
156
158
 
157
159
  layout.current_document = resource
158
160
  layout.current_document_output = output
@@ -61,19 +61,17 @@ module Bridgetown
61
61
  @helpers ||= Helpers.new(self, site)
62
62
  end
63
63
 
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
64
+ ruby2_keywords def method_missing(method_name, *args, &block)
65
+ if helpers.respond_to?(method_name.to_sym)
66
+ helpers.send method_name.to_sym, *args, &block
68
67
  else
69
68
  super
70
69
  end
71
70
  end
72
71
 
73
- def respond_to_missing?(method, include_private = false)
74
- helpers.respond_to?(method.to_sym, include_private) || super
72
+ def respond_to_missing?(method_name, include_private = false)
73
+ helpers.respond_to?(method_name.to_sym, include_private) || super
75
74
  end
76
- # rubocop:enable Style/MissingRespondToMissing
77
75
 
78
76
  private
79
77
 
@@ -84,7 +82,7 @@ module Bridgetown
84
82
  ["{% render \"#{component}\""]
85
83
  end
86
84
  unless options.empty?
87
- render_statement << ", " + options.keys.map { |k| "#{k}: #{k}" }.join(", ")
85
+ render_statement << ", #{options.keys.map { |k| "#{k}: #{k}" }.join(", ")}"
88
86
  end
89
87
  render_statement << " %}"
90
88
  if options[:_block_content]
@@ -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,20 +35,16 @@ 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.
47
46
  def path
48
- @path ||= begin
49
- File.join(*[@base, @dir, @name].compact)
50
- end
47
+ @path ||= File.join(*[@base, @dir, @name].compact)
51
48
  end
52
49
 
53
50
  # Obtain destination path.
@@ -58,7 +55,7 @@ module Bridgetown
58
55
  def destination(dest)
59
56
  dest = site.in_dest_dir(dest)
60
57
  dest_url = url
61
- if site.uses_resource? && site.base_path.present? && collection
58
+ if site.base_path.present? && collection
62
59
  dest_url = dest_url.delete_prefix site.base_path(strip_slash_only: true)
63
60
  end
64
61
  site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
@@ -112,6 +109,7 @@ module Bridgetown
112
109
 
113
110
  FileUtils.mkdir_p(File.dirname(dest_path))
114
111
  FileUtils.rm(dest_path) if File.exist?(dest_path)
112
+ Bridgetown.logger.debug "Saving file:", dest_path
115
113
  copy_file(dest_path)
116
114
 
117
115
  true
@@ -177,14 +175,9 @@ module Bridgetown
177
175
  site.config.content_engine != "resource"
178
176
  base = if @collection.nil? || special_posts_case
179
177
  cleaned_relative_path
180
- elsif site.uses_resource?
178
+ else
181
179
  newly_processed = true
182
180
  Bridgetown::Resource::PermalinkProcessor.new(self).transform
183
- else
184
- Bridgetown::URL.new(
185
- template: @collection.url_template,
186
- placeholders: placeholders
187
- )
188
181
  end.to_s.chomp("/")
189
182
  newly_processed ? base : "#{base}#{extname}"
190
183
  end
@@ -212,9 +205,9 @@ module Bridgetown
212
205
  def copy_file(dest_path)
213
206
  FileUtils.copy_entry(path, dest_path)
214
207
 
215
- unless File.symlink?(dest_path)
216
- File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
217
- end
208
+ return if File.symlink?(dest_path)
209
+
210
+ File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
218
211
  end
219
212
  end
220
213
  end
@@ -11,12 +11,7 @@ module Bridgetown
11
11
 
12
12
  def initialize(tag_name, markup, tokens)
13
13
  super
14
- if markup.strip =~ SYNTAX
15
- @new_var_name = Regexp.last_match(1).strip
16
- @single_or_group = Regexp.last_match(2)
17
- @arr_name = Regexp.last_match(3).strip
18
- @conditions = process_conditions(Regexp.last_match(4).strip)
19
- else
14
+ unless markup.strip =~ SYNTAX
20
15
  raise SyntaxError, <<~MSG
21
16
  Syntax Error in tag 'find' while parsing the following markup:
22
17
 
@@ -25,6 +20,11 @@ module Bridgetown
25
20
  Valid syntax: find <varname> where|in <array>, <condition(s)>
26
21
  MSG
27
22
  end
23
+
24
+ @new_var_name = Regexp.last_match(1).strip
25
+ @single_or_group = Regexp.last_match(2)
26
+ @arr_name = Regexp.last_match(3).strip
27
+ @conditions = process_conditions(Regexp.last_match(4).strip)
28
28
  end
29
29
 
30
30
  def render(context)
@@ -14,10 +14,7 @@ module Bridgetown
14
14
 
15
15
  def initialize(tag_name, markup, tokens)
16
16
  super
17
- if markup.strip =~ SYNTAX
18
- @lang = Regexp.last_match(1).downcase
19
- @highlight_options = parse_options(Regexp.last_match(2))
20
- else
17
+ unless markup.strip =~ SYNTAX
21
18
  raise SyntaxError, <<~MSG
22
19
  Syntax Error in tag 'highlight' while parsing the following markup:
23
20
 
@@ -26,6 +23,9 @@ module Bridgetown
26
23
  Valid syntax: highlight <lang> [linenos]
27
24
  MSG
28
25
  end
26
+
27
+ @lang = Regexp.last_match(1).downcase
28
+ @highlight_options = parse_options(Regexp.last_match(2))
29
29
  end
30
30
 
31
31
  LEADING_OR_TRAILING_LINE_TERMINATORS = %r!\A(\n|\r)+|(\n|\r)+\z!.freeze
@@ -89,7 +89,7 @@ module Bridgetown
89
89
  "data-lang=\"#{@lang}\"",
90
90
  ].join(" ")
91
91
  "<figure class=\"highlight\"><pre><code #{code_attributes}>"\
92
- "#{code.chomp}</code></pre></figure>"
92
+ "#{code.chomp}</code></pre></figure>"
93
93
  end
94
94
  end
95
95
  end
@@ -9,15 +9,18 @@ module Bridgetown
9
9
 
10
10
  VALID_SYNTAX = %r!
11
11
  ([\w-]+)\s*=\s*
12
- (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
12
+ (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.-]+))
13
13
  !x.freeze
14
+
15
+ # rubocop:disable Lint/MixedRegexpCaptureTypes
14
16
  VARIABLE_SYNTAX = %r!
15
- (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
17
+ (?<variable>[^{]*(\{\{\s*[\w\-.]+\s*(\|.*)?\}\}[^\s{}]*)+)
16
18
  (?<params>.*)
17
19
  !mx.freeze
20
+ # rubocop:enable Lint/MixedRegexpCaptureTypes
18
21
 
19
22
  FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
20
- VALID_FILENAME_CHARS = %r!^[\w/\.-]+$!.freeze
23
+ VALID_FILENAME_CHARS = %r!^[\w/.-]+$!.freeze
21
24
  INVALID_SEQUENCES = %r![./]{2,}!.freeze
22
25
 
23
26
  def initialize(tag_name, markup, tokens)
@@ -66,33 +69,33 @@ module Bridgetown
66
69
  end
67
70
 
68
71
  def validate_file_name(file)
69
- if INVALID_SEQUENCES.match?(file) || !VALID_FILENAME_CHARS.match?(file)
70
- raise ArgumentError, <<~MSG
71
- Invalid syntax for include tag. File contains invalid characters or sequences:
72
+ return unless INVALID_SEQUENCES.match?(file) || !VALID_FILENAME_CHARS.match?(file)
72
73
 
73
- #{file}
74
+ raise ArgumentError, <<~MSG
75
+ Invalid syntax for include tag. File contains invalid characters or sequences:
74
76
 
75
- Valid syntax:
77
+ #{file}
76
78
 
77
- #{syntax_example}
79
+ Valid syntax:
78
80
 
79
- MSG
80
- end
81
+ #{syntax_example}
82
+
83
+ MSG
81
84
  end
82
85
 
83
86
  def validate_params
84
- unless FULL_VALID_SYNTAX.match?(@params)
85
- raise ArgumentError, <<~MSG
86
- Invalid syntax for include tag:
87
+ return if FULL_VALID_SYNTAX.match?(@params)
87
88
 
88
- #{@params}
89
+ raise ArgumentError, <<~MSG
90
+ Invalid syntax for include tag:
89
91
 
90
- Valid syntax:
92
+ #{@params}
91
93
 
92
- #{syntax_example}
94
+ Valid syntax:
93
95
 
94
- MSG
95
- end
96
+ #{syntax_example}
97
+
98
+ MSG
96
99
  end
97
100
 
98
101
  # Grab file read opts in the context
@@ -119,16 +122,12 @@ module Bridgetown
119
122
  end
120
123
 
121
124
  def render(context)
122
- site = context.registers[:site]
123
-
124
125
  file = render_variable(context) || @file
125
126
  validate_file_name(file)
126
127
 
127
128
  path = locate_include_file(context, file)
128
129
  return unless path
129
130
 
130
- add_include_to_dependency(site, path, context)
131
-
132
131
  partial = load_cached_partial(path, context)
133
132
 
134
133
  context.stack do
@@ -143,15 +142,6 @@ module Bridgetown
143
142
  end
144
143
  end
145
144
 
146
- def add_include_to_dependency(site, path, context)
147
- if context.registers[:page]&.key?("path")
148
- site.regenerator.add_dependency(
149
- site.in_source_dir(context.registers[:page]["path"]),
150
- path
151
- )
152
- end
153
- end
154
-
155
145
  def load_cached_partial(path, context)
156
146
  context.registers[:cached_partials] ||= {}
157
147
  cached_partial = context.registers[:cached_partials]
@@ -23,6 +23,10 @@ module Bridgetown
23
23
  relative_path = Liquid::Template.parse(@relative_path).render(context)
24
24
 
25
25
  site.each_site_file do |item|
26
+ # Resource engine:
27
+ if item.respond_to?(:relative_url) && item.relative_path.to_s == relative_path
28
+ return item.relative_url
29
+ end
26
30
  return relative_url(item) if item.relative_path == relative_path
27
31
  # This takes care of the case for static files that have a leading /
28
32
  return relative_url(item) if item.relative_path == "/#{relative_path}"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Tags
5
+ class LiveReloadJsTag < Liquid::Tag
6
+ def render(context)
7
+ Bridgetown::Utils.live_reload_js(context.registers[:site])
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ Liquid::Template.register_tag("live_reload_dev_js", Bridgetown::Tags::LiveReloadJsTag)