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
@@ -1,18 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- # TODO: to be retired once the Resource engine is made official
5
- class Page
6
- include DataAccessible
4
+ class GeneratedPage
7
5
  include LayoutPlaceable
8
6
  include LiquidRenderable
9
7
  include Publishable
10
- include Validatable
11
8
 
12
9
  attr_writer :dir
13
- attr_accessor :site, :paginator, :pager
14
- attr_accessor :name, :ext, :basename
15
- attr_accessor :data, :content, :output
10
+ attr_accessor :site, :paginator, :name, :ext, :basename, :data, :content, :output
16
11
 
17
12
  alias_method :extname, :ext
18
13
 
@@ -25,7 +20,7 @@ module Bridgetown
25
20
  .htm
26
21
  ).freeze
27
22
 
28
- # Initialize a new Page.
23
+ # Initialize a new GeneratedPage.
29
24
  #
30
25
  # site - The Site object.
31
26
  # base - The String path to the source.
@@ -38,23 +33,36 @@ module Bridgetown
38
33
  @base = base
39
34
  @dir = dir
40
35
  @name = name
36
+ @ext = File.extname(name)
37
+ @basename = File.basename(name, ".*")
41
38
  @path = if from_plugin
42
39
  File.join(base, dir, name)
43
40
  else
44
41
  site.in_source_dir(base, dir, name)
45
42
  end
46
43
 
47
- process(name)
48
- read_yaml(File.join(base, dir), name)
44
+ process
49
45
 
50
- data.default_proc = proc do |_, key|
51
- site.frontmatter_defaults.find(relative_path, type, key.to_s)
52
- end
46
+ self.data ||= HashWithDotAccess::Hash.new
53
47
 
54
- Bridgetown::Hooks.trigger :pages, :post_init, self
48
+ Bridgetown::Hooks.trigger :generated_pages, :post_init, self
55
49
  end
56
50
  # rubocop:enable Metrics/ParameterLists
57
51
 
52
+ # Returns the contents as a String.
53
+ def to_s
54
+ output || content || ""
55
+ end
56
+
57
+ # Accessor for data properties by Liquid.
58
+ #
59
+ # property - The String name of the property to retrieve.
60
+ #
61
+ # Returns the String value or nil if the property isn't included.
62
+ def [](property)
63
+ data[property]
64
+ end
65
+
58
66
  # The generated directory into which the page will be placed
59
67
  # upon generation. This is derived from the permalink or, if
60
68
  # permalink is absent, will be '/'
@@ -69,29 +77,15 @@ module Bridgetown
69
77
  end
70
78
  end
71
79
 
72
- def liquid_drop
73
- @liquid_drop ||= begin
74
- defaults = site.frontmatter_defaults.all(relative_path, type)
75
- unless defaults.empty?
76
- Utils.deep_merge_hashes!(data, Utils.deep_merge_hashes!(defaults, data))
77
- end
78
- Drops::PageDrop.new(self)
79
- end
80
- end
81
-
82
- # Public
83
- #
84
80
  # Liquid representation of current page
85
81
  def to_liquid
86
- liquid_drop
82
+ @liquid_drop ||= Drops::GeneratedPageDrop.new(self)
87
83
  end
88
84
 
89
85
  # The full path and filename of the post. Defined in the YAML of the post
90
- # body.
91
- #
92
- # Returns the String permalink or nil if none has been set.
86
+ # body
93
87
  def permalink
94
- data.nil? ? nil : data["permalink"]
88
+ data&.permalink
95
89
  end
96
90
 
97
91
  # The template of the permalink.
@@ -123,33 +117,20 @@ module Bridgetown
123
117
  # desired placeholder replacements. For details see "url.rb"
124
118
  def url_placeholders
125
119
  {
126
- path: qualified_pages_path_for_url,
127
- basename: basename,
120
+ path: @dir,
121
+ basename: @basename,
128
122
  output_ext: output_ext,
129
123
  }
130
124
  end
131
125
 
132
- # Strips _pages prefix off if needed for the url/destination generation
133
- # @return [String]
134
- def qualified_pages_path_for_url
135
- @dir.sub(%r!^/_pages!, "")
136
- end
137
-
138
- # Extract information from the page filename.
139
- #
140
- # name - The String filename of the page file.
141
- #
142
- # NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
143
- # Returns nothing.
144
- def process(name)
145
- self.ext = File.extname(name)
146
- self.basename = name[0..-ext.length - 1].gsub(%r!\.*\z!, "")
126
+ # Overide this in subclasses for custom initialization behavior
127
+ def process
128
+ # no-op by default
147
129
  end
148
130
 
149
131
  # The path to the source file
150
- #
151
- # Returns the path to the source file
152
132
  def path
133
+ # TODO: is this trip really necessary?!
153
134
  data.fetch("path") { relative_path }
154
135
  end
155
136
 
@@ -190,7 +171,7 @@ module Bridgetown
190
171
  FileUtils.mkdir_p(File.dirname(path))
191
172
  Bridgetown.logger.debug "Writing:", path
192
173
  File.write(path, output, mode: "wb")
193
- Bridgetown::Hooks.trigger :pages, :post_write, self
174
+ Bridgetown::Hooks.trigger :generated_pages, :post_write, self
194
175
  end
195
176
 
196
177
  # Returns the object as a debug String.
@@ -209,22 +190,15 @@ module Bridgetown
209
190
  end
210
191
 
211
192
  def trigger_hooks(hook_name, *args)
212
- Bridgetown::Hooks.trigger :pages, hook_name, self, *args
193
+ Bridgetown::Hooks.trigger :generated_pages, hook_name, self, *args
213
194
  end
214
195
 
215
196
  def type
216
- :pages
197
+ :generated_pages
217
198
  end
218
199
 
219
200
  def write?
220
201
  true
221
202
  end
222
203
  end
223
-
224
- # set up virtual page class for future compatibility
225
- class GeneratedPage < Page
226
- def read_yaml(_base, _name, _opts = {})
227
- self.data ||= HashWithDotAccess::Hash.new
228
- end
229
- end
230
204
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Handles Generated Pages
4
- Bridgetown::Hooks.register :pages, :post_init, reloadable: false do |page|
4
+ Bridgetown::Hooks.register :generated_pages, :post_init, reloadable: false do |page|
5
5
  if page.class != Bridgetown::PrototypePage && page.data["prototype"].is_a?(Hash)
6
6
  Bridgetown::PrototypeGenerator.add_matching_template(page)
7
7
  end
@@ -38,52 +38,51 @@ module Bridgetown
38
38
  # @param site [Bridgetown::Site]
39
39
  def generate(site)
40
40
  @site = site
41
- @configured_collection = "posts" unless site.uses_resource?
42
- page_list = site.uses_resource? ? site.collections.pages.resources : site.pages
41
+ page_list = site.collections.pages.resources
43
42
 
44
43
  prototype_pages = self.class.matching_templates.select do |page|
45
44
  page_list.include?(page)
46
45
  end
47
46
 
48
- if prototype_pages.length.positive?
49
- ensure_pagination_enabled
47
+ return unless prototype_pages.length.positive?
50
48
 
51
- page_list.reject! do |page|
52
- prototype_pages.include? page
53
- end
49
+ ensure_pagination_enabled
50
+
51
+ page_list.reject! do |page|
52
+ prototype_pages.include? page
53
+ end
54
54
 
55
- prototype_pages.each do |prototype_page|
56
- search_term = validate_search_term(prototype_page)
57
- next if search_term.nil?
55
+ prototype_pages.each do |prototype_page|
56
+ search_term = validate_search_term(prototype_page)
57
+ next if search_term.nil?
58
58
 
59
- terms_matching_pages(search_term).each do |term|
60
- generate_new_page_from_prototype(prototype_page, search_term, term)
61
- end
59
+ terms_matching_pages(search_term).each do |term|
60
+ generate_new_page_from_prototype(prototype_page, search_term, term)
62
61
  end
63
62
  end
64
63
  end
65
64
 
66
65
  def ensure_pagination_enabled
67
- unless @site.config.dig(:pagination, :enabled)
68
- Bridgetown.logger.warn(
69
- "Pagination:",
70
- "Must be enabled for prototype pages to contain matches"
71
- )
72
- end
66
+ return if @site.config.dig(:pagination, :enabled)
67
+
68
+ Bridgetown.logger.warn(
69
+ "Pagination:",
70
+ "Must be enabled for prototype pages to contain matches"
71
+ )
73
72
  end
74
73
 
75
74
  # Check incoming prototype configuration and normalize options.
76
75
  #
77
- # @param prototype_page [Bridgetown::Page, Bridgetown::Resource::Base]
76
+ # @param prototype_page [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
78
77
  #
79
78
  # @return [String, nil]
80
79
  def validate_search_term(prototype_page)
81
80
  # @type [String]
82
- search_term = prototype_page.data["prototype"]["term"]
83
- return nil unless search_term.is_a?(String)
81
+ search_term = prototype_page.data["prototype"]["term"].to_s
82
+ return nil unless search_term.present?
84
83
 
85
84
  if prototype_page.data["prototype"]["collection"]
86
- @configured_collection = prototype_page.data["prototype"]["collection"]
85
+ @configured_collection = prototype_page.data["prototype"]["collection"].to_s
87
86
  end
88
87
 
89
88
  unless site.collections[@configured_collection]
@@ -110,11 +109,7 @@ module Bridgetown
110
109
  #
111
110
  # @return [Array<String>]
112
111
  def terms_matching_pages(search_term)
113
- pages_list = if site.uses_resource?
114
- site.collections[@configured_collection].resources
115
- else
116
- site.collections[@configured_collection].docs
117
- end
112
+ pages_list = site.collections[@configured_collection].resources
118
113
 
119
114
  Bridgetown::Paginate::PaginationIndexer.index_documents_by(
120
115
  pages_list, search_term
@@ -123,35 +118,29 @@ module Bridgetown
123
118
  end
124
119
 
125
120
  class PrototypePage < GeneratedPage
126
- # @return [Bridgetown::Page, Bridgetown::Resource::Base]
121
+ # @return [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
127
122
  attr_reader :prototyped_page
128
123
 
129
124
  # @param prototyped_page [Bridgetown::Page, Bridgetown::Resource::Base]
130
125
  # @param collection [Bridgetown::Collection]
131
126
  # @param search_term [String]
132
127
  # @param term [String]
133
- def initialize(prototyped_page, collection, search_term, term)
128
+ def initialize(prototyped_page, collection, search_term, term) # rubocop:disable Lint/MissingSuper
134
129
  @prototyped_page = prototyped_page
135
130
  @site = prototyped_page.site
136
131
  @url = ""
137
132
  @name = "index.html"
138
- @path = prototyped_page.path
139
-
140
- process(@name)
133
+ @ext = ".html"
134
+ @basename = "index"
135
+ @dir = Pathname.new(prototyped_page.relative_path).dirname.to_s.sub(%r{^_pages}, "")
136
+ @path = site.in_source_dir(@dir, @name)
141
137
 
142
138
  self.data = Bridgetown::Utils.deep_merge_hashes prototyped_page.data, {}
143
139
  self.content = prototyped_page.content
144
140
 
145
- # Perform some validation that is also performed in Bridgetown::Page
146
- validate_data! prototyped_page.path
147
- validate_permalink! prototyped_page.path
148
-
149
- @dir = Pathname.new(prototyped_page.relative_path).dirname.to_s.sub(%r{^_pages}, "")
150
- @path = site.in_source_dir(@dir, @name)
151
-
152
141
  process_prototype_page_data(collection, search_term, term)
153
142
 
154
- Bridgetown::Hooks.trigger :pages, :post_init, self
143
+ Bridgetown::Hooks.trigger :generated_pages, :post_init, self
155
144
  end
156
145
 
157
146
  def process_prototype_page_data(collection, search_term, term)
@@ -171,22 +160,21 @@ module Bridgetown
171
160
  slugify_term(term)
172
161
  end
173
162
 
174
- # rubocop:todo Metrics/AbcSize
175
- def process_title_data_placeholder(search_term, term)
176
- if prototyped_page.data["prototype"]["data"]
177
- if data["title"]&.include?(":prototype-data-label")
178
- related_data = site.data[prototyped_page.data["prototype"]["data"]].dig(term)
179
- if related_data
180
- data["#{search_term}_data"] = related_data
181
- data_label = related_data[prototyped_page.data["prototype"]["data_label"]]
182
- data["title"] = data["title"].gsub(
183
- ":prototype-data-label", data_label
184
- )
185
- end
186
- end
163
+ def process_title_data_placeholder(search_term, term) # rubocop:todo Metrics/AbcSize
164
+ unless prototyped_page.data["prototype"]["data"] &&
165
+ data["title"]&.include?(":prototype-data-label")
166
+ return
187
167
  end
168
+
169
+ related_data = site.data[prototyped_page.data["prototype"]["data"]][term]
170
+ return unless related_data
171
+
172
+ data["#{search_term}_data"] = related_data
173
+ data_label = related_data[prototyped_page.data["prototype"]["data_label"]]
174
+ data["title"] = data["title"].gsub(
175
+ ":prototype-data-label", data_label
176
+ )
188
177
  end
189
- # rubocop:enable Metrics/AbcSize
190
178
 
191
179
  def process_title_simple_placeholders(term)
192
180
  if data["title"]&.include?(":prototype-term-titleize")
@@ -195,11 +183,11 @@ module Bridgetown
195
183
  )
196
184
  end
197
185
 
198
- if data["title"]&.include?(":prototype-term")
199
- data["title"] = data["title"].gsub(
200
- ":prototype-term", term
201
- )
202
- end
186
+ return unless data["title"]&.include?(":prototype-term")
187
+
188
+ data["title"] = data["title"].gsub(
189
+ ":prototype-term", term
190
+ )
203
191
  end
204
192
 
205
193
  def slugify_term(term)
@@ -26,6 +26,10 @@ module Bridgetown
26
26
  Bridgetown::Utils.parse_webpack_manifest_file(site, asset_type.to_s)
27
27
  end
28
28
 
29
+ def live_reload_dev_js
30
+ Bridgetown::Utils.live_reload_js(site)
31
+ end
32
+
29
33
  # @param pairs [Hash] A hash of key/value pairs.
30
34
  #
31
35
  # @return [String] Space-separated keys where the values are truthy.
@@ -52,11 +56,11 @@ module Bridgetown
52
56
  # `url` or `relative_url`
53
57
  # @return [String] the permalink URL for the file
54
58
  def url_for(relative_path)
55
- if relative_path.respond_to?(:relative_url)
59
+ if relative_path.respond_to?(:relative_url) # rubocop:disable Style/GuardClause
56
60
  return safe(relative_path.relative_url) # new resource engine
57
61
  elsif relative_path.respond_to?(:url)
58
62
  return safe(relative_url(relative_path.url)) # old legacy engine
59
- elsif relative_path.start_with?("/", "http")
63
+ elsif relative_path.to_s.start_with?("/", "http")
60
64
  return safe(relative_path)
61
65
  end
62
66
 
@@ -69,7 +73,8 @@ module Bridgetown
69
73
  # @raise [ArgumentError] if the file cannot be found
70
74
  def find_relative_url_for_path(relative_path)
71
75
  site.each_site_file do |item|
72
- if item.relative_path == relative_path || item.relative_path == "/#{relative_path}"
76
+ if item.relative_path.to_s == relative_path ||
77
+ item.relative_path.to_s == "/#{relative_path}"
73
78
  return safe(item.respond_to?(:relative_url) ? item.relative_url : relative_url(item))
74
79
  end
75
80
  end
@@ -72,14 +72,14 @@ module Bridgetown
72
72
  @registry[owner].delete_if { |item| item.block == block }
73
73
  end
74
74
 
75
- def self.trigger(owner, event, *args)
75
+ def self.trigger(owner, event, *args) # rubocop:disable Metrics/CyclomaticComplexity
76
76
  # proceed only if there are hooks to call
77
77
  hooks = @registry[owner]&.select { |item| item.event == event }
78
78
  return if hooks.nil? || hooks.empty?
79
79
 
80
80
  prioritized_hooks(hooks).each do |hook|
81
81
  if ENV["BRIDGETOWN_LOG_LEVEL"] == "debug"
82
- hook_info = args[0]&.respond_to?(:url) ? args[0].relative_path : hook.block
82
+ hook_info = args[0].respond_to?(:url) ? args[0].relative_path : hook.block
83
83
  Bridgetown.logger.debug("Triggering hook:", "#{owner}:#{event} for #{hook_info}")
84
84
  end
85
85
  hook.block.call(*args)
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Bridgetown
4
4
  class Layout
5
- include DataAccessible
6
5
  include FrontMatterImporter
7
6
  include LiquidRenderable
8
7
 
@@ -44,9 +43,7 @@ module Bridgetown
44
43
  # @param file [String]
45
44
  # @return [String]
46
45
  def self.label_for_file(file)
47
- # TODO: refactor this so multi-extension layout filenames don't leak
48
- # middle extensions into layout label
49
- file.split(".")[0..-2].join(".")
46
+ file.split(".").first
50
47
  end
51
48
 
52
49
  # Initialize a new Layout.
@@ -93,6 +90,20 @@ module Bridgetown
93
90
  end
94
91
  end
95
92
 
93
+ # Returns the contents as a String.
94
+ def to_s
95
+ output || content || ""
96
+ end
97
+
98
+ # Accessor for data properties by Liquid.
99
+ #
100
+ # property - The String name of the property to retrieve.
101
+ #
102
+ # Returns the String value or nil if the property isn't included.
103
+ def [](property)
104
+ data[property]
105
+ end
106
+
96
107
  # The label of the layout (should match what would used in front matter
97
108
  # references).
98
109
  #
@@ -68,9 +68,7 @@ module Bridgetown
68
68
  private
69
69
 
70
70
  def filename_regex
71
- @filename_regex ||= begin
72
- %r!\A(#{Regexp.escape(source_dir)}/|/*)(.*)!i
73
- end
71
+ @filename_regex ||= %r!\A(#{Regexp.escape(source_dir)}/|/*)(.*)!i
74
72
  end
75
73
 
76
74
  def new_profile_hash
@@ -120,7 +120,7 @@ module Bridgetown
120
120
  # colon -
121
121
  #
122
122
  # Returns the formatted topic statement
123
- def formatted_topic(topic, colon = false)
123
+ def formatted_topic(topic, colon = false) # rubocop:disable Style/OptionalBooleanParameter
124
124
  "#{topic}#{colon ? ": " : " "}".rjust(20)
125
125
  end
126
126
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bridgetown
4
4
  class LogWriter < ::Logger
5
- def initialize
5
+ def initialize # rubocop:disable Lint/MissingSuper
6
6
  @progname = nil
7
7
  @level = DEBUG
8
8
  @default_formatter = Formatter.new
@@ -12,6 +12,12 @@ module Bridgetown
12
12
  end
13
13
  end
14
14
 
15
+ def enable_prefix
16
+ @formatter = proc do |_, _, _, msg|
17
+ "\e[32m[Bridgetown]\e[0m #{msg}"
18
+ end
19
+ end
20
+
15
21
  def add(severity, message = nil, progname = nil)
16
22
  severity ||= UNKNOWN
17
23
  @logdev = logdevice(severity)
@@ -46,8 +46,10 @@ module Bridgetown
46
46
  end
47
47
 
48
48
  class << self
49
- def build(collection_name, path, data)
50
- data = Bridgetown::Model::BuilderOrigin.new("builder://#{path}").read do
49
+ def build(builder, collection_name, path, data)
50
+ data = Bridgetown::Model::BuilderOrigin.new(
51
+ Bridgetown::Model::BuilderOrigin.id_for_builder_path(builder, path)
52
+ ).read do
51
53
  data[:_collection_] = Bridgetown::Current.site.collections[collection_name]
52
54
  data
53
55
  end
@@ -79,11 +81,17 @@ module Bridgetown
79
81
  Bridgetown::Resource::Base.new(model: self)
80
82
  end
81
83
 
84
+ # @return [Bridgetown::Resource::Base]
82
85
  def as_resource_in_collection
83
86
  collection.resources << to_resource.read!
84
87
  collection.resources.last
85
88
  end
86
89
 
90
+ # @return [Bridgetown::Resource::Base]
91
+ def render_as_resource
92
+ to_resource.read!.transform!
93
+ end
94
+
87
95
  # override if need be
88
96
  # @return [Bridgetown::Site]
89
97
  def site
@@ -114,7 +122,7 @@ module Bridgetown
114
122
  attributes.key?(method_name) || method_name.to_s.end_with?("=") || super
115
123
  end
116
124
 
117
- def method_missing(method_name, *args) # rubocop:disable Style/MethodMissingSuper
125
+ def method_missing(method_name, *args)
118
126
  return attributes[method_name] if attributes.key?(method_name)
119
127
 
120
128
  key = method_name.to_s
@@ -126,7 +134,7 @@ module Bridgetown
126
134
  end
127
135
 
128
136
  Bridgetown.logger.warn "key `#{method_name}' not found in attributes for" \
129
- " #{attributes[:id].presence || ("new " + self.class.to_s)}"
137
+ " #{attributes[:id].presence || "new #{self.class}"}"
130
138
  nil
131
139
  end
132
140
 
@@ -2,29 +2,29 @@
2
2
 
3
3
  module Bridgetown
4
4
  module Model
5
- # Abstract Superclass
6
5
  class BuilderOrigin < Origin
7
6
  # @return [Pathname]
8
7
  attr_reader :relative_path
9
8
 
10
- # Override in subclass
11
9
  def self.handle_scheme?(scheme)
12
10
  scheme == "builder"
13
11
  end
14
12
 
13
+ def self.id_for_builder_path(builder, path)
14
+ "builder://#{builder.class.name.gsub("::", ".")}/#{path}"
15
+ end
16
+
15
17
  def initialize(id)
16
- self.id = id
17
- @relative_path = Pathname.new(id.delete_prefix("builder://"))
18
+ super
19
+ @relative_path = Pathname.new(url.path.delete_prefix("/"))
20
+ end
21
+
22
+ def url
23
+ @url ||= URI.parse(id)
18
24
  end
19
25
 
20
26
  def read
21
- @data = if block_given?
22
- yield
23
- elsif defined?(SiteBuilder) && SiteBuilder.respond_to?(:data_for_id)
24
- SiteBuilder.data_for_id(id)
25
- else
26
- raise "No builder exists which can read #{id}"
27
- end
27
+ @data = block_given? ? yield : read_data_from_builder
28
28
  @data[:_id_] = id
29
29
  @data[:_origin_] = self
30
30
  @relative_path = Pathname.new(@data[:_relative_path_]) if @data[:_relative_path_]
@@ -35,6 +35,18 @@ module Bridgetown
35
35
  def exists?
36
36
  false
37
37
  end
38
+
39
+ def read_data_from_builder
40
+ builder = Kernel.const_get(url.host.gsub(".", "::"))
41
+ raise NameError unless builder.respond_to?(:resource_data_for_id)
42
+
43
+ builder.resource_data_for_id(id)
44
+ rescue NameError
45
+ raise(
46
+ Bridgetown::Errors::FatalException,
47
+ "Builder not found which can read #{id}"
48
+ )
49
+ end
38
50
  end
39
51
  end
40
52
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # See bottom of file for specific origin requires...
4
+
3
5
  module Bridgetown
4
6
  module Model
5
7
  # Abstract Superclass
@@ -36,3 +38,4 @@ end
36
38
 
37
39
  require "bridgetown-core/model/builder_origin"
38
40
  require "bridgetown-core/model/repo_origin"
41
+ require "bridgetown-core/model/plugin_origin"
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Model
5
+ class PluginOrigin < RepoOrigin
6
+ class << self
7
+ def handle_scheme?(scheme)
8
+ scheme == "plugin"
9
+ end
10
+ end
11
+
12
+ def manifest
13
+ @manifest ||= begin
14
+ manifest_origin = Addressable::URI.unescape(url.path.delete_prefix("/")).split("/").first
15
+ Bridgetown::PluginManager.source_manifests.find do |manifest|
16
+ manifest.origin.to_s == manifest_origin
17
+ end.tap do |manifest|
18
+ raise "Unable to locate a source manifest for #{manifest_origin}" unless manifest
19
+ end
20
+ end
21
+ end
22
+
23
+ def relative_path
24
+ @relative_path ||= Pathname.new(
25
+ Addressable::URI.unescape(url.path.delete_prefix("/")).split("/")[1..-1].join("/")
26
+ )
27
+ end
28
+
29
+ def original_path
30
+ @original_path ||= relative_path.expand_path(manifest.content)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -47,7 +47,7 @@ module Bridgetown
47
47
  end
48
48
 
49
49
  def url
50
- @url = URI.parse(id)
50
+ @url ||= URI.parse(id)
51
51
  end
52
52
 
53
53
  def relative_path