bridgetown-core 1.0.0.alpha1 → 1.0.0.alpha5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +35 -0
  3. data/Rakefile +5 -5
  4. data/lib/bridgetown-core/cache.rb +3 -5
  5. data/lib/bridgetown-core/cleaner.rb +2 -2
  6. data/lib/bridgetown-core/collection.rb +4 -6
  7. data/lib/bridgetown-core/commands/base.rb +4 -3
  8. data/lib/bridgetown-core/commands/build.rb +20 -19
  9. data/lib/bridgetown-core/commands/concerns/actions.rb +2 -2
  10. data/lib/bridgetown-core/commands/console.rb +3 -3
  11. data/lib/bridgetown-core/commands/doctor.rb +10 -8
  12. data/lib/bridgetown-core/commands/new.rb +5 -3
  13. data/lib/bridgetown-core/commands/plugins.rb +7 -9
  14. data/lib/bridgetown-core/commands/serve/servlet.rb +4 -4
  15. data/lib/bridgetown-core/commands/serve.rb +25 -27
  16. data/lib/bridgetown-core/commands/start.rb +6 -6
  17. data/lib/bridgetown-core/commands/webpack.rb +1 -1
  18. data/lib/bridgetown-core/component.rb +2 -6
  19. data/lib/bridgetown-core/concerns/liquid_renderable.rb +2 -2
  20. data/lib/bridgetown-core/concerns/site/configurable.rb +1 -6
  21. data/lib/bridgetown-core/concerns/site/content.rb +2 -2
  22. data/lib/bridgetown-core/concerns/site/extensible.rb +3 -4
  23. data/lib/bridgetown-core/concerns/site/localizable.rb +1 -1
  24. data/lib/bridgetown-core/concerns/site/ssr.rb +1 -1
  25. data/lib/bridgetown-core/concerns/site/writable.rb +1 -1
  26. data/lib/bridgetown-core/configuration.rb +1 -2
  27. data/lib/bridgetown-core/converter.rb +1 -0
  28. data/lib/bridgetown-core/converters/erb_templates.rb +6 -4
  29. data/lib/bridgetown-core/converters/liquid_templates.rb +2 -0
  30. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  31. data/lib/bridgetown-core/converters/smartypants.rb +1 -0
  32. data/lib/bridgetown-core/drops/drop.rb +4 -4
  33. data/lib/bridgetown-core/entry_filter.rb +1 -0
  34. data/lib/bridgetown-core/filters/url_filters.rb +1 -1
  35. data/lib/bridgetown-core/filters.rb +11 -12
  36. data/lib/bridgetown-core/frontmatter_defaults.rb +5 -7
  37. data/lib/bridgetown-core/generated_page.rb +1 -3
  38. data/lib/bridgetown-core/generators/prototype_generator.rb +36 -37
  39. data/lib/bridgetown-core/helpers.rb +1 -1
  40. data/lib/bridgetown-core/hooks.rb +2 -2
  41. data/lib/bridgetown-core/liquid_renderer.rb +1 -3
  42. data/lib/bridgetown-core/log_adapter.rb +1 -1
  43. data/lib/bridgetown-core/log_writer.rb +1 -1
  44. data/lib/bridgetown-core/model/base.rb +2 -2
  45. data/lib/bridgetown-core/model/builder_origin.rb +3 -3
  46. data/lib/bridgetown-core/model/plugin_origin.rb +1 -1
  47. data/lib/bridgetown-core/plugin_manager.rb +2 -2
  48. data/lib/bridgetown-core/publisher.rb +1 -1
  49. data/lib/bridgetown-core/rack/boot.rb +8 -0
  50. data/lib/bridgetown-core/rack/routes.rb +1 -5
  51. data/lib/bridgetown-core/rack/static_indexes.rb +2 -2
  52. data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
  53. data/lib/bridgetown-core/renderer.rb +1 -1
  54. data/lib/bridgetown-core/resource/base.rb +7 -7
  55. data/lib/bridgetown-core/resource/permalink_processor.rb +3 -2
  56. data/lib/bridgetown-core/resource/taxonomy_term.rb +1 -5
  57. data/lib/bridgetown-core/resource/transformer.rb +7 -5
  58. data/lib/bridgetown-core/ruby_template_view.rb +1 -3
  59. data/lib/bridgetown-core/static_file.rb +5 -7
  60. data/lib/bridgetown-core/tags/find.rb +6 -6
  61. data/lib/bridgetown-core/tags/highlight.rb +5 -5
  62. data/lib/bridgetown-core/tags/post_url.rb +6 -6
  63. data/lib/bridgetown-core/tags/render_content.rb +2 -2
  64. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +7 -1
  65. data/lib/bridgetown-core/url.rb +3 -3
  66. data/lib/bridgetown-core/utils.rb +7 -9
  67. data/lib/bridgetown-core/version.rb +1 -1
  68. data/lib/bridgetown-core/watcher.rb +2 -2
  69. data/lib/bridgetown-core.rb +2 -1
  70. data/lib/site_template/src/_layouts/default.liquid +1 -1
  71. metadata +3 -3
  72. data/lib/bridgetown-core/tags/include.rb +0 -213
@@ -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
@@ -267,7 +267,7 @@ module Bridgetown
267
267
  # Comparison is a comparison between the 2 dates or paths of the resources.
268
268
  #
269
269
  # @return [Integer] -1, 0, or +1
270
- def <=>(other) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity
270
+ def <=>(other) # rubocop:todo Metrics/AbcSize
271
271
  return nil unless other.respond_to?(:data)
272
272
 
273
273
  cmp = if data.date.respond_to?(:to_datetime) && other.data.date.respond_to?(:to_datetime)
@@ -293,7 +293,7 @@ module Bridgetown
293
293
 
294
294
  private
295
295
 
296
- def ensure_default_data
296
+ def ensure_default_data # rubocop:todo Metrics/AbcSize
297
297
  determine_locale
298
298
 
299
299
  slug = if matches = relative_path.to_s.match(DATE_FILENAME_MATCHER) # rubocop:disable Lint/AssignmentInCondition
@@ -337,14 +337,14 @@ module Bridgetown
337
337
  end
338
338
  end
339
339
 
340
- def determine_locale
340
+ def determine_locale # rubocop:todo Metrics/AbcSize
341
341
  unless data.locale
342
342
  data.locale = locale_from_alt_data_or_filename.presence || site.config.default_locale
343
343
  end
344
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
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
348
  end
349
349
 
350
350
  # Look for alternative front matter or look at the filename pattern: slug.locale.ext
@@ -46,9 +46,10 @@ module Bridgetown
46
46
  segment = segment.to_sym
47
47
  if self.class.placeholder_processors[segment]
48
48
  segment_value = self.class.placeholder_processors[segment].(resource)
49
- if segment_value.is_a?(Hash)
49
+ case segment_value
50
+ when Hash
50
51
  segment_value[:raw_value]
51
- elsif segment_value.is_a?(Array)
52
+ when Array
52
53
  segment_value.map do |subsegment|
53
54
  Utils.slugify(subsegment, mode: slugify_mode)
54
55
  end.join("/")
@@ -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
@@ -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,7 +61,6 @@ module Bridgetown
61
61
  @helpers ||= Helpers.new(self, site)
62
62
  end
63
63
 
64
- # rubocop:disable Style/MissingRespondToMissing
65
64
  ruby2_keywords def method_missing(method_name, *args, &block)
66
65
  if helpers.respond_to?(method_name.to_sym)
67
66
  helpers.send method_name.to_sym, *args, &block
@@ -73,7 +72,6 @@ module Bridgetown
73
72
  def respond_to_missing?(method_name, include_private = false)
74
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]
@@ -36,7 +36,7 @@ module Bridgetown
36
36
  @extname = File.extname(@name)
37
37
  @data = @site.frontmatter_defaults.all(relative_path, type).with_dot_access
38
38
  data.permalink ||= if collection && !collection.builtin?
39
- collection.default_permalink.chomp("/").chomp(".*") + ".*"
39
+ "#{collection.default_permalink.chomp("/").chomp(".*")}.*"
40
40
  else
41
41
  "/:path.*"
42
42
  end
@@ -44,9 +44,7 @@ module Bridgetown
44
44
 
45
45
  # Returns source file path.
46
46
  def path
47
- @path ||= begin
48
- File.join(*[@base, @dir, @name].compact)
49
- end
47
+ @path ||= File.join(*[@base, @dir, @name].compact)
50
48
  end
51
49
 
52
50
  # Obtain destination path.
@@ -207,9 +205,9 @@ module Bridgetown
207
205
  def copy_file(dest_path)
208
206
  FileUtils.copy_entry(path, dest_path)
209
207
 
210
- unless File.symlink?(dest_path)
211
- File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
212
- end
208
+ return if File.symlink?(dest_path)
209
+
210
+ File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
213
211
  end
214
212
  end
215
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
@@ -74,19 +74,19 @@ module Bridgetown
74
74
 
75
75
  site.collections.posts.resources.each do |document|
76
76
  return relative_url(document) if @post == document
77
- end
78
-
79
- # New matching method did not match, fall back to old method
80
- # with deprecation warning if this matches
81
77
 
82
- site.collections.posts.resources.each do |document|
78
+ # New matching method did not match, fall back to old method
79
+ # with deprecation warning if this matches
83
80
  next unless @post.deprecated_equality document
84
81
 
85
- Bridgetown::Deprecator.deprecation_message "A call to "\
82
+ Bridgetown::Deprecator.deprecation_message(
83
+ "A call to "\
86
84
  "'{% post_url #{@post.name} %}' did not match " \
87
85
  "a post using the new matching method of checking name " \
88
86
  "(path-date-slug) equality. Please make sure that you " \
89
87
  "change this tag to match the post's name exactly."
88
+ )
89
+
90
90
  return relative_url(document)
91
91
  end
92
92
 
@@ -3,7 +3,7 @@
3
3
  module Bridgetown
4
4
  module Tags
5
5
  class BlockRenderTag < Liquid::Block
6
- # rubocop:disable Metrics/MethodLength
6
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
7
7
  def render(context)
8
8
  context.stack({}) do
9
9
  # unindent the incoming text
@@ -37,7 +37,7 @@ module Bridgetown
37
37
  .render_tag(context, +"")
38
38
  end
39
39
  end
40
- # rubocop:enable Metrics/MethodLength
40
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
41
41
 
42
42
  private
43
43
 
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ desc "Generate a secret key for use in sessions, token generation, and beyond"
4
+ task :secret do
5
+ require "securerandom"
6
+ puts SecureRandom.hex(64) # rubocop:disable Bridgetown/NoPutsAllowed
7
+ end
8
+
3
9
  namespace :frontend do
4
10
  desc "Run frontend bundler independently"
5
11
  task :watcher, :sidecar do |_task, args|
@@ -23,7 +29,7 @@ end
23
29
 
24
30
  desc "Prerequisite task which loads site and provides automation"
25
31
  task :environment do
26
- class HammerActions < Thor
32
+ class HammerActions < Thor # rubocop:disable Lint/ConstantDefinitionInBlock
27
33
  include Thor::Actions
28
34
  include Bridgetown::Commands::Actions
29
35
 
@@ -28,9 +28,9 @@ module Bridgetown
28
28
  @placeholders = options[:placeholders] || {}
29
29
  @permalink = options[:permalink]
30
30
 
31
- if (@template || @permalink).nil?
32
- raise ArgumentError, "One of :template or :permalink must be supplied."
33
- end
31
+ return unless (@template || @permalink).nil?
32
+
33
+ raise ArgumentError, "One of :template or :permalink must be supplied."
34
34
  end
35
35
 
36
36
  # The generated relative URL of the resource
@@ -12,7 +12,7 @@ module Bridgetown
12
12
 
13
13
  # Constants for use in #slugify
14
14
  SLUGIFY_MODES = %w(raw default pretty simple ascii latin).freeze
15
- SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
15
+ SLUGIFY_RAW_REGEXP = Regexp.new("\\s+").freeze
16
16
  SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}]+").freeze
17
17
  SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze
18
18
  SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze
@@ -203,7 +203,7 @@ module Bridgetown
203
203
  slug = replace_character_sequence_with_hyphen(string, mode: mode)
204
204
 
205
205
  # Remove leading/trailing hyphen
206
- slug.gsub!(%r!^\-|\-$!i, "")
206
+ slug.gsub!(%r!^-|-$!i, "")
207
207
 
208
208
  slug.downcase! unless cased
209
209
 
@@ -316,9 +316,7 @@ module Bridgetown
316
316
  lines.map do |line|
317
317
  continue_processing = !skip_pre_lines
318
318
 
319
- if skip_pre_lines
320
- skip_pre_lines = false if line.include?("</pre>")
321
- end
319
+ skip_pre_lines = false if skip_pre_lines && line.include?("</pre>")
322
320
  if line.include?("<pre")
323
321
  skip_pre_lines = true
324
322
  continue_processing = false
@@ -340,7 +338,7 @@ module Bridgetown
340
338
  else
341
339
  line
342
340
  end
343
- end.join("")
341
+ end.join
344
342
  end
345
343
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
346
344
 
@@ -448,9 +446,9 @@ module Bridgetown
448
446
  end
449
447
 
450
448
  def merge_default_proc(target, overwrite)
451
- if target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
452
- target.default_proc = overwrite.default_proc
453
- end
449
+ return unless target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
450
+
451
+ target.default_proc = overwrite.default_proc
454
452
  end
455
453
 
456
454
  def duplicate_frozen_values(target)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "1.0.0.alpha1"
4
+ VERSION = "1.0.0.alpha5"
5
5
  CODE_NAME = "Pearl"
6
6
  end
@@ -116,7 +116,7 @@ module Bridgetown
116
116
  rescue ArgumentError
117
117
  # Could not find a relative path
118
118
  end
119
- end.compact + [%r!^\.bridgetown\-metadata!]
119
+ end.compact + [%r!^\.bridgetown-metadata!]
120
120
  end
121
121
 
122
122
  def sleep_forever
@@ -132,7 +132,7 @@ module Bridgetown
132
132
  site.plugin_manager.reload_component_loaders
133
133
  site.process
134
134
  Bridgetown.logger.info "Done! 🎉", "#{"Completed".green} in less than" \
135
- " #{(Time.now - time).ceil(2)} seconds."
135
+ " #{(Time.now - time).ceil(2)} seconds."
136
136
  rescue Exception => e
137
137
  Bridgetown.logger.error "Error:", e.message
138
138
 
@@ -249,12 +249,13 @@ end
249
249
 
250
250
  module Bridgetown
251
251
  module Model; end
252
+
252
253
  module Resource
253
254
  def self.register_extension(mod)
254
255
  if mod.const_defined?(:LiquidResource)
255
256
  Bridgetown::Drops::ResourceDrop.include mod.const_get(:LiquidResource)
256
257
  end
257
- if mod.const_defined?(:RubyResource)
258
+ if mod.const_defined?(:RubyResource) # rubocop:disable Style/GuardClause
258
259
  Bridgetown::Resource::Base.include mod.const_get(:RubyResource)
259
260
  end
260
261
  end
@@ -1,5 +1,5 @@
1
1
  <!doctype html>
2
- <html lang="en">
2
+ <html lang="{{ site.locale }}">
3
3
  <head>
4
4
  {% render "head", metadata: site.metadata, title: page.title %}
5
5
  </head>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha1
4
+ version: 1.0.0.alpha5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-16 00:00:00.000000000 Z
11
+ date: 2021-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -340,6 +340,7 @@ executables:
340
340
  extensions: []
341
341
  extra_rdoc_files: []
342
342
  files:
343
+ - ".rubocop.yml"
343
344
  - ".yardopts"
344
345
  - Rakefile
345
346
  - bin/bridgetown
@@ -475,7 +476,6 @@ files:
475
476
  - lib/bridgetown-core/tags/class_map.rb
476
477
  - lib/bridgetown-core/tags/find.rb
477
478
  - lib/bridgetown-core/tags/highlight.rb
478
- - lib/bridgetown-core/tags/include.rb
479
479
  - lib/bridgetown-core/tags/link.rb
480
480
  - lib/bridgetown-core/tags/live_reload_dev_js.rb
481
481
  - lib/bridgetown-core/tags/post_url.rb
@@ -1,213 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module Tags
5
- class IncludeTag < Liquid::Tag
6
- class << self
7
- attr_accessor :deprecation_message_shown
8
- end
9
-
10
- VALID_SYNTAX = %r!
11
- ([\w-]+)\s*=\s*
12
- (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
13
- !x.freeze
14
- VARIABLE_SYNTAX = %r!
15
- (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
16
- (?<params>.*)
17
- !mx.freeze
18
-
19
- FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
20
- VALID_FILENAME_CHARS = %r!^[\w/\.-]+$!.freeze
21
- INVALID_SEQUENCES = %r![./]{2,}!.freeze
22
-
23
- def initialize(tag_name, markup, tokens)
24
- super
25
-
26
- unless self.class.deprecation_message_shown
27
- Bridgetown.logger.warn "NOTICE: the {% include %} tag is deprecated and" \
28
- " will be removed in Bridgetown 1.0. You should" \
29
- " use the {% render %} tag instead."
30
- self.class.deprecation_message_shown = true
31
- end
32
-
33
- matched = markup.strip.match(VARIABLE_SYNTAX)
34
- if matched
35
- @file = matched["variable"].strip
36
- @params = matched["params"].strip
37
- else
38
- @file, @params = markup.strip.split(%r!\s+!, 2)
39
- end
40
- validate_params if @params
41
- @tag_name = tag_name
42
- end
43
-
44
- def syntax_example
45
- "{% #{@tag_name} file.ext param='value' param2='value' %}"
46
- end
47
-
48
- def parse_params(context)
49
- params = {}
50
- markup = @params
51
-
52
- while (match = VALID_SYNTAX.match(markup))
53
- markup = markup[match.end(0)..-1]
54
-
55
- value = if match[2]
56
- match[2].gsub('\\"', '"')
57
- elsif match[3]
58
- match[3].gsub("\\'", "'")
59
- elsif match[4]
60
- context[match[4]]
61
- end
62
-
63
- params[match[1]] = value
64
- end
65
- params
66
- end
67
-
68
- 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
-
73
- #{file}
74
-
75
- Valid syntax:
76
-
77
- #{syntax_example}
78
-
79
- MSG
80
- end
81
- end
82
-
83
- def validate_params
84
- unless FULL_VALID_SYNTAX.match?(@params)
85
- raise ArgumentError, <<~MSG
86
- Invalid syntax for include tag:
87
-
88
- #{@params}
89
-
90
- Valid syntax:
91
-
92
- #{syntax_example}
93
-
94
- MSG
95
- end
96
- end
97
-
98
- # Grab file read opts in the context
99
- def file_read_opts(context)
100
- context.registers[:site].file_read_opts
101
- end
102
-
103
- # Render the variable if required
104
- def render_variable(context)
105
- Liquid::Template.parse(@file).render(context) if VARIABLE_SYNTAX.match?(@file)
106
- end
107
-
108
- def tag_includes_dirs(context)
109
- context.registers[:site].includes_load_paths.freeze
110
- end
111
-
112
- def locate_include_file(context, file)
113
- includes_dirs = tag_includes_dirs(context)
114
- includes_dirs.each do |dir|
115
- path = File.join(dir, file)
116
- return path if valid_include_file?(path, dir.to_s)
117
- end
118
- raise IOError, could_not_locate_message(file, includes_dirs)
119
- end
120
-
121
- def render(context)
122
- file = render_variable(context) || @file
123
- validate_file_name(file)
124
-
125
- path = locate_include_file(context, file)
126
- return unless path
127
-
128
- partial = load_cached_partial(path, context)
129
-
130
- context.stack do
131
- context["include"] = parse_params(context) if @params
132
- begin
133
- partial.render!(context)
134
- rescue Liquid::Error => e
135
- e.template_name = path
136
- e.markup_context = "included " if e.markup_context.nil?
137
- raise e
138
- end
139
- end
140
- end
141
-
142
- def load_cached_partial(path, context)
143
- context.registers[:cached_partials] ||= {}
144
- cached_partial = context.registers[:cached_partials]
145
-
146
- if cached_partial.key?(path)
147
- cached_partial[path]
148
- else
149
- unparsed_file = context.registers[:site]
150
- .liquid_renderer
151
- .file(path)
152
- begin
153
- cached_partial[path] = unparsed_file.parse(read_file(path, context))
154
- rescue Liquid::Error => e
155
- e.template_name = path
156
- e.markup_context = "included " if e.markup_context.nil?
157
- raise e
158
- end
159
- end
160
- end
161
-
162
- def valid_include_file?(path, _dir)
163
- File.file?(path)
164
- end
165
-
166
- def realpath_prefixed_with?(path, dir)
167
- File.exist?(path) && File.realpath(path).start_with?(dir)
168
- rescue StandardError
169
- false
170
- end
171
-
172
- # This method allows to modify the file content by inheriting from the class.
173
- def read_file(file, context)
174
- File.read(file, **file_read_opts(context))
175
- end
176
-
177
- private
178
-
179
- def could_not_locate_message(file, includes_dirs)
180
- "Could not locate the included file '#{file}' in any of #{includes_dirs}." \
181
- " Ensure it exists in one of those directories."
182
- end
183
- end
184
-
185
- class IncludeRelativeTag < IncludeTag
186
- def tag_includes_dirs(context)
187
- Array(page_path(context)).freeze
188
- end
189
-
190
- def page_path(context)
191
- if context.registers[:page].nil?
192
- context.registers[:site].source
193
- else
194
- site = context.registers[:site]
195
- page_payload = context.registers[:page]
196
- resource_path = \
197
- if page_payload["collection"].nil?
198
- page_payload["path"]
199
- else
200
- File.join(site.config["collections_dir"], page_payload["path"])
201
- end
202
- # rubocop:disable Performance/DeleteSuffix
203
- resource_path.sub!(%r!/#excerpt\z!, "")
204
- # rubocop:enable Performance/DeleteSuffix
205
- site.in_source_dir File.dirname(resource_path)
206
- end
207
- end
208
- end
209
- end
210
- end
211
-
212
- Liquid::Template.register_tag("include", Bridgetown::Tags::IncludeTag)
213
- Liquid::Template.register_tag("include_relative", Bridgetown::Tags::IncludeRelativeTag)