bridgetown-core 0.19.3 → 0.21.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/bridgetown-core.gemspec +1 -2
  3. data/lib/bridgetown-core.rb +37 -29
  4. data/lib/bridgetown-core/cleaner.rb +9 -3
  5. data/lib/bridgetown-core/collection.rb +177 -78
  6. data/lib/bridgetown-core/commands/base.rb +9 -0
  7. data/lib/bridgetown-core/commands/build.rb +0 -11
  8. data/lib/bridgetown-core/commands/concerns/git_helpers.rb +20 -0
  9. data/lib/bridgetown-core/commands/configure.rb +8 -3
  10. data/lib/bridgetown-core/commands/console.rb +4 -0
  11. data/lib/bridgetown-core/commands/doctor.rb +1 -19
  12. data/lib/bridgetown-core/commands/new.rb +6 -6
  13. data/lib/bridgetown-core/commands/plugins.rb +14 -13
  14. data/lib/bridgetown-core/commands/serve.rb +0 -14
  15. data/lib/bridgetown-core/commands/webpack.rb +75 -0
  16. data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +12 -0
  17. data/lib/bridgetown-core/commands/webpack/setup.rb +4 -0
  18. data/lib/bridgetown-core/commands/webpack/update.rb +3 -0
  19. data/lib/bridgetown-core/commands/webpack/webpack.config.js +18 -0
  20. data/lib/{site_template/webpack.config.js.erb → bridgetown-core/commands/webpack/webpack.defaults.js.erb} +32 -16
  21. data/lib/bridgetown-core/component.rb +183 -0
  22. data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
  23. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  24. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  25. data/lib/bridgetown-core/concerns/site/configurable.rb +10 -10
  26. data/lib/bridgetown-core/concerns/site/content.rb +56 -15
  27. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -5
  28. data/lib/bridgetown-core/concerns/site/processable.rb +6 -4
  29. data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
  30. data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
  31. data/lib/bridgetown-core/concerns/validatable.rb +2 -5
  32. data/lib/bridgetown-core/configuration.rb +61 -33
  33. data/lib/bridgetown-core/configurations/bt-postcss.rb +6 -6
  34. data/lib/bridgetown-core/configurations/netlify.rb +1 -0
  35. data/lib/bridgetown-core/configurations/tailwindcss.rb +6 -6
  36. data/lib/bridgetown-core/converter.rb +23 -0
  37. data/lib/bridgetown-core/converters/erb_templates.rb +51 -35
  38. data/lib/bridgetown-core/converters/identity.rb +0 -9
  39. data/lib/bridgetown-core/converters/liquid_templates.rb +1 -1
  40. data/lib/bridgetown-core/converters/markdown.rb +14 -4
  41. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +5 -38
  42. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  43. data/lib/bridgetown-core/converters/smartypants.rb +3 -1
  44. data/lib/bridgetown-core/core_ext/psych.rb +19 -0
  45. data/lib/bridgetown-core/current.rb +10 -0
  46. data/lib/bridgetown-core/document.rb +9 -16
  47. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  48. data/lib/bridgetown-core/drops/page_drop.rb +4 -0
  49. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  50. data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
  51. data/lib/bridgetown-core/drops/site_drop.rb +33 -8
  52. data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
  53. data/lib/bridgetown-core/entry_filter.rb +17 -28
  54. data/lib/bridgetown-core/errors.rb +0 -2
  55. data/lib/bridgetown-core/filters.rb +3 -26
  56. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  57. data/lib/bridgetown-core/filters/url_filters.rb +12 -0
  58. data/lib/bridgetown-core/frontmatter_defaults.rb +1 -1
  59. data/lib/bridgetown-core/generators/prototype_generator.rb +59 -20
  60. data/lib/bridgetown-core/helpers.rb +48 -9
  61. data/lib/bridgetown-core/layout.rb +53 -21
  62. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
  63. data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
  64. data/lib/bridgetown-core/model/base.rb +138 -0
  65. data/lib/bridgetown-core/model/builder_origin.rb +40 -0
  66. data/lib/bridgetown-core/model/origin.rb +38 -0
  67. data/lib/bridgetown-core/model/repo_origin.rb +126 -0
  68. data/lib/bridgetown-core/page.rb +11 -2
  69. data/lib/bridgetown-core/plugin_manager.rb +1 -3
  70. data/lib/bridgetown-core/publisher.rb +8 -2
  71. data/lib/bridgetown-core/reader.rb +37 -22
  72. data/lib/bridgetown-core/readers/data_reader.rb +5 -5
  73. data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
  74. data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
  75. data/lib/bridgetown-core/readers/page_reader.rb +1 -0
  76. data/lib/bridgetown-core/readers/post_reader.rb +5 -4
  77. data/lib/bridgetown-core/regenerator.rb +9 -2
  78. data/lib/bridgetown-core/related_posts.rb +9 -6
  79. data/lib/bridgetown-core/renderer.rb +6 -13
  80. data/lib/bridgetown-core/resource/base.rb +329 -0
  81. data/lib/bridgetown-core/resource/destination.rb +49 -0
  82. data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
  83. data/lib/bridgetown-core/resource/relations.rb +132 -0
  84. data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
  85. data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
  86. data/lib/bridgetown-core/resource/transformer.rb +177 -0
  87. data/lib/bridgetown-core/ruby_template_view.rb +11 -11
  88. data/lib/bridgetown-core/site.rb +13 -6
  89. data/lib/bridgetown-core/static_file.rb +33 -10
  90. data/lib/bridgetown-core/tags/highlight.rb +2 -15
  91. data/lib/bridgetown-core/tags/include.rb +1 -1
  92. data/lib/bridgetown-core/tags/post_url.rb +2 -2
  93. data/lib/bridgetown-core/url.rb +1 -0
  94. data/lib/bridgetown-core/utils.rb +49 -43
  95. data/lib/bridgetown-core/utils/require_gems.rb +60 -0
  96. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  97. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  98. data/lib/bridgetown-core/version.rb +2 -2
  99. data/lib/bridgetown-core/watcher.rb +2 -1
  100. data/lib/bridgetown-core/yaml_parser.rb +22 -0
  101. data/lib/site_template/config/.keep +0 -0
  102. data/lib/site_template/package.json.erb +4 -4
  103. data/lib/site_template/plugins/site_builder.rb +1 -1
  104. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
  105. metadata +46 -41
  106. data/lib/bridgetown-core/external.rb +0 -58
  107. data/lib/bridgetown-core/page_without_a_file.rb +0 -17
  108. data/lib/bridgetown-core/path_manager.rb +0 -31
  109. data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
  110. data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
  111. data/lib/bridgetown-core/utils/exec.rb +0 -26
  112. data/lib/bridgetown-core/utils/internet.rb +0 -37
  113. data/lib/bridgetown-core/utils/platforms.rb +0 -80
  114. data/lib/bridgetown-core/utils/thread_event.rb +0 -31
  115. data/lib/bridgetown-core/utils/win_tz.rb +0 -75
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class Component
5
+ extend Forwardable
6
+
7
+ def_delegators :@view_context, :helpers, :liquid_render, :partial
8
+
9
+ # @return [Bridgetown::Site]
10
+ attr_reader :site # will be nil unless you explicitly set a `@site` ivar
11
+
12
+ # @return [Bridgetown::RubyTemplateView, Bridgetown::Component]
13
+ attr_reader :view_context
14
+
15
+ class << self
16
+ attr_accessor :source_location
17
+
18
+ def inherited(child)
19
+ # Code cribbed from ViewComponent by GitHub:
20
+ # Derive the source location of the component Ruby file from the call stack
21
+ child.source_location = caller_locations(1, 10).reject do |l|
22
+ l.label == "inherited"
23
+ end[0].absolute_path
24
+
25
+ super
26
+ end
27
+
28
+ # Return the appropriate template renderer for a given extension.
29
+ # TODO: make this extensible
30
+ #
31
+ # @param ext [String] erb, slim, etc.
32
+ def renderer_for_ext(ext, &block)
33
+ @_tmpl ||= case ext
34
+ when "erb"
35
+ include ERBCapture
36
+ Tilt::ErubiTemplate.new(component_template_path,
37
+ outvar: "@_erbout",
38
+ bufval: "Bridgetown::OutputBuffer.new",
39
+ engine_class: Bridgetown::ERBEngine,
40
+ &block)
41
+ when "serb" # requires serbea
42
+ include Serbea::Helpers
43
+ Tilt::SerbeaTemplate.new(component_template_path, &block)
44
+ when "slim" # requires bridgetown-slim
45
+ Slim::Template.new(component_template_path, &block)
46
+ when "haml" # requires bridgetown-haml
47
+ Tilt::HamlTemplate.new(component_template_path, &block)
48
+ else
49
+ raise NameError
50
+ end
51
+ rescue NameError, LoadError
52
+ raise "No component rendering engine could be found for .#{ext} templates"
53
+ end
54
+
55
+ # Find the first matching template path based on source location and extension.
56
+ #
57
+ # @return [String]
58
+ def component_template_path
59
+ @_tmpl_path ||= begin
60
+ stripped_path = File.join(
61
+ File.dirname(source_location),
62
+ File.basename(source_location, ".*")
63
+ )
64
+ supported_template_extensions.each do |ext|
65
+ test_path = "#{stripped_path}.#{ext}"
66
+ break test_path if File.exist?(test_path)
67
+
68
+ test_path = "#{stripped_path}.html.#{ext}"
69
+ break test_path if File.exist?(test_path)
70
+ end
71
+ end
72
+
73
+ unless @_tmpl_path.is_a?(String)
74
+ raise "#{name}: no matching template could be found in #{File.dirname(source_location)}"
75
+ end
76
+
77
+ @_tmpl_path
78
+ end
79
+
80
+ # Read the template file.
81
+ #
82
+ # @return [String]
83
+ def component_template_content
84
+ @_tmpl_content ||= File.read(component_template_path)
85
+ end
86
+
87
+ # A list of extensions supported by the renderer
88
+ # TODO: make this extensible
89
+ #
90
+ # @return [Array<String>]
91
+ def supported_template_extensions
92
+ %w(erb serb slim haml)
93
+ end
94
+ end
95
+
96
+ # If a content block was originally passed into via `render`, capture its output.
97
+ #
98
+ # @return [String] or nil
99
+ def content
100
+ @_content ||= begin
101
+ view_context.capture(self, &@_content_block) if @_content_block
102
+ end
103
+ end
104
+
105
+ # Provide a render helper for evaluation within the component context.
106
+ #
107
+ # @param item [Object] a component supporting `render_in` or a partial name
108
+ # @param options [Hash] passed to the `partial` helper if needed
109
+ # @return [String]
110
+ def render(item, options = {}, &block)
111
+ if item.respond_to?(:render_in)
112
+ result = ""
113
+ capture do # this ensures no leaky interactions between BT<=>VC blocks
114
+ result = item.render_in(self, &block)
115
+ end
116
+ result&.html_safe
117
+ else
118
+ partial(item, options, &block)&.html_safe
119
+ end
120
+ end
121
+
122
+ # This is where the magic happens. Render the component within a view context.
123
+ #
124
+ # @param view_context [Bridgetown::RubyTemplateView]
125
+ def render_in(view_context, &block)
126
+ @view_context = view_context
127
+ @_content_block = block
128
+
129
+ if render?
130
+ before_render
131
+ template
132
+ else
133
+ ""
134
+ end
135
+ rescue StandardError => e
136
+ Bridgetown.logger.error "Component error:",
137
+ "#{self.class} encountered an error while "\
138
+ "rendering `#{self.class.component_template_path}'"
139
+ raise e
140
+ end
141
+
142
+ # Subclasses can override this method to return a string from their own
143
+ # template handling.
144
+ def template
145
+ call || _renderer.render(self)
146
+ end
147
+
148
+ # Typically not used but here as a compatibility nod toward ViewComponent.
149
+ def call
150
+ nil
151
+ end
152
+
153
+ # Subclasses can override this method to perform tasks before a render.
154
+ def before_render; end
155
+
156
+ # Subclasses can override this method to determine if the component should
157
+ # be rendered based on initialized data or other logic.
158
+ def render?
159
+ true
160
+ end
161
+
162
+ def _renderer
163
+ @_renderer ||= begin
164
+ ext = File.extname(self.class.component_template_path).delete_prefix(".")
165
+ self.class.renderer_for_ext(ext) { self.class.component_template_content }
166
+ end
167
+ end
168
+
169
+ # rubocop:disable Style/MissingRespondToMissing
170
+ ruby2_keywords def method_missing(method, *args, &block)
171
+ if helpers.respond_to?(method.to_sym)
172
+ helpers.send method.to_sym, *args, &block
173
+ else
174
+ super
175
+ end
176
+ end
177
+
178
+ def respond_to_missing?(method, include_private = false)
179
+ helpers.respond_to?(method.to_sym, include_private) || super
180
+ end
181
+ # rubocop:enable Style/MissingRespondToMissing
182
+ end
183
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
+ # TODO: to be retired once the Resource engine is made official
4
5
  module DataAccessible
5
6
  # Returns the contents as a String.
6
7
  def to_s
@@ -0,0 +1,52 @@
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..-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
@@ -11,7 +11,7 @@ module Bridgetown
11
11
  end
12
12
 
13
13
  def no_layout?
14
- data["layout"] == "none" || data["layout"] == false
14
+ data.layout.nil? || data.layout == "none" || data.layout == false
15
15
  end
16
16
  end
17
17
  end
@@ -18,23 +18,22 @@ class Bridgetown::Site
18
18
  @root_dir = File.expand_path(config["root_dir"]).freeze
19
19
  @source = File.expand_path(config["source"]).freeze
20
20
  @dest = File.expand_path(config["destination"]).freeze
21
- @cache_dir = in_root_dir(config["cache_dir"]).freeze
22
-
23
- %w(lsi highlighter baseurl exclude include future unpublished
24
- limit_posts keep_files).each do |opt|
25
- send("#{opt}=", config[opt])
26
- end
27
21
 
28
22
  configure_cache
29
23
  configure_component_paths
30
24
  configure_include_paths
31
25
  configure_file_read_opts
32
26
 
33
- self.permalink_style = config["permalink"].to_sym
27
+ self.baseurl = config.baseurl
28
+ self.permalink_style = (config["permalink"] || "pretty").to_sym
34
29
 
35
30
  @config
36
31
  end
37
32
 
33
+ def uses_resource?
34
+ config[:content_engine] == "resource"
35
+ end
36
+
38
37
  def defaults_reader
39
38
  @defaults_reader ||= Bridgetown::DefaultsReader.new(self)
40
39
  end
@@ -78,7 +77,7 @@ class Bridgetown::Site
78
77
  # @return [Array<String>] Return an array of updated paths if multiple paths given.
79
78
  def in_root_dir(*paths)
80
79
  paths.reduce(root_dir) do |base, path|
81
- Bridgetown.sanitized_path(base, path)
80
+ Bridgetown.sanitized_path(base, path.to_s)
82
81
  end
83
82
  end
84
83
 
@@ -91,7 +90,7 @@ class Bridgetown::Site
91
90
  # @return [Array<String>] Return an array of updated paths if multiple paths given.
92
91
  def in_source_dir(*paths)
93
92
  paths.reduce(source) do |base, path|
94
- Bridgetown.sanitized_path(base, path)
93
+ Bridgetown.sanitized_path(base, path.to_s)
95
94
  end
96
95
  end
97
96
 
@@ -149,7 +148,8 @@ class Bridgetown::Site
149
148
 
150
149
  # Disable Marshaling cache to disk in Safe Mode
151
150
  def configure_cache
152
- Bridgetown::Cache.cache_dir = in_root_dir(config["cache_dir"], "Bridgetown/Cache")
151
+ @cache_dir = in_root_dir(config["cache_dir"]).freeze
152
+ Bridgetown::Cache.cache_dir = File.join(cache_dir, "Bridgetown/Cache")
153
153
  Bridgetown::Cache.disable_disk_cache! if config["disable_disk_cache"]
154
154
  end
155
155
 
@@ -32,6 +32,18 @@ class Bridgetown::Site
32
32
  end
33
33
  end
34
34
 
35
+ def resources_grouped_by_taxonomy(taxonomy)
36
+ @post_attr_hash[taxonomy.label] ||= begin
37
+ taxonomy.terms.transform_values { |terms| terms.map(&:resource).sort.reverse }
38
+ end
39
+ end
40
+
41
+ def taxonomies
42
+ taxonomy_types.transform_values do |taxonomy|
43
+ resources_grouped_by_taxonomy(taxonomy)
44
+ end
45
+ end
46
+
35
47
  # Returns a hash of "tags" using {#post_attr_hash} where each tag is a key
36
48
  # and each value is a post which contains the key.
37
49
  # @example
@@ -41,7 +53,7 @@ class Bridgetown::Site
41
53
  # @return [Hash{String, Array<Post>}] Returns a hash of all tags and their corresponding posts
42
54
  # @see post_attr_hash
43
55
  def tags
44
- post_attr_hash("tags")
56
+ uses_resource? ? taxonomies.tag : post_attr_hash("tags")
45
57
  end
46
58
 
47
59
  # Returns a hash of "categories" using {#post_attr_hash} where each tag is
@@ -54,7 +66,7 @@ class Bridgetown::Site
54
66
  # their corresponding posts
55
67
  # @see post_attr_hash
56
68
  def categories
57
- post_attr_hash("categories")
69
+ uses_resource? ? taxonomies.category : post_attr_hash("categories")
58
70
  end
59
71
 
60
72
  # Returns the value of `data["site_metadata"]` or creates a new instance of
@@ -121,19 +133,25 @@ class Bridgetown::Site
121
133
  # An array of collection names.
122
134
  # @return [Array<String>] an array of collection names from the configuration,
123
135
  # or an empty array if the `config["collections"]` key is not set.
124
- # @raise ArgumentError Raise an error if `config["collections"]` is not
125
- # an Array or a Hash
126
136
  def collection_names
127
- case config["collections"]
128
- when Hash
129
- config["collections"].keys
130
- when Array
131
- config["collections"]
132
- when nil
133
- []
134
- else
135
- raise ArgumentError, "Your `collections` key must be a hash or an array."
136
- end
137
+ Array(config.collections&.keys)
138
+ end
139
+
140
+ # @return [Array<Bridgetown::Resource::TaxonomyType>]
141
+ def taxonomy_types
142
+ @taxonomy_types ||= config.taxonomies.map do |label, key_or_metadata|
143
+ key = key_or_metadata
144
+ tax_metadata = if key_or_metadata.is_a? Hash
145
+ key = key_or_metadata["key"]
146
+ key_or_metadata.reject { |k| k == "key" }
147
+ else
148
+ HashWithDotAccess::Hash.new
149
+ end
150
+
151
+ [label, Bridgetown::Resource::TaxonomyType.new(
152
+ site: self, label: label, key: key, metadata: tax_metadata
153
+ ),]
154
+ end.to_h.with_dot_access
137
155
  end
138
156
 
139
157
  # Get all documents.
@@ -155,11 +173,28 @@ class Bridgetown::Site
155
173
  documents.select(&:write?)
156
174
  end
157
175
 
158
- # Get all posts.
176
+ # Get all loaded resources.
177
+ # @return [Array<Bridgetown::Resource::Base>] an array of resources
178
+ def resources
179
+ collections.each_with_object(Set.new) do |(_, collection), set|
180
+ set.merge(collection.resources)
181
+ end.to_a
182
+ end
183
+
184
+ def resources_to_write
185
+ resources.select(&:write?)
186
+ end
187
+
188
+ # Get all posts. Deprecated, to be removed in v1.0.
159
189
  #
160
190
  # @return [Collection] Returns {#collections}`["posts"]`, creating it if need be
161
191
  # @see Collection
162
192
  def posts
193
+ unless @wrote_deprecation_msg
194
+ Bridgetown::Deprecator.deprecation_message "Call site.collections.posts " \
195
+ "instead of site.posts (Ruby code)"
196
+ end
197
+ @wrote_deprecation_msg ||= true
163
198
  collections["posts"] ||= Bridgetown::Collection.new(self, "posts")
164
199
  end
165
200
 
@@ -177,7 +212,13 @@ class Bridgetown::Site
177
212
  #
178
213
  # @return [Array]
179
214
  def contents
215
+ return resources if uses_resource?
216
+
180
217
  pages + documents
181
218
  end
219
+
220
+ def add_generated_page(generated_page)
221
+ generated_pages << generated_page
222
+ end
182
223
  end
183
224
  end
@@ -5,13 +5,11 @@ class Bridgetown::Site
5
5
  # Returns the current and/or default configured locale
6
6
  # @return String
7
7
  def locale
8
- if @locale
9
- @locale
10
- else
11
- @locale = ENV.fetch("BRIDGETOWN_LOCALE", config[:default_locale]).to_sym
8
+ @locale ||= begin
9
+ locale = ENV.fetch("BRIDGETOWN_LOCALE", config[:default_locale]).to_sym
12
10
  I18n.load_path << Dir[in_source_dir("_locales") + "/*.yml"]
13
11
  I18n.available_locales = config[:available_locales]
14
- I18n.default_locale = @locale
12
+ I18n.default_locale = locale
15
13
  end
16
14
  end
17
15