bridgetown-core 1.3.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bridgetown +0 -6
  3. data/bin/bt +6 -0
  4. data/bridgetown-core.gemspec +9 -6
  5. data/lib/bridgetown-core/cleaner.rb +1 -1
  6. data/lib/bridgetown-core/collection.rb +30 -18
  7. data/lib/bridgetown-core/commands/build.rb +9 -22
  8. data/lib/bridgetown-core/commands/concerns/actions.rb +15 -8
  9. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +1 -1
  10. data/lib/bridgetown-core/commands/console.rb +3 -0
  11. data/lib/bridgetown-core/commands/doctor.rb +2 -4
  12. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +1 -1
  13. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -1
  14. data/lib/bridgetown-core/commands/esbuild/update.rb +2 -2
  15. data/lib/bridgetown-core/commands/esbuild.rb +3 -3
  16. data/lib/bridgetown-core/commands/new.rb +32 -39
  17. data/lib/bridgetown-core/commands/start.rb +76 -60
  18. data/lib/bridgetown-core/component.rb +19 -13
  19. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  20. data/lib/bridgetown-core/concerns/prioritizable.rb +11 -1
  21. data/lib/bridgetown-core/concerns/site/configurable.rb +7 -18
  22. data/lib/bridgetown-core/concerns/site/content.rb +10 -9
  23. data/lib/bridgetown-core/concerns/site/extensible.rb +4 -6
  24. data/lib/bridgetown-core/concerns/site/fast_refreshable.rb +161 -0
  25. data/lib/bridgetown-core/concerns/site/processable.rb +1 -0
  26. data/lib/bridgetown-core/concerns/site/renderable.rb +31 -7
  27. data/lib/bridgetown-core/concerns/site/ssr.rb +23 -9
  28. data/lib/bridgetown-core/concerns/site/writable.rb +1 -1
  29. data/lib/bridgetown-core/concerns/transformable.rb +3 -5
  30. data/lib/bridgetown-core/configuration/configuration_dsl.rb +23 -14
  31. data/lib/bridgetown-core/configuration.rb +67 -114
  32. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -2
  33. data/lib/bridgetown-core/configurations/cypress/cypress_tasks +2 -2
  34. data/lib/bridgetown-core/configurations/cypress.rb +1 -1
  35. data/lib/bridgetown-core/configurations/gh-pages/gh-pages.yml +3 -3
  36. data/lib/bridgetown-core/configurations/is-land.rb +1 -1
  37. data/lib/bridgetown-core/configurations/lit.rb +1 -1
  38. data/lib/bridgetown-core/configurations/open-props.rb +1 -1
  39. data/lib/bridgetown-core/configurations/purgecss.rb +1 -1
  40. data/lib/bridgetown-core/configurations/ruby2js.rb +1 -1
  41. data/lib/bridgetown-core/configurations/shoelace.rb +8 -20
  42. data/lib/bridgetown-core/configurations/stimulus.rb +17 -36
  43. data/lib/bridgetown-core/configurations/turbo.rb +1 -2
  44. data/lib/bridgetown-core/converter.rb +38 -10
  45. data/lib/bridgetown-core/converters/erb_templates.rb +9 -26
  46. data/lib/bridgetown-core/converters/identity.rb +1 -1
  47. data/lib/bridgetown-core/converters/liquid_templates.rb +2 -20
  48. data/lib/bridgetown-core/converters/ruby_templates.rb +61 -3
  49. data/lib/bridgetown-core/converters/serbea_templates.rb +12 -24
  50. data/lib/bridgetown-core/current.rb +19 -17
  51. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  52. data/lib/bridgetown-core/drops/drop.rb +3 -3
  53. data/lib/bridgetown-core/drops/relations_drop.rb +3 -2
  54. data/lib/bridgetown-core/drops/site_drop.rb +0 -5
  55. data/lib/bridgetown-core/entry_filter.rb +4 -6
  56. data/lib/bridgetown-core/errors.rb +2 -2
  57. data/lib/bridgetown-core/filters/from_liquid.rb +6 -10
  58. data/lib/bridgetown-core/filters/localization_filters.rb +1 -1
  59. data/lib/bridgetown-core/filters/translation_filters.rb +2 -2
  60. data/lib/bridgetown-core/filters.rb +3 -3
  61. data/lib/bridgetown-core/front_matter/defaults.rb +225 -0
  62. data/lib/bridgetown-core/front_matter/importer.rb +34 -0
  63. data/lib/bridgetown-core/front_matter/loaders/base.rb +29 -0
  64. data/lib/bridgetown-core/front_matter/loaders/ruby.rb +113 -0
  65. data/lib/bridgetown-core/front_matter/loaders/yaml.rb +42 -0
  66. data/lib/bridgetown-core/front_matter/loaders.rb +44 -0
  67. data/lib/bridgetown-core/{utils/ruby_front_matter.rb → front_matter/ruby.rb} +5 -5
  68. data/lib/bridgetown-core/front_matter.rb +11 -0
  69. data/lib/bridgetown-core/generated_page.rb +71 -31
  70. data/lib/bridgetown-core/generators/prototype_generator.rb +30 -18
  71. data/lib/bridgetown-core/helpers.rb +36 -47
  72. data/lib/bridgetown-core/hooks.rb +5 -5
  73. data/lib/bridgetown-core/inflector.rb +40 -0
  74. data/lib/bridgetown-core/kramdown/parser/gfm.rb +2 -2
  75. data/lib/bridgetown-core/layout.rb +3 -3
  76. data/lib/bridgetown-core/log_adapter.rb +12 -13
  77. data/lib/bridgetown-core/log_writer.rb +4 -4
  78. data/lib/bridgetown-core/model/base.rb +17 -17
  79. data/lib/bridgetown-core/model/builder_origin.rb +5 -3
  80. data/lib/bridgetown-core/model/origin.rb +1 -3
  81. data/lib/bridgetown-core/model/repo_origin.rb +12 -14
  82. data/lib/bridgetown-core/plugin.rb +0 -1
  83. data/lib/bridgetown-core/plugin_manager.rb +27 -84
  84. data/lib/bridgetown-core/rack/boot.rb +0 -15
  85. data/lib/bridgetown-core/rack/routes.rb +30 -90
  86. data/lib/bridgetown-core/reader.rb +6 -4
  87. data/lib/bridgetown-core/readers/layout_reader.rb +2 -2
  88. data/lib/bridgetown-core/readers/plugin_content_reader.rb +2 -2
  89. data/lib/bridgetown-core/resource/base.rb +112 -29
  90. data/lib/bridgetown-core/resource/destination.rb +1 -1
  91. data/lib/bridgetown-core/resource/relations.rb +11 -8
  92. data/lib/bridgetown-core/resource/taxonomy_type.rb +3 -1
  93. data/lib/bridgetown-core/resource/transformer.rb +4 -4
  94. data/lib/bridgetown-core/ruby_template_view.rb +44 -28
  95. data/lib/bridgetown-core/signals.rb +95 -0
  96. data/lib/bridgetown-core/site.rb +22 -4
  97. data/lib/bridgetown-core/slot.rb +5 -5
  98. data/lib/bridgetown-core/static_file.rb +5 -7
  99. data/lib/bridgetown-core/tags/asset_path.rb +11 -2
  100. data/lib/bridgetown-core/tags/find.rb +3 -5
  101. data/lib/bridgetown-core/tags/highlight.rb +3 -3
  102. data/lib/bridgetown-core/tags/post_url.rb +1 -1
  103. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +2 -2
  104. data/lib/bridgetown-core/utils/aux.rb +41 -41
  105. data/lib/bridgetown-core/utils/loaders_manager.rb +2 -21
  106. data/lib/bridgetown-core/utils/ruby_exec.rb +17 -0
  107. data/lib/bridgetown-core/utils.rb +46 -110
  108. data/lib/bridgetown-core/version.rb +2 -2
  109. data/lib/bridgetown-core/watcher.rb +21 -10
  110. data/lib/bridgetown-core.rb +35 -49
  111. data/lib/roda/plugins/bridgetown_server.rb +54 -12
  112. data/lib/roda/plugins/bridgetown_ssr.rb +13 -2
  113. data/lib/roda/plugins/ssg.rb +72 -0
  114. data/lib/site_template/.gitignore +9 -3
  115. data/lib/site_template/Gemfile.erb +3 -3
  116. data/lib/site_template/README.md +3 -4
  117. data/lib/site_template/Rakefile.erb +2 -15
  118. data/lib/site_template/TEMPLATES/erb/_partials/_head.erb +2 -2
  119. data/lib/site_template/TEMPLATES/serbea/_partials/_head.serb +2 -2
  120. data/lib/site_template/config/initializers.rb +60 -22
  121. data/lib/site_template/config/puma.rb +2 -0
  122. data/lib/site_template/package.json.erb +2 -27
  123. data/lib/site_template/src/index.md.erb +3 -3
  124. data/lib/site_template/tmp/pids/.keep +0 -0
  125. metadata +98 -63
  126. data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +0 -12
  127. data/lib/bridgetown-core/commands/webpack/setup.rb +0 -4
  128. data/lib/bridgetown-core/commands/webpack/update.rb +0 -24
  129. data/lib/bridgetown-core/commands/webpack/webpack.config.js +0 -31
  130. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +0 -135
  131. data/lib/bridgetown-core/commands/webpack.rb +0 -82
  132. data/lib/bridgetown-core/concerns/front_matter_importer.rb +0 -52
  133. data/lib/bridgetown-core/concerns/liquid_renderable.rb +0 -30
  134. data/lib/bridgetown-core/core_ext/psych.rb +0 -15
  135. data/lib/bridgetown-core/drops/url_drop.rb +0 -152
  136. data/lib/bridgetown-core/frontmatter_defaults.rb +0 -223
  137. data/lib/bridgetown-core/rack/static_indexes.rb +0 -31
  138. data/lib/bridgetown-core/url.rb +0 -166
  139. data/lib/bridgetown-core/utils/ansi.rb +0 -57
  140. data/lib/site_template/bridgetown.config.yml +0 -33
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module Commands
5
- class Webpack < Thor::Group
6
- include Thor::Actions
7
- extend Summarizable
8
-
9
- Registrations.register do
10
- register(Webpack, "webpack", "webpack ACTION", Webpack.summary)
11
- end
12
-
13
- def self.banner
14
- "bridgetown webpack ACTION"
15
- end
16
- summary "Perform actions on the Bridgetown Webpack configuration"
17
-
18
- def self.exit_on_failure?
19
- true
20
- end
21
-
22
- def webpack
23
- @logger = Bridgetown.logger
24
- return show_actions if args.empty?
25
-
26
- action = args.first
27
- if supported_actions.include?(action)
28
- perform action
29
- else
30
- @logger.error "Error:".red, "🚨 Please enter a valid action."
31
- say "\n"
32
- show_actions
33
- end
34
- end
35
-
36
- def self.source_root
37
- File.expand_path("./webpack", __dir__)
38
- end
39
-
40
- def self.destination_root
41
- config.root_dir
42
- end
43
-
44
- protected
45
-
46
- def config
47
- @config ||= Bridgetown.configuration({ root_dir: Dir.pwd })
48
- end
49
-
50
- def package_json
51
- @package_json ||= begin
52
- package_json_file = File.read(Bridgetown.sanitized_path(config.root_dir, "package.json"))
53
- JSON.parse(package_json_file)
54
- end
55
- end
56
-
57
- def perform(action)
58
- automation = find_in_source_paths("#{action}.rb")
59
- inside(New.created_site_dir || Dir.pwd) do
60
- apply automation, verbose: false
61
- end
62
- end
63
-
64
- def show_actions
65
- say "Available actions:\n".bold
66
-
67
- longest_action = supported_actions.keys.max_by(&:size).size
68
- supported_actions.each do |action, description|
69
- say "#{action.ljust(longest_action).to_s.bold.blue}\t# #{description}"
70
- end
71
- end
72
-
73
- def supported_actions
74
- {
75
- setup: "Sets up a Webpack integration with Bridgetown in your project",
76
- update: "Updates the Bridgetown Webpack defaults to the latest available version",
77
- "enable-postcss": "Configures PostCSS in your project",
78
- }.with_indifferent_access
79
- end
80
- end
81
- end
82
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module FrontMatterImporter
5
- # Requires klass#content and klass#front_matter_line_count accessors
6
- def self.included(klass)
7
- klass.include Bridgetown::Utils::RubyFrontMatterDSL
8
- end
9
-
10
- YAML_HEADER = %r!\A---\s*\n!.freeze
11
- YAML_BLOCK = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
12
- RUBY_HEADER = %r!\A[~`#-]{3,}(?:ruby|<%|{%)\s*\n!.freeze
13
- RUBY_BLOCK =
14
- %r!#{RUBY_HEADER.source}(.*?\n?)^((?:%>|%})?[~`#-]{3,}\s*$\n?)!m.freeze
15
-
16
- def read_front_matter(file_path) # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
17
- file_contents = File.read(
18
- file_path, **Bridgetown::Utils.merged_file_read_opts(Bridgetown::Current.site, {})
19
- )
20
- yaml_content = file_contents.match(YAML_BLOCK)
21
- if !yaml_content && Bridgetown::Current.site.config.should_execute_inline_ruby?
22
- ruby_content = file_contents.match(RUBY_BLOCK)
23
- end
24
-
25
- if yaml_content
26
- self.content = yaml_content.post_match
27
- self.front_matter_line_count = yaml_content[1].lines.size - 1
28
- YAMLParser.load(yaml_content[1])
29
- elsif ruby_content
30
- # rbfm header + content underneath
31
- self.content = ruby_content.post_match
32
- self.front_matter_line_count = ruby_content[1].lines.size
33
- process_ruby_data(ruby_content[1], file_path, 2)
34
- elsif Bridgetown::Utils.has_rbfm_header?(file_path)
35
- process_ruby_data(File.read(file_path).lines[1..].join("\n"), file_path, 2)
36
- elsif is_a?(Layout)
37
- self.content = file_contents
38
- {}
39
- else
40
- yaml_data = YAMLParser.load_file(file_path)
41
- yaml_data.is_a?(Array) ? { rows: yaml_data } : yaml_data
42
- end
43
- end
44
-
45
- def process_ruby_data(rubycode, file_path, starting_line)
46
- ruby_data = instance_eval(rubycode, file_path.to_s, starting_line)
47
- ruby_data.is_a?(Array) ? { rows: ruby_data } : ruby_data.to_h
48
- rescue StandardError => e
49
- raise "Ruby code isn't returning an array, or object which responds to `to_h' (#{e.message})"
50
- end
51
- end
52
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module LiquidRenderable
5
- # Determine whether the file should be rendered with Liquid.
6
- #
7
- # Returns false if the document is a yaml file or if the document doesn't
8
- # contain any Liquid Tags or Variables, true otherwise.
9
- def render_with_liquid?
10
- return false if data["render_with_liquid"] == false
11
- return false unless liquid_engine_configured?
12
-
13
- !(yaml_file? || !Utils.has_liquid_construct?(content))
14
- end
15
-
16
- def liquid_engine_configured?
17
- data["template_engine"].to_s == "liquid" ||
18
- (
19
- data["template_engine"].nil? && (
20
- site.config[:template_engine].nil? || site.config[:template_engine].to_s == "liquid"
21
- )
22
- )
23
- end
24
-
25
- # Override in individual classes
26
- def yaml_file?
27
- false
28
- end
29
- end
30
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module CoreExt
5
- module Psych
6
- module SafeLoadFile
7
- def safe_load_file(filename, **kwargs)
8
- File.open(filename, "r:bom|utf-8") do |f|
9
- safe_load f, filename: filename, **kwargs
10
- end
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,152 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- module Drops
5
- class UrlDrop < Drop
6
- extend Forwardable
7
-
8
- mutable false
9
-
10
- def_delegator :@obj, :cleaned_relative_path, :path
11
- def_delegator :@obj, :output_ext, :output_ext
12
-
13
- def collection
14
- @obj.collection.label
15
- end
16
-
17
- def name
18
- Utils.slugify(@obj.basename_without_ext)
19
- end
20
-
21
- def title
22
- Utils.slugify(qualified_slug_data, mode: "pretty", cased: true)
23
- end
24
-
25
- def slug
26
- Utils.slugify(qualified_slug_data)
27
- end
28
-
29
- def locale
30
- locale_data = @obj.data["locale"]
31
- @obj.site.config["available_locales"].include?(locale_data) ? locale_data : nil
32
- end
33
- alias_method :lang, :locale
34
-
35
- def categories
36
- category_set = Set.new
37
- Array(@obj.data["categories"]).each do |category|
38
- category_set << if @obj.site.config["slugify_categories"]
39
- Utils.slugify(category.to_s)
40
- else
41
- category.to_s.downcase
42
- end
43
- end
44
- category_set.to_a.join("/")
45
- end
46
-
47
- # CCYY
48
- def year
49
- @obj.date.strftime("%Y")
50
- end
51
-
52
- # MM: 01..12
53
- def month
54
- @obj.date.strftime("%m")
55
- end
56
-
57
- # DD: 01..31
58
- def day
59
- @obj.date.strftime("%d")
60
- end
61
-
62
- # hh: 00..23
63
- def hour
64
- @obj.date.strftime("%H")
65
- end
66
-
67
- # mm: 00..59
68
- def minute
69
- @obj.date.strftime("%M")
70
- end
71
-
72
- # ss: 00..59
73
- def second
74
- @obj.date.strftime("%S")
75
- end
76
-
77
- # D: 1..31
78
- def i_day
79
- @obj.date.strftime("%-d")
80
- end
81
-
82
- # M: 1..12
83
- def i_month
84
- @obj.date.strftime("%-m")
85
- end
86
-
87
- # MMM: Jan..Dec
88
- def short_month
89
- @obj.date.strftime("%b")
90
- end
91
-
92
- # MMMM: January..December
93
- def long_month
94
- @obj.date.strftime("%B")
95
- end
96
-
97
- # YY: 00..99
98
- def short_year
99
- @obj.date.strftime("%y")
100
- end
101
-
102
- # CCYYw, ISO week year
103
- # may differ from CCYY for the first days of January and last days of December
104
- def w_year
105
- @obj.date.strftime("%G")
106
- end
107
-
108
- # WW: 01..53
109
- # %W and %U do not comply with ISO 8601-1
110
- def week
111
- @obj.date.strftime("%V")
112
- end
113
-
114
- # d: 1..7 (Monday..Sunday)
115
- def w_day
116
- @obj.date.strftime("%u")
117
- end
118
-
119
- # dd: Mon..Sun
120
- def short_day
121
- @obj.date.strftime("%a")
122
- end
123
-
124
- # ddd: Monday..Sunday
125
- def long_day
126
- @obj.date.strftime("%A")
127
- end
128
-
129
- # DDD: 001..366
130
- def y_day
131
- @obj.date.strftime("%j")
132
- end
133
-
134
- private
135
-
136
- def qualified_slug_data
137
- slug_data = @obj.data["slug"] || @obj.basename_without_ext
138
- if @obj.data["locale"]
139
- slug_data.split(".").tap do |segments|
140
- segments.pop if segments.length > 1 && segments.last == @obj.data["locale"]
141
- end.join(".")
142
- else
143
- slug_data
144
- end
145
- end
146
-
147
- def fallback_data
148
- @fallback_data ||= {}
149
- end
150
- end
151
- end
152
- end
@@ -1,223 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- # This class handles custom defaults for front matter settings.
5
- # It is exposed via the frontmatter_defaults method on the site class.
6
- class FrontmatterDefaults
7
- # @return [Bridgetown::Site]
8
- attr_reader :site
9
-
10
- def initialize(site)
11
- @site = site
12
- @defaults_cache = {}
13
- end
14
-
15
- def reset
16
- @glob_cache = {}
17
- @defaults_cache = {}
18
- end
19
-
20
- def ensure_time!(set)
21
- return set unless set.key?("values") && set["values"].key?("date")
22
- return set if set["values"]["date"].is_a?(Time)
23
-
24
- set["values"]["date"] = Utils.parse_date(
25
- set["values"]["date"],
26
- "An invalid date format was found in a front-matter default set: #{set}"
27
- )
28
- set
29
- end
30
-
31
- # Collects a hash with all default values for a resource
32
- #
33
- # @param path [String] the relative path of the resource
34
- # @param collection_name [Symbol] :posts, :pages, etc.
35
- #
36
- # @return [Hash] all default values (an empty hash if there are none)
37
- def all(path, collection_name)
38
- if @defaults_cache.key?([path, collection_name])
39
- return @defaults_cache[[path, collection_name]]
40
- end
41
-
42
- defaults = {}
43
- merge_data_cascade_for_path(path, defaults)
44
-
45
- old_scope = nil
46
- matching_sets(path, collection_name).each do |set|
47
- if has_precedence?(old_scope, set["scope"])
48
- defaults = Utils.deep_merge_hashes(defaults, set["values"])
49
- old_scope = set["scope"]
50
- else
51
- defaults = Utils.deep_merge_hashes(set["values"], defaults)
52
- end
53
- end
54
-
55
- @defaults_cache[[path, collection_name]] = defaults
56
- end
57
-
58
- private
59
-
60
- def merge_data_cascade_for_path(path, merged_data)
61
- absolute_path = site.in_source_dir(path)
62
- site.defaults_reader.path_defaults
63
- .select { |k, _v| absolute_path.include? k }
64
- .sort_by { |k, _v| k.length }
65
- .each do |defaults|
66
- merged_data.merge!(defaults[1])
67
- end
68
- end
69
-
70
- # Checks if a given default setting scope matches the given path and collection
71
- #
72
- # scope - the hash indicating the scope, as defined in bridgetown.config.yml
73
- # path - the path to check for
74
- # collection - the collection (:posts or :pages) to check for
75
- #
76
- # Returns true if the scope applies to the given collection and path
77
- def applies?(scope, path, collection)
78
- applies_collection?(scope, collection) && applies_path?(scope, path)
79
- end
80
-
81
- def applies_path?(scope, path)
82
- rel_scope_path = scope["path"]
83
- return true if !rel_scope_path.is_a?(String) || rel_scope_path.empty?
84
-
85
- sanitized_path = strip_collections_dir(sanitize_path(path))
86
-
87
- if rel_scope_path.include?("*")
88
- glob_scope(sanitized_path, rel_scope_path)
89
- else
90
- path_is_subpath?(sanitized_path, strip_collections_dir(rel_scope_path))
91
- end
92
- end
93
-
94
- def glob_scope(sanitized_path, rel_scope_path)
95
- site_source = Pathname.new(site.source)
96
- abs_scope_path = site_source.join(rel_scope_path).to_s
97
-
98
- glob_cache(abs_scope_path).each do |scope_path|
99
- scope_path = Pathname.new(scope_path).relative_path_from(site_source).to_s
100
- scope_path = strip_collections_dir(scope_path)
101
- Bridgetown.logger.debug "Globbed Scope Path:", scope_path
102
- return true if path_is_subpath?(sanitized_path, scope_path)
103
- end
104
- false
105
- end
106
-
107
- def glob_cache(path)
108
- @glob_cache ||= {}
109
- @glob_cache[path] ||= Dir.glob(path)
110
- end
111
-
112
- def path_is_subpath?(path, parent_path)
113
- path.start_with?(parent_path)
114
- end
115
-
116
- def strip_collections_dir(path)
117
- collections_dir = site.config["collections_dir"]
118
- slashed_coll_dir = collections_dir.empty? ? "/" : "#{collections_dir}/"
119
- return path if collections_dir.empty? || !path.to_s.start_with?(slashed_coll_dir)
120
-
121
- path.sub(slashed_coll_dir, "")
122
- end
123
-
124
- # Determines whether the scope applies to collection.
125
- # The scope applies to the collection if:
126
- # 1. no 'collection' is specified
127
- # 2. the 'collection' in the scope is the same as the collection asked about
128
- #
129
- # @param scope [Hash] the defaults set being asked about
130
- # @param collection [Symbol] the collection of the resource being processed
131
- #
132
- # @return [Boolean] whether either of the above conditions are satisfied
133
- def applies_collection?(scope, collection)
134
- !scope.key?("collection") || scope["collection"].eql?(collection.to_s)
135
- end
136
-
137
- # Checks if a given set of default values is valid
138
- #
139
- # @param set [Hash] the default value hash as defined in bridgetown.config.yml
140
- #
141
- # @return [Boolean] if the set is valid and can be used
142
- def valid?(set)
143
- set.is_a?(Hash) && set["values"].is_a?(Hash)
144
- end
145
-
146
- # Determines if a new scope has precedence over an old one
147
- #
148
- # old_scope - the old scope hash, or nil if there's none
149
- # new_scope - the new scope hash
150
- #
151
- # Returns true if the new scope has precedence over the older
152
- # rubocop: disable Naming/PredicateName
153
- def has_precedence?(old_scope, new_scope)
154
- return true if old_scope.nil?
155
-
156
- new_path = sanitize_path(new_scope["path"])
157
- old_path = sanitize_path(old_scope["path"])
158
-
159
- if new_path.length != old_path.length
160
- new_path.length >= old_path.length
161
- elsif new_scope.key?("collection")
162
- true
163
- else
164
- !old_scope.key? "collection"
165
- end
166
- end
167
- # rubocop: enable Naming/PredicateName
168
-
169
- # Collects a list of sets that match the given path and collection
170
- #
171
- # @return [Array<Hash>]
172
- def matching_sets(path, collection)
173
- @matched_set_cache ||= {}
174
- @matched_set_cache[path] ||= {}
175
- @matched_set_cache[path][collection] ||= valid_sets.select do |set|
176
- !set.key?("scope") || applies?(set["scope"], path, collection)
177
- end
178
- end
179
-
180
- # Returns a list of valid sets
181
- #
182
- # This is not cached to allow plugins to modify the configuration
183
- # and have their changes take effect
184
- #
185
- # @return [Array<Hash>]
186
- def valid_sets
187
- sets = site.config["defaults"]
188
- return [] unless sets.is_a?(Array)
189
-
190
- sets.filter_map do |set|
191
- if valid?(set)
192
- massage_scope!(set)
193
- # TODO: is this trip really necessary?
194
- ensure_time!(set)
195
- else
196
- Bridgetown.logger.warn "Defaults:", "An invalid front-matter default set was found:"
197
- Bridgetown.logger.warn set.to_s
198
- nil
199
- end
200
- end
201
- end
202
-
203
- # Set path to blank if not specified and alias older type to collection
204
- def massage_scope!(set)
205
- set["scope"] ||= {}
206
- set["scope"]["path"] ||= ""
207
- return unless set["scope"]["type"] && !set["scope"]["collection"]
208
-
209
- set["scope"]["collection"] = set["scope"]["type"]
210
- end
211
-
212
- SANITIZATION_REGEX = %r!\A/|(?<=[^/])\z!.freeze
213
-
214
- # Sanitizes the given path by removing a leading and adding a trailing slash
215
- def sanitize_path(path)
216
- if path.nil? || path.empty?
217
- ""
218
- else
219
- path.gsub(SANITIZATION_REGEX, "")
220
- end
221
- end
222
- end
223
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "roda/plugins/public"
4
-
5
- # TODO: extract out to a standalone Roda plugin
6
- Roda::RodaPlugins::Public::RequestMethods.module_eval do
7
- SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact) # rubocop:disable Lint/ConstantDefinitionInBlock
8
- def public_path_segments(path) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
9
- segments = []
10
-
11
- path.split(SPLIT).each do |seg|
12
- next if seg.empty? || seg == "."
13
-
14
- seg == ".." ? segments.pop : segments << seg
15
- end
16
-
17
- path = File.join(roda_class.opts[:public_root], *segments)
18
- unless File.file?(path)
19
- path = File.join(path, "index.html")
20
- if File.file?(path)
21
- segments << "index.html"
22
- else
23
- segments[segments.size - 1] = "#{segments.last}.html"
24
- end
25
- end
26
-
27
- segments
28
- rescue IndexError
29
- nil
30
- end
31
- end