bridgetown-core 0.12.0 → 0.15.0.beta1

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/bin/bridgetown +9 -48
  4. data/bridgetown-core.gemspec +10 -5
  5. data/lib/bridgetown-core.rb +20 -4
  6. data/lib/bridgetown-core/cleaner.rb +1 -0
  7. data/lib/bridgetown-core/commands/apply.rb +73 -0
  8. data/lib/bridgetown-core/commands/base.rb +45 -0
  9. data/lib/bridgetown-core/commands/build.rb +91 -86
  10. data/lib/bridgetown-core/commands/clean.rb +30 -29
  11. data/lib/bridgetown-core/commands/concerns/actions.rb +95 -0
  12. data/lib/bridgetown-core/commands/concerns/build_options.rb +76 -0
  13. data/lib/bridgetown-core/commands/concerns/configuration_overridable.rb +18 -0
  14. data/lib/bridgetown-core/commands/concerns/summarizable.rb +13 -0
  15. data/lib/bridgetown-core/commands/console.rb +46 -38
  16. data/lib/bridgetown-core/commands/doctor.rb +125 -135
  17. data/lib/bridgetown-core/commands/new.rb +120 -158
  18. data/lib/bridgetown-core/commands/plugins.rb +206 -0
  19. data/lib/bridgetown-core/commands/registrations.rb +16 -0
  20. data/lib/bridgetown-core/commands/serve.rb +214 -217
  21. data/lib/bridgetown-core/{convertible.rb → concerns/convertible.rb} +2 -2
  22. data/lib/bridgetown-core/concerns/site/configurable.rb +153 -0
  23. data/lib/bridgetown-core/concerns/site/content.rb +111 -0
  24. data/lib/bridgetown-core/concerns/site/extensible.rb +56 -0
  25. data/lib/bridgetown-core/concerns/site/processable.rb +74 -0
  26. data/lib/bridgetown-core/concerns/site/renderable.rb +50 -0
  27. data/lib/bridgetown-core/concerns/site/writable.rb +31 -0
  28. data/lib/bridgetown-core/configuration.rb +98 -108
  29. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +0 -3
  30. data/lib/bridgetown-core/document.rb +1 -1
  31. data/lib/bridgetown-core/drops/bridgetown_drop.rb +6 -1
  32. data/lib/bridgetown-core/drops/site_drop.rb +1 -2
  33. data/lib/bridgetown-core/external.rb +17 -21
  34. data/lib/bridgetown-core/filters.rb +10 -0
  35. data/lib/bridgetown-core/generators/prototype_generator.rb +3 -1
  36. data/lib/bridgetown-core/hooks.rb +62 -62
  37. data/lib/bridgetown-core/layout.rb +10 -4
  38. data/lib/bridgetown-core/liquid_renderer.rb +2 -0
  39. data/lib/bridgetown-core/liquid_renderer/file_system.rb +5 -1
  40. data/lib/bridgetown-core/page.rb +9 -2
  41. data/lib/bridgetown-core/plugin.rb +2 -0
  42. data/lib/bridgetown-core/plugin_manager.rb +68 -14
  43. data/lib/bridgetown-core/reader.rb +5 -0
  44. data/lib/bridgetown-core/readers/data_reader.rb +15 -2
  45. data/lib/bridgetown-core/readers/layout_reader.rb +9 -2
  46. data/lib/bridgetown-core/readers/plugin_content_reader.rb +48 -0
  47. data/lib/bridgetown-core/renderer.rb +51 -32
  48. data/lib/bridgetown-core/site.rb +20 -449
  49. data/lib/bridgetown-core/static_file.rb +1 -5
  50. data/lib/bridgetown-core/tags/include.rb +12 -0
  51. data/lib/bridgetown-core/tags/render_content.rb +27 -16
  52. data/lib/bridgetown-core/tags/with.rb +15 -0
  53. data/lib/bridgetown-core/utils.rb +2 -27
  54. data/lib/bridgetown-core/utils/ruby_exec.rb +66 -0
  55. data/lib/bridgetown-core/version.rb +2 -2
  56. data/lib/bridgetown-core/watcher.rb +21 -10
  57. data/lib/site_template/Gemfile.erb +19 -0
  58. data/lib/site_template/plugins/{.keep → builders/.keep} +0 -0
  59. data/lib/site_template/plugins/site_builder.rb +4 -0
  60. data/lib/site_template/src/_components/footer.html +3 -0
  61. data/lib/site_template/src/_components/head.html +9 -0
  62. data/lib/site_template/src/{_includes → _components}/navbar.html +1 -0
  63. data/lib/site_template/src/_layouts/default.html +3 -3
  64. data/lib/site_template/src/{_components/.keep → favicon.ico} +0 -0
  65. data/lib/site_template/src/posts.md +15 -0
  66. data/lib/site_template/start.js +1 -1
  67. metadata +107 -19
  68. data/lib/bridgetown-core/command.rb +0 -106
  69. data/lib/bridgetown-core/commands/help.rb +0 -34
  70. data/lib/site_template/src/_includes/footer.html +0 -3
  71. data/lib/site_template/src/_includes/head.html +0 -9
@@ -14,6 +14,13 @@ module Bridgetown
14
14
  Layout.new(site, layout_directory, layout_file)
15
15
  end
16
16
 
17
+ Bridgetown::PluginManager.source_manifests.map(&:layouts).compact.each do |plugin_layouts|
18
+ layout_entries(plugin_layouts).each do |layout_file|
19
+ @layouts[layout_name(layout_file)] ||= \
20
+ Layout.new(site, plugin_layouts, layout_file, from_plugin: true)
21
+ end
22
+ end
23
+
17
24
  @layouts
18
25
  end
19
26
 
@@ -23,8 +30,8 @@ module Bridgetown
23
30
 
24
31
  private
25
32
 
26
- def layout_entries
27
- entries_in layout_directory
33
+ def layout_entries(dir = layout_directory)
34
+ entries_in dir
28
35
  end
29
36
 
30
37
  def entries_in(dir)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class PluginContentReader
5
+ attr_reader :site, :content_dir
6
+
7
+ def initialize(site, plugin_content_dir)
8
+ @site = site
9
+ @content_dir = plugin_content_dir
10
+ @content_files = Set.new
11
+ end
12
+
13
+ def read
14
+ return unless content_dir
15
+
16
+ Find.find(content_dir) do |path|
17
+ next if File.directory?(path)
18
+
19
+ if File.symlink?(path)
20
+ Bridgetown.logger.warn "Plugin content reader:", "Ignored symlinked asset: #{path}"
21
+ else
22
+ read_content_file(path)
23
+ end
24
+ end
25
+ end
26
+
27
+ def read_content_file(path)
28
+ dir = File.dirname(path.sub("#{content_dir}/", ""))
29
+ name = File.basename(path)
30
+
31
+ @content_files << if Utils.has_yaml_header?(path)
32
+ Bridgetown::Page.new(site, content_dir, dir, name, from_plugin: true)
33
+ else
34
+ Bridgetown::StaticFile.new(site, content_dir, "/#{dir}", name)
35
+ end
36
+
37
+ add_to(site.pages, Bridgetown::Page)
38
+ add_to(site.static_files, Bridgetown::StaticFile)
39
+ end
40
+
41
+ def add_to(content_type, klass)
42
+ existing_paths = content_type.map(&:relative_path).compact
43
+ @content_files.select { |item| item.is_a?(klass) }.each do |item|
44
+ content_type << item unless existing_paths.include?(item.relative_path)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -5,11 +5,16 @@ module Bridgetown
5
5
  attr_reader :document, :site
6
6
  attr_writer :layouts, :payload
7
7
 
8
+ class << self
9
+ attr_accessor :cached_partials
10
+ end
11
+
8
12
  def initialize(site, document, site_payload = nil)
9
13
  @site = site
10
14
  @document = document
11
15
  @payload = site_payload
12
16
  @layouts = nil
17
+ self.class.cached_partials ||= {}
13
18
  end
14
19
 
15
20
  # Fetches the payload used in Liquid rendering.
@@ -57,7 +62,6 @@ module Bridgetown
57
62
  assign_highlighter_options!
58
63
  assign_layout_data!
59
64
 
60
- Bridgetown.logger.debug "Pre-Render Hooks:", document.relative_path
61
65
  document.trigger_hooks(:pre_render, payload)
62
66
 
63
67
  render_document
@@ -68,16 +72,14 @@ module Bridgetown
68
72
  # Returns String rendered document output
69
73
  # rubocop: disable Metrics/AbcSize
70
74
  def render_document
71
- info = {
72
- registers: { site: site, page: payload["page"] },
73
- strict_filters: liquid_options["strict_filters"],
74
- strict_variables: liquid_options["strict_variables"],
75
- }
75
+ liquid_context = provide_liquid_context
76
+
77
+ execute_inline_ruby!
76
78
 
77
79
  output = document.content
78
80
  if document.render_with_liquid?
79
81
  Bridgetown.logger.debug "Rendering Liquid:", document.relative_path
80
- output = render_liquid(output, payload, info, document.path)
82
+ output = render_liquid(output, payload, liquid_context, document.path)
81
83
  end
82
84
 
83
85
  Bridgetown.logger.debug "Rendering Markup:", document.relative_path
@@ -86,45 +88,47 @@ module Bridgetown
86
88
 
87
89
  if document.place_in_layout?
88
90
  Bridgetown.logger.debug "Rendering Layout:", document.relative_path
89
- output = place_in_layouts(output, payload, info)
91
+ output = place_in_layouts(output, payload, liquid_context)
90
92
  end
91
93
 
92
94
  output
93
95
  end
94
- # rubocop: enable Metrics/AbcSize
95
96
 
96
- # Convert the document using the converters which match this renderer's document.
97
- #
98
- # Returns String the converted content.
99
- def convert(content)
100
- converters.reduce(content) do |output, converter|
101
- begin
102
- converter.convert output
103
- rescue StandardError => e
104
- Bridgetown.logger.error "Conversion error:",
105
- "#{converter.class} encountered an error while "\
106
- "converting '#{document.relative_path}':"
107
- Bridgetown.logger.error("", e.to_s)
108
- raise e
109
- end
110
- end
97
+ def provide_liquid_context
98
+ {
99
+ registers: {
100
+ site: site,
101
+ page: payload["page"],
102
+ cached_partials: self.class.cached_partials,
103
+ },
104
+ strict_filters: liquid_options["strict_filters"],
105
+ strict_variables: liquid_options["strict_variables"],
106
+ }
107
+ end
108
+
109
+ def execute_inline_ruby!
110
+ return unless site.config.should_execute_inline_ruby?
111
+
112
+ Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document, self)
111
113
  end
112
114
 
113
- # Render the given content with the payload and info
115
+ # rubocop: enable Metrics/AbcSize
116
+
117
+ # Render the given content with the payload and context
114
118
  #
115
119
  # content -
116
120
  # payload -
117
- # info -
121
+ # context -
118
122
  # path - (optional) the path to the file, for use in ex
119
123
  #
120
124
  # Returns String the content, rendered by Liquid.
121
- def render_liquid(content, payload, info, path = nil)
125
+ def render_liquid(content, payload, liquid_context, path = nil)
122
126
  template = site.liquid_renderer.file(path).parse(content)
123
127
  template.warnings.each do |e|
124
128
  Bridgetown.logger.warn "Liquid Warning:",
125
129
  LiquidRenderer.format_error(e, path || document.relative_path)
126
130
  end
127
- template.render!(payload, info)
131
+ template.render!(payload, liquid_context)
128
132
  # rubocop: disable Lint/RescueException
129
133
  rescue Exception => e
130
134
  Bridgetown.logger.error "Liquid Exception:",
@@ -133,6 +137,21 @@ module Bridgetown
133
137
  end
134
138
  # rubocop: enable Lint/RescueException
135
139
 
140
+ # Convert the document using the converters which match this renderer's document.
141
+ #
142
+ # Returns String the converted content.
143
+ def convert(content)
144
+ converters.reduce(content) do |output, converter|
145
+ converter.convert output
146
+ rescue StandardError => e
147
+ Bridgetown.logger.error "Conversion error:",
148
+ "#{converter.class} encountered an error while "\
149
+ "converting '#{document.relative_path}':"
150
+ Bridgetown.logger.error("", e.to_s)
151
+ raise e
152
+ end
153
+ end
154
+
136
155
  # Checks if the layout specified in the document actually exists
137
156
  #
138
157
  # layout - the layout to check
@@ -145,7 +164,7 @@ module Bridgetown
145
164
  # Render layouts and place document content inside.
146
165
  #
147
166
  # Returns String rendered content
148
- def place_in_layouts(content, payload, info)
167
+ def place_in_layouts(content, payload, liquid_context)
149
168
  output = content.dup
150
169
  layout = layouts[document.data["layout"].to_s]
151
170
  validate_layout(layout)
@@ -156,7 +175,7 @@ module Bridgetown
156
175
  payload["layout"] = nil
157
176
 
158
177
  while layout
159
- output = render_layout(output, layout, info)
178
+ output = render_layout(output, layout, liquid_context)
160
179
  add_regenerator_dependencies(layout)
161
180
 
162
181
  next unless (layout = site.layouts[layout.data["layout"]])
@@ -183,14 +202,14 @@ module Bridgetown
183
202
  # Render layout content into document.output
184
203
  #
185
204
  # Returns String rendered content
186
- def render_layout(output, layout, info)
205
+ def render_layout(output, layout, liquid_context)
187
206
  payload["content"] = output
188
207
  payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
189
208
 
190
209
  render_liquid(
191
210
  layout.content,
192
211
  payload,
193
- info,
212
+ liquid_context,
194
213
  layout.path
195
214
  )
196
215
  end
@@ -2,125 +2,43 @@
2
2
 
3
3
  module Bridgetown
4
4
  class Site
5
- attr_reader :root_dir, :source, :dest, :cache_dir, :config
5
+ require_all "bridgetown-core/concerns/site"
6
+
7
+ include Configurable
8
+ include Content
9
+ include Extensible
10
+ include Processable
11
+ include Renderable
12
+ include Writable
13
+
14
+ attr_reader :root_dir, :source, :dest, :cache_dir, :config,
15
+ :regenerator, :liquid_renderer, :components_load_paths,
16
+ :includes_load_paths
6
17
  attr_accessor :layouts, :pages, :static_files,
7
18
  :exclude, :include, :lsi, :highlighter, :permalink_style,
8
- :time, :future, :unpublished, :plugins, :limit_posts,
19
+ :time, :future, :unpublished, :limit_posts,
9
20
  :keep_files, :baseurl, :data, :file_read_opts,
10
- :plugin_manager
11
-
12
- attr_accessor :converters, :generators, :reader
13
- attr_reader :regenerator, :liquid_renderer, :components_load_paths,
14
- :includes_load_paths
21
+ :plugin_manager, :converters, :generators, :reader
15
22
 
16
23
  # Public: Initialize a new Site.
17
24
  #
18
25
  # config - A Hash containing site configuration details.
19
26
  def initialize(config)
20
- # Source and destination may not be changed after the site has been created.
21
- @root_dir = File.expand_path(config["root_dir"]).freeze
22
- @source = File.expand_path(config["source"]).freeze
23
- @dest = File.expand_path(config["destination"]).freeze
24
-
25
27
  self.config = config
26
28
 
27
- @cache_dir = in_root_dir(config["cache_dir"])
29
+ @plugin_manager = PluginManager.new(self)
30
+ @cleaner = Cleaner.new(self)
28
31
  @reader = Reader.new(self)
29
32
  @regenerator = Regenerator.new(self)
30
33
  @liquid_renderer = LiquidRenderer.new(self)
31
34
 
32
- Bridgetown.sites << self
33
-
34
- reset
35
- setup
36
-
37
- Bridgetown::Hooks.trigger :site, :after_init, self
38
- end
39
-
40
- # Public: Set the site's configuration. This handles side-effects caused by
41
- # changing values in the configuration.
42
- #
43
- # config - a Bridgetown::Configuration, containing the new configuration.
44
- #
45
- # Returns the new configuration.
46
- def config=(config)
47
- @config = config.clone
48
-
49
- %w(lsi highlighter baseurl exclude include future unpublished
50
- limit_posts keep_files).each do |opt|
51
- send("#{opt}=", config[opt])
52
- end
53
-
54
- configure_cache
55
- configure_plugins
56
- configure_component_paths
57
- configure_include_paths
58
- configure_file_read_opts
59
-
60
- self.permalink_style = config["permalink"].to_sym
61
-
62
- @config
63
- end
64
-
65
- # Public: Read, process, and write this Site to output.
66
- #
67
- # Returns nothing.
68
- def process
69
- reset
70
- read
71
- generate
72
- render
73
- cleanup
74
- write
75
- print_stats if config["profile"]
76
- end
77
-
78
- def print_stats
79
- Bridgetown.logger.info @liquid_renderer.stats_table
80
- end
81
-
82
- # rubocop:disable Metrics/MethodLength
83
- #
84
- # Reset Site details.
85
- #
86
- # Returns nothing
87
- def reset
88
- self.time = if config["time"]
89
- Utils.parse_date(config["time"].to_s, "Invalid time in bridgetown.config.yml.")
90
- else
91
- Time.now
92
- end
93
- self.layouts = {}
94
- self.pages = []
95
- self.static_files = []
96
- self.data = {}
97
- @post_attr_hash = {}
98
- @site_data = nil
99
- @collections = nil
100
- @documents = nil
101
- @docs_to_write = nil
102
- @regenerator.clear_cache
103
- @liquid_renderer.reset
104
- @site_cleaner = nil
105
- frontmatter_defaults.reset
106
-
107
- raise ArgumentError, "limit_posts must be a non-negative number" if limit_posts.negative?
108
-
109
- Bridgetown::Cache.clear_if_config_changed config
110
- Bridgetown::Hooks.trigger :site, :after_reset, self
111
- end
112
- # rubocop:enable Metrics/MethodLength
113
-
114
- # Load necessary libraries, plugins, converters, and generators.
115
- #
116
- # Returns nothing.
117
- def setup
118
35
  ensure_not_in_dest
119
36
 
120
- plugin_manager.conscientious_require
37
+ Bridgetown.sites << self
38
+ Bridgetown::Hooks.trigger :site, :after_init, self
121
39
 
122
- self.converters = instantiate_subclasses(Bridgetown::Converter)
123
- self.generators = instantiate_subclasses(Bridgetown::Generator)
40
+ reset # Processable
41
+ setup # Extensible
124
42
  end
125
43
 
126
44
  # Check that the destination dir isn't the source dir or a directory
@@ -134,352 +52,5 @@ module Bridgetown
134
52
  end
135
53
  end
136
54
  end
137
-
138
- # The list of collections and their corresponding Bridgetown::Collection instances.
139
- # If config['collections'] is set, a new instance is created
140
- # for each item in the collection, a new hash is returned otherwise.
141
- #
142
- # Returns a Hash containing collection name-to-instance pairs.
143
- def collections
144
- @collections ||= collection_names.each_with_object({}) do |name, hsh|
145
- hsh[name] = Bridgetown::Collection.new(self, name)
146
- end
147
- end
148
-
149
- # The list of collection names.
150
- #
151
- # Returns an array of collection names from the configuration,
152
- # or an empty array if the `collections` key is not set.
153
- def collection_names
154
- case config["collections"]
155
- when Hash
156
- config["collections"].keys
157
- when Array
158
- config["collections"]
159
- when nil
160
- []
161
- else
162
- raise ArgumentError, "Your `collections` key must be a hash or an array."
163
- end
164
- end
165
-
166
- # Read Site data from disk and load it into internal data structures.
167
- #
168
- # Returns nothing.
169
- def read
170
- reader.read
171
- limit_posts!
172
- Bridgetown::Hooks.trigger :site, :post_read, self
173
- end
174
-
175
- # Run each of the Generators.
176
- #
177
- # Returns nothing.
178
- def generate
179
- generators.each do |generator|
180
- start = Time.now
181
- generator.generate(self)
182
- Bridgetown.logger.debug "Generating:",
183
- "#{generator.class} finished in #{Time.now - start} seconds."
184
- end
185
- end
186
-
187
- # Render the site to the destination.
188
- #
189
- # Returns nothing.
190
- def render
191
- payload = site_payload
192
-
193
- Bridgetown::Hooks.trigger :site, :pre_render, self, payload
194
-
195
- render_docs(payload)
196
- render_pages(payload)
197
-
198
- Bridgetown::Hooks.trigger :site, :post_render, self, payload
199
- end
200
-
201
- # Remove orphaned files and empty directories in destination.
202
- #
203
- # Returns nothing.
204
- def cleanup
205
- site_cleaner.cleanup!
206
- end
207
-
208
- # Write static files, pages, and posts.
209
- #
210
- # Returns nothing.
211
- def write
212
- each_site_file do |item|
213
- item.write(dest) if regenerator.regenerate?(item)
214
- end
215
- regenerator.write_metadata
216
- Bridgetown::Hooks.trigger :site, :post_write, self
217
- end
218
-
219
- def posts
220
- collections["posts"] ||= Collection.new(self, "posts")
221
- end
222
-
223
- # Construct a Hash of Posts indexed by the specified Post attribute.
224
- #
225
- # post_attr - The String name of the Post attribute.
226
- #
227
- # Examples
228
- #
229
- # post_attr_hash('categories')
230
- # # => { 'tech' => [<Post A>, <Post B>],
231
- # # 'ruby' => [<Post B>] }
232
- #
233
- # Returns the Hash: { attr => posts } where
234
- # attr - One of the values for the requested attribute.
235
- # posts - The Array of Posts with the given attr value.
236
- def post_attr_hash(post_attr)
237
- # Build a hash map based on the specified post attribute ( post attr =>
238
- # array of posts ) then sort each array in reverse order.
239
- @post_attr_hash[post_attr] ||= begin
240
- hash = Hash.new { |h, key| h[key] = [] }
241
- posts.docs.each do |p|
242
- p.data[post_attr]&.each { |t| hash[t] << p }
243
- end
244
- hash.each_value { |posts| posts.sort!.reverse! }
245
- hash
246
- end
247
- end
248
-
249
- def tags
250
- post_attr_hash("tags")
251
- end
252
-
253
- def categories
254
- post_attr_hash("categories")
255
- end
256
-
257
- # Prepare site data for site payload. The method maintains backward compatibility
258
- # if the key 'data' is already used in bridgetown.config.yml.
259
- #
260
- # Returns the Hash to be hooked to site.data.
261
- def site_data
262
- @site_data ||= (config["data"] || data)
263
- end
264
-
265
- # The Hash payload containing site-wide data.
266
- #
267
- # Returns the Hash: { "site" => data } where data is a Hash with keys:
268
- # "time" - The Time as specified in the configuration or the
269
- # current time if none was specified.
270
- # "posts" - The Array of Posts, sorted chronologically by post date
271
- # and then title.
272
- # "pages" - The Array of all Pages.
273
- # "html_pages" - The Array of HTML Pages.
274
- # "categories" - The Hash of category values and Posts.
275
- # See Site#post_attr_hash for type info.
276
- # "tags" - The Hash of tag values and Posts.
277
- # See Site#post_attr_hash for type info.
278
- def site_payload
279
- Drops::UnifiedPayloadDrop.new self
280
- end
281
- alias_method :to_liquid, :site_payload
282
-
283
- # Get the implementation class for the given Converter.
284
- # Returns the Converter instance implementing the given Converter.
285
- # klass - The Class of the Converter to fetch.
286
- def find_converter_instance(klass)
287
- @find_converter_instance ||= {}
288
- @find_converter_instance[klass] ||= begin
289
- converters.find { |converter| converter.instance_of?(klass) } || \
290
- raise("No Converters found for #{klass}")
291
- end
292
- end
293
-
294
- # klass - class or module containing the subclasses.
295
- # Returns array of instances of subclasses of parameter.
296
- # Create array of instances of the subclasses of the class or module
297
- # passed in as argument.
298
-
299
- def instantiate_subclasses(klass)
300
- klass.descendants.sort.map do |c|
301
- c.new(config)
302
- end
303
- end
304
-
305
- # Get the to be written documents
306
- #
307
- # Returns an Array of Documents which should be written
308
- def docs_to_write
309
- documents.select(&:write?)
310
- end
311
-
312
- # Get all the documents
313
- #
314
- # Returns an Array of all Documents
315
- def documents
316
- collections.each_with_object(Set.new) do |(_, collection), set|
317
- set.merge(collection.docs).merge(collection.files)
318
- end.to_a
319
- end
320
-
321
- def each_site_file
322
- %w(pages static_files docs_to_write).each do |type|
323
- send(type).each do |item|
324
- yield item
325
- end
326
- end
327
- end
328
-
329
- # Returns the FrontmatterDefaults or creates a new FrontmatterDefaults
330
- # if it doesn't already exist.
331
- #
332
- # Returns The FrontmatterDefaults
333
- def frontmatter_defaults
334
- @frontmatter_defaults ||= FrontmatterDefaults.new(self)
335
- end
336
-
337
- # Whether to perform a full rebuild without incremental regeneration
338
- #
339
- # Returns a Boolean: true for a full rebuild, false for normal build
340
- def incremental?(override = {})
341
- override["incremental"] || config["incremental"]
342
- end
343
-
344
- # Returns the publisher or creates a new publisher if it doesn't
345
- # already exist.
346
- #
347
- # Returns The Publisher
348
- def publisher
349
- @publisher ||= Publisher.new(self)
350
- end
351
-
352
- # Public: Prefix a given path with the root directory.
353
- #
354
- # paths - (optional) path elements to a file or directory within the
355
- # root directory
356
- #
357
- # Returns a path which is prefixed with the root_dir directory.
358
- def in_root_dir(*paths)
359
- paths.reduce(root_dir) do |base, path|
360
- Bridgetown.sanitized_path(base, path)
361
- end
362
- end
363
-
364
- # Public: Prefix a given path with the source directory.
365
- #
366
- # paths - (optional) path elements to a file or directory within the
367
- # source directory
368
- #
369
- # Returns a path which is prefixed with the source directory.
370
- def in_source_dir(*paths)
371
- paths.reduce(source) do |base, path|
372
- Bridgetown.sanitized_path(base, path)
373
- end
374
- end
375
-
376
- # Public: Prefix a given path with the destination directory.
377
- #
378
- # paths - (optional) path elements to a file or directory within the
379
- # destination directory
380
- #
381
- # Returns a path which is prefixed with the destination directory.
382
- def in_dest_dir(*paths)
383
- paths.reduce(dest) do |base, path|
384
- Bridgetown.sanitized_path(base, path)
385
- end
386
- end
387
-
388
- # Public: Prefix a given path with the cache directory.
389
- #
390
- # paths - (optional) path elements to a file or directory within the
391
- # cache directory
392
- #
393
- # Returns a path which is prefixed with the cache directory.
394
- def in_cache_dir(*paths)
395
- paths.reduce(cache_dir) do |base, path|
396
- Bridgetown.sanitized_path(base, path)
397
- end
398
- end
399
-
400
- # Public: The full path to the directory that houses all the collections registered
401
- # with the current site.
402
- #
403
- # Returns the source directory or the absolute path to the custom collections_dir
404
- def collections_path
405
- dir_str = config["collections_dir"]
406
- @collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
407
- end
408
-
409
- private
410
-
411
- # Limits the current posts; removes the posts which exceed the limit_posts
412
- #
413
- # Returns nothing
414
- def limit_posts!
415
- if limit_posts.positive?
416
- limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
417
- posts.docs = posts.docs[-limit, limit]
418
- end
419
- end
420
-
421
- # Returns the Cleaner or creates a new Cleaner if it doesn't
422
- # already exist.
423
- #
424
- # Returns The Cleaner
425
- def site_cleaner
426
- @site_cleaner ||= Cleaner.new(self)
427
- end
428
-
429
- # Disable Marshaling cache to disk in Safe Mode
430
- def configure_cache
431
- Bridgetown::Cache.cache_dir = in_root_dir(config["cache_dir"], "Bridgetown/Cache")
432
- Bridgetown::Cache.disable_disk_cache! if config["disable_disk_cache"]
433
- end
434
-
435
- def configure_plugins
436
- self.plugin_manager = Bridgetown::PluginManager.new(self)
437
- self.plugins = plugin_manager.plugins_path
438
- end
439
-
440
- def configure_component_paths
441
- @components_load_paths = config["components_dir"].then do |dir|
442
- dir.is_a?(Array) ? dir : [dir]
443
- end
444
- @components_load_paths.map! do |dir|
445
- if !!(dir =~ %r!^\.\.?\/!)
446
- # allow ./dir or ../../dir type options
447
- File.expand_path(dir.to_s, root_dir)
448
- else
449
- in_source_dir(dir.to_s)
450
- end
451
- end
452
- end
453
-
454
- def configure_include_paths
455
- @includes_load_paths = Array(in_source_dir(config["includes_dir"].to_s))
456
- end
457
-
458
- def configure_file_read_opts
459
- self.file_read_opts = {}
460
- file_read_opts[:encoding] = config["encoding"] if config["encoding"]
461
- self.file_read_opts = Bridgetown::Utils.merged_file_read_opts(self, {})
462
- end
463
-
464
- def render_docs(payload)
465
- collections.each_value do |collection|
466
- collection.docs.each do |document|
467
- render_regenerated(document, payload)
468
- end
469
- end
470
- end
471
-
472
- def render_pages(payload)
473
- pages.each do |page|
474
- render_regenerated(page, payload)
475
- end
476
- end
477
-
478
- def render_regenerated(document, payload)
479
- return unless regenerator.regenerate?(document)
480
-
481
- document.output = Bridgetown::Renderer.new(self, document, payload).run
482
- document.trigger_hooks(:post_render)
483
- end
484
55
  end
485
56
  end