bridgetown-core 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53b0e9ed90d2ea5578e1c19daf6d1f91dcb97c5142d57272077978b3ec158b62
4
- data.tar.gz: ae7795236a44bbbe2f5a0fd5a6b5658626b5460446cd13e2af0182e47705e9cd
3
+ metadata.gz: 5434399f502bf037e77a019dfda4b2deae10b6a532349ec21b32977a224ca448
4
+ data.tar.gz: cae6a4eb2d435bfd0e85f18320e76a90619c872ccf69f44c9ac2e13e987e1fe7
5
5
  SHA512:
6
- metadata.gz: 0e3a9ef6b53cf66028912478cac3151ad0d6fe3a5f612d9a3b5d0bf77da8b4ffe1b87e5ead0a4581e8773bf7cce09fc9cb57e9bbc8b67ac58d1cc6b261bdd522
7
- data.tar.gz: 51c6fe403e12cf6c054a31646b880082954db7d33695b4b04679b410f0466b06e5b756bba88b78e483334bff6c58319da0356b2fed81f40b29aa261b2383a42f
6
+ metadata.gz: 5344308e24f519099a33af769a1c5dd908d1fd54f10aaec4c81f4254c9ff772787f1a2e4b9f0d488a21167cc98c6a1c526df1fd2e7d6ee4e86cf33afc4efe2bd
7
+ data.tar.gz: f2eedc957c8782b03e08f0834b88981e40f6539ac65899096bcfc1c1e4ed196b4046859530d5e281dee2b1455ac4e01e7b8a63dfdf29e3ad36e8725d1ed00f64
@@ -13,7 +13,7 @@ Bridgetown::PluginManager.require_from_bundler
13
13
  Bridgetown::Deprecator.process(ARGV)
14
14
 
15
15
  Mercenary.program(:bridgetown) do |p|
16
- p.version Bridgetown::VERSION
16
+ p.version "#{Bridgetown::VERSION.magenta} \"#{Bridgetown::CODE_NAME.yellow}\""
17
17
  p.description "Bridgetown is a Webpack-aware, Ruby-powered static site generator for the modern Jamstack era"
18
18
  p.syntax "bridgetown <subcommand> [options]"
19
19
 
@@ -23,24 +23,24 @@ Mercenary.program(:bridgetown) do |p|
23
23
  # if you do bridgetown build --help — ouch!
24
24
  p.option "source", "-s", "--source [DIR]", "Source directory (defaults to src)"
25
25
  p.option "destination", "-d", "--destination [DIR]",
26
- "Destination directory (defaults to output)"
26
+ "Destination directory (defaults to output)"
27
27
  p.option "plugins_dir", "-p", "--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]", Array,
28
- "Plugins directory (defaults to plugins)"
28
+ "Plugins directory (defaults to plugins)"
29
29
  p.option "layouts_dir", "--layouts DIR", String,
30
- "Layouts directory (defaults to src/_layouts)"
30
+ "Layouts directory (defaults to src/_layouts)"
31
31
  p.option "profile", "--profile", "Generate a Liquid rendering profile"
32
32
 
33
- # TODO: this is not the way to bring in extra command gems!
34
- # Bridgetown::External.require_if_present(Bridgetown::External.blessed_gems) do |g, ver_constraint|
35
- # cmd = g.split("-").last
36
- # p.command(cmd.to_sym) do |c|
37
- # c.syntax cmd
38
- # c.action do
39
- # Bridgetown.logger.abort_with "You must install the '#{g}' gem" \
40
- # " version #{ver_constraint} to use the 'bridgetown #{cmd}' command."
41
- # end
42
- # end
43
- # end
33
+ # TODO: this is not the way to bring in extra command gems!
34
+ # Bridgetown::External.require_if_present(Bridgetown::External.blessed_gems) do |g, ver_constraint|
35
+ # cmd = g.split("-").last
36
+ # p.command(cmd.to_sym) do |c|
37
+ # c.syntax cmd
38
+ # c.action do
39
+ # Bridgetown.logger.abort_with "You must install the '#{g}' gem" \
40
+ # " version #{ver_constraint} to use the 'bridgetown #{cmd}' command."
41
+ # end
42
+ # end
43
+ # end
44
44
 
45
45
  Bridgetown::Command.subclasses.each { |c| c.init_with_program(p) }
46
46
 
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
 
34
34
  s.add_runtime_dependency("addressable", "~> 2.4")
35
35
  s.add_runtime_dependency("colorator", "~> 1.0")
36
+ s.add_runtime_dependency("faraday", "~> 1.0")
36
37
  s.add_runtime_dependency("i18n", "~> 1.0")
37
38
  s.add_runtime_dependency("kramdown", "~> 2.1")
38
39
  s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
@@ -36,9 +36,14 @@ require "liquid"
36
36
  require "kramdown"
37
37
  require "colorator"
38
38
  require "i18n"
39
+ require "faraday"
39
40
 
40
41
  SafeYAML::OPTIONS[:suppress_warnings] = true
41
42
 
43
+ # Create our little String subclass for Ruby Front Matter
44
+ class Rb < String; end
45
+ SafeYAML::OPTIONS[:whitelisted_tags] = ["!ruby/string:Rb"]
46
+
42
47
  module Bridgetown
43
48
  # internal requires
44
49
  autoload :Cleaner, "bridgetown-core/cleaner"
@@ -101,9 +106,10 @@ module Bridgetown
101
106
  # Public: Tells you which Bridgetown environment you are building in so
102
107
  # you can skip tasks if you need to.
103
108
 
104
- def env
109
+ def environment
105
110
  ENV["BRIDGETOWN_ENV"] || "development"
106
111
  end
112
+ alias_method :env, :environment
107
113
 
108
114
  # Public: Generate a Bridgetown configuration Hash by merging the default
109
115
  # options with anything in bridgetown.config.yml, and adding the given
@@ -87,7 +87,6 @@ module Bridgetown
87
87
  "run Bridgetown with --no-watch."
88
88
  end
89
89
 
90
- # External.require_with_graceful_fail "bridgetown-watch"
91
90
  Bridgetown::Watcher.watch(@site, options)
92
91
  end
93
92
 
@@ -100,6 +99,7 @@ module Bridgetown
100
99
  source = File.expand_path(options["source"])
101
100
  destination = File.expand_path(options["destination"])
102
101
  plugins_dir = File.expand_path(options["plugins_dir"])
102
+ Bridgetown.logger.info "Environment:", Bridgetown.environment.cyan
103
103
  Bridgetown.logger.info "Source:", source
104
104
  Bridgetown.logger.info "Destination:", destination
105
105
  Bridgetown.logger.info "Custom Plugins:", plugins_dir if Dir.exist?(plugins_dir)
@@ -24,9 +24,10 @@ module Bridgetown
24
24
  # TODO: is there a way to add a unit test for this command?
25
25
  # rubocop:disable Style/GlobalVars, Metrics/AbcSize, Metrics/MethodLength
26
26
  def process(options)
27
- Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION}" \
28
- " (codename \"#{Bridgetown::CODE_NAME}\")" \
27
+ Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta}" \
28
+ " (codename \"#{Bridgetown::CODE_NAME.yellow}\")" \
29
29
  " console…"
30
+ Bridgetown.logger.info "Environment:", Bridgetown.environment.cyan
30
31
  site = Bridgetown::Site.new(configuration_from_options(options))
31
32
  site.reset
32
33
  site.read
@@ -34,7 +34,6 @@ module Bridgetown
34
34
  def healthy?(site)
35
35
  [
36
36
  fsnotify_buggy?(site),
37
- !deprecated_relative_permalinks(site),
38
37
  !conflicting_urls(site),
39
38
  !urls_only_differ_by_case(site),
40
39
  proper_site_url?(site),
@@ -56,14 +55,6 @@ module Bridgetown
56
55
  false
57
56
  end
58
57
 
59
- def deprecated_relative_permalinks(site)
60
- if site.config["relative_permalinks"]
61
- Bridgetown::Deprecator.deprecation_message "Your site still uses relative permalinks," \
62
- " which was removed in Bridgetown v0.1"
63
- true
64
- end
65
- end
66
-
67
58
  def conflicting_urls(site)
68
59
  conflicting_urls = false
69
60
  urls = {}
@@ -60,7 +60,7 @@ module Bridgetown
60
60
 
61
61
  # TODO: this prints the configuration file log message out-of-order
62
62
  config = configuration_from_options(opts)
63
- config["url"] = default_url(config) if Bridgetown.env == "development"
63
+ config["url"] = default_url(config) if Bridgetown.environment == "development"
64
64
 
65
65
  process_with_graceful_fail(cmd, config, Build, Serve)
66
66
  end
@@ -69,12 +69,11 @@ module Bridgetown
69
69
 
70
70
  #
71
71
 
72
- def process(opts)
73
- opts = configuration_from_options(opts)
74
- destination = opts["destination"]
72
+ def process(config)
73
+ destination = config["destination"]
75
74
  setup(destination)
76
75
 
77
- start_up_webrick(opts, destination)
76
+ start_up_webrick(config, destination)
78
77
  end
79
78
 
80
79
  def shutdown
@@ -157,8 +156,7 @@ module Bridgetown
157
156
  baseurl: baseurl ? "#{baseurl}/" : "")
158
157
  end
159
158
 
160
- def default_url(opts)
161
- config = configuration_from_options(opts)
159
+ def default_url(config)
162
160
  format_url(
163
161
  config["ssl_cert"] && config["ssl_key"],
164
162
  config["host"] == "127.0.0.1" ? "localhost" : config["host"],
@@ -1,66 +1,70 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
+ # TODO: refactor this whole object! Already had to fix obscure
5
+ # bugs just making minor changes, and all the indirection is
6
+ # quite hard to decipher. -JW
4
7
  class Configuration < Hash
5
8
  # Default options. Overridden by values in bridgetown.config.yml.
6
9
  # Strings rather than symbols are used for compatibility with YAML.
7
10
  DEFAULTS = {
8
11
  # Where things are
9
- "root_dir" => Dir.pwd,
10
- "plugins_dir" => "plugins",
11
- "source" => File.join(Dir.pwd, "src"),
12
- "destination" => File.join(Dir.pwd, "output"),
13
- "collections_dir" => "",
14
- "cache_dir" => ".bridgetown-cache",
15
- "layouts_dir" => "_layouts",
16
- "data_dir" => "_data",
17
- "components_dir" => "_components",
18
- "includes_dir" => "_includes",
19
- "collections" => {},
12
+ "root_dir" => Dir.pwd,
13
+ "plugins_dir" => "plugins",
14
+ "source" => File.join(Dir.pwd, "src"),
15
+ "destination" => File.join(Dir.pwd, "output"),
16
+ "collections_dir" => "",
17
+ "cache_dir" => ".bridgetown-cache",
18
+ "layouts_dir" => "_layouts",
19
+ "data_dir" => "_data",
20
+ "components_dir" => "_components",
21
+ "includes_dir" => "_includes",
22
+ "collections" => {},
20
23
 
21
24
  # Handling Reading
22
- "include" => [".htaccess", "_redirects", ".well-known"],
23
- "exclude" => [],
24
- "keep_files" => [".git", ".svn", "_bridgetown"],
25
- "encoding" => "utf-8",
26
- "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
27
- "strict_front_matter" => false,
28
- "slugify_categories" => true,
25
+ "include" => [".htaccess", "_redirects", ".well-known"],
26
+ "exclude" => [],
27
+ "keep_files" => [".git", ".svn", "_bridgetown"],
28
+ "encoding" => "utf-8",
29
+ "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
30
+ "strict_front_matter" => false,
31
+ "slugify_categories" => true,
29
32
 
30
33
  # Filtering Content
31
- "limit_posts" => 0,
32
- "future" => false,
33
- "unpublished" => false,
34
+ "limit_posts" => 0,
35
+ "future" => false,
36
+ "unpublished" => false,
37
+ "ruby_in_front_matter" => true, # requires BRIDGETOWN_RUBY_IN_FRONT_MATTER == "true"
34
38
 
35
39
  # Conversion
36
- "markdown" => "kramdown",
37
- "highlighter" => "rouge",
38
- "lsi" => false,
39
- "excerpt_separator" => "\n\n",
40
- "incremental" => false,
40
+ "markdown" => "kramdown",
41
+ "highlighter" => "rouge",
42
+ "lsi" => false,
43
+ "excerpt_separator" => "\n\n",
44
+ "incremental" => false,
41
45
 
42
46
  # Serving
43
- "detach" => false, # default to not detaching the server
44
- "port" => "4000",
45
- "host" => "127.0.0.1",
46
- "baseurl" => nil, # this mounts at /, i.e. no subdirectory
47
- "show_dir_listing" => false,
47
+ "detach" => false, # default to not detaching the server
48
+ "port" => "4000",
49
+ "host" => "127.0.0.1",
50
+ "baseurl" => nil, # this mounts at /, i.e. no subdirectory
51
+ "show_dir_listing" => false,
48
52
 
49
53
  # Output Configuration
50
- "permalink" => "date",
51
- "timezone" => nil, # use the local timezone
54
+ "permalink" => "date",
55
+ "timezone" => nil, # use the local timezone
52
56
 
53
- "quiet" => false,
54
- "verbose" => false,
55
- "defaults" => [],
57
+ "quiet" => false,
58
+ "verbose" => false,
59
+ "defaults" => [],
56
60
 
57
- "liquid" => {
61
+ "liquid" => {
58
62
  "error_mode" => "warn",
59
63
  "strict_filters" => false,
60
64
  "strict_variables" => false,
61
65
  },
62
66
 
63
- "kramdown" => {
67
+ "kramdown" => {
64
68
  "auto_ids" => true,
65
69
  "toc_levels" => (1..6).to_a,
66
70
  "entity_output" => "as_char",
@@ -88,7 +92,10 @@ module Bridgetown
88
92
  # Returns a Configuration filled with defaults.
89
93
  def from(user_config)
90
94
  Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
91
- .add_default_collections.add_default_excludes
95
+ .merge_environment_specific_options!
96
+ .add_default_collections
97
+ .add_default_excludes
98
+ .check_include_exclude
92
99
  end
93
100
  end
94
101
 
@@ -178,31 +185,6 @@ module Bridgetown
178
185
  Array(config_files)
179
186
  end
180
187
 
181
- # Public: Read configuration and return merged Hash
182
- #
183
- # file - the path to the YAML file to be read in
184
- #
185
- # Returns this configuration, overridden by the values in the file
186
- def read_config_file(file)
187
- file = File.expand_path(file)
188
- next_config = safe_load_file(file)
189
-
190
- unless next_config.is_a?(Hash)
191
- raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
192
- end
193
-
194
- Bridgetown.logger.info "Configuration file:", file
195
- next_config
196
- rescue SystemCallError
197
- if @default_config_file ||= nil
198
- Bridgetown.logger.warn "Configuration file:", "none"
199
- {}
200
- else
201
- Bridgetown.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
202
- raise LoadError, "The Configuration file '#{file}' could not be found."
203
- end
204
- end
205
-
206
188
  # Public: Read in a list of configuration files and merge with this hash
207
189
  #
208
190
  # files - the list of configuration file paths
@@ -210,14 +192,14 @@ module Bridgetown
210
192
  # Returns the full configuration, with the defaults overridden by the values in the
211
193
  # configuration files
212
194
  def read_config_files(files)
213
- configuration = clone
195
+ config = self
214
196
 
215
197
  begin
216
198
  files.each do |config_file|
217
199
  next if config_file.nil? || config_file.empty?
218
200
 
219
201
  new_config = read_config_file(config_file)
220
- configuration = Utils.deep_merge_hashes(configuration, new_config)
202
+ config = Utils.deep_merge_hashes(self, new_config)
221
203
  end
222
204
  rescue ArgumentError => e
223
205
  Bridgetown.logger.warn "WARNING:", "Error reading configuration. Using defaults" \
@@ -225,52 +207,64 @@ module Bridgetown
225
207
  warn e
226
208
  end
227
209
 
228
- configuration.validate.add_default_collections
210
+ config
229
211
  end
230
212
 
231
- # Public: Split a CSV string into an array containing its values
213
+ # Public: Read configuration and return merged Hash
232
214
  #
233
- # csv - the string of comma-separated values
215
+ # file - the path to the YAML file to be read in
234
216
  #
235
- # Returns an array of the values contained in the CSV
236
- def csv_to_array(csv)
237
- csv.split(",").map(&:strip)
238
- end
217
+ # Returns this configuration, overridden by the values in the file
218
+ def read_config_file(file)
219
+ file = File.expand_path(file)
220
+ next_config = safe_load_file(file)
239
221
 
240
- # Public: Ensure the proper options are set in the configuration
241
- #
242
- # Returns the configuration Hash
243
- def validate
244
- config = clone
222
+ unless next_config.is_a?(Hash)
223
+ raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
224
+ end
245
225
 
246
- check_include_exclude(config)
226
+ Bridgetown.logger.info "Configuration file:", file
227
+ next_config
228
+ rescue SystemCallError
229
+ if @default_config_file ||= nil
230
+ Bridgetown.logger.warn "Configuration file:", "none"
231
+ {}
232
+ else
233
+ Bridgetown.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
234
+ raise LoadError, "The Configuration file '#{file}' could not be found."
235
+ end
236
+ end
247
237
 
248
- config
238
+ # Merge in environment-specific options, if present
239
+ def merge_environment_specific_options!
240
+ self[Bridgetown.environment]&.each_key do |k|
241
+ self[k] = self[Bridgetown.environment][k]
242
+ end
243
+ delete(Bridgetown.environment)
244
+ self
249
245
  end
250
246
 
251
247
  def add_default_collections
252
- config = clone
253
-
254
248
  # It defaults to `{}`, so this is only if someone sets it to null manually.
255
- return config if config["collections"].nil?
249
+ return self if self["collections"].nil?
256
250
 
257
251
  # Ensure we have a hash.
258
- if config["collections"].is_a?(Array)
259
- config["collections"] = config["collections"].each_with_object({}) do |collection, hash|
252
+ if self["collections"].is_a?(Array)
253
+ self["collections"] = self["collections"].each_with_object({}) do |collection, hash|
260
254
  hash[collection] = {}
261
255
  end
262
256
  end
263
257
 
264
- config["collections"] = Utils.deep_merge_hashes(
265
- { "posts" => {} }, config["collections"]
258
+ self["collections"] = Utils.deep_merge_hashes(
259
+ { "posts" => {} }, self["collections"]
266
260
  ).tap do |collections|
267
261
  collections["posts"]["output"] = true
268
- if config["permalink"]
269
- collections["posts"]["permalink"] ||= style_to_permalink(config["permalink"])
262
+ if self["permalink"]
263
+ collections["posts"]["permalink"] ||= style_to_permalink(self["permalink"])
270
264
  end
271
265
  end
272
266
 
273
- config
267
+ self
274
268
  end
275
269
 
276
270
  DEFAULT_EXCLUDES = %w(
@@ -281,14 +275,16 @@ module Bridgetown
281
275
  ).freeze
282
276
 
283
277
  def add_default_excludes
284
- config = clone
285
- return config if config["exclude"].nil?
278
+ return self if self["exclude"].nil?
286
279
 
287
- config["exclude"].concat(DEFAULT_EXCLUDES).uniq!
288
- config
280
+ self["exclude"].concat(DEFAULT_EXCLUDES).uniq!
281
+ self
289
282
  end
290
283
 
291
- private
284
+ def should_execute_inline_ruby?
285
+ ENV["BRIDGETOWN_RUBY_IN_FRONT_MATTER"] == "true" &&
286
+ self["ruby_in_front_matter"]
287
+ end
292
288
 
293
289
  # rubocop:disable Metrics/CyclomaticComplexity #
294
290
  def style_to_permalink(permalink_style)
@@ -311,14 +307,15 @@ module Bridgetown
311
307
  end
312
308
  # rubocop:enable Metrics/CyclomaticComplexity #
313
309
 
314
- def check_include_exclude(config)
310
+ def check_include_exclude
315
311
  %w(include exclude).each do |option|
316
- next unless config.key?(option)
317
- next if config[option].is_a?(Array)
312
+ next unless key?(option)
313
+ next if self[option].is_a?(Array)
318
314
 
319
315
  raise Bridgetown::Errors::InvalidConfigurationError,
320
- "'#{option}' should be set as an array, but was: #{config[option].inspect}."
316
+ "'#{option}' should be set as an array, but was: #{self[option].inspect}."
321
317
  end
318
+ self
322
319
  end
323
320
  end
324
321
  end
@@ -13,13 +13,18 @@ module Bridgetown
13
13
  Bridgetown::VERSION
14
14
  end
15
15
 
16
+ def code_name
17
+ Bridgetown::CODE_NAME
18
+ end
19
+
16
20
  def environment
17
- Bridgetown.env
21
+ Bridgetown.environment
18
22
  end
19
23
 
20
24
  def to_h
21
25
  @to_h ||= {
22
26
  "version" => version,
27
+ "code_name" => code_name,
23
28
  "environment" => environment,
24
29
  }
25
30
  end
@@ -50,7 +50,6 @@ module Bridgetown
50
50
  @documents ||= @obj.documents
51
51
  end
52
52
 
53
- # TODO: provide a way to set BRIDGETOWN_ENV-specific metadata
54
53
  def metadata
55
54
  @site_metadata ||= @obj.data["site_metadata"]
56
55
  end
@@ -17,6 +17,7 @@ module Bridgetown
17
17
  Liquid::Template.file_system = LiquidRenderer::FileSystem.new(
18
18
  @site.components_load_paths, "%s.liquid"
19
19
  )
20
+ Liquid::Template.file_system.site = site
20
21
 
21
22
  Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym
22
23
  reset
@@ -3,6 +3,8 @@
3
3
  module Bridgetown
4
4
  class LiquidRenderer
5
5
  class FileSystem < Liquid::LocalFileSystem
6
+ attr_accessor :site
7
+
6
8
  def read_template_file(template_path)
7
9
  load_paths = root
8
10
  found_paths = []
@@ -29,7 +31,7 @@ module Bridgetown
29
31
  raise Liquid::FileSystemError, "No such template '#{template_path}'" if found_paths.empty?
30
32
 
31
33
  # Last path in the list wins
32
- ::File.read(found_paths.last)
34
+ ::File.read(found_paths.last, site.file_read_opts)
33
35
  end
34
36
  end
35
37
  end
@@ -18,6 +18,7 @@ module Bridgetown
18
18
  def read(dir)
19
19
  base = site.in_source_dir(dir)
20
20
  read_data_to(base, @content)
21
+ merge_environment_specific_metadata!
21
22
  @content
22
23
  end
23
24
 
@@ -67,6 +68,15 @@ module Bridgetown
67
68
  end
68
69
  end
69
70
 
71
+ def merge_environment_specific_metadata!
72
+ if @content["site_metadata"]
73
+ @content["site_metadata"][Bridgetown.environment]&.each_key do |k|
74
+ @content["site_metadata"][k] = @content["site_metadata"][Bridgetown.environment][k]
75
+ end
76
+ @content["site_metadata"].delete(Bridgetown.environment)
77
+ end
78
+ end
79
+
70
80
  def sanitize_filename(name)
71
81
  name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
72
82
  .gsub(%r!\s+!, "_")
@@ -74,6 +74,8 @@ module Bridgetown
74
74
  strict_variables: liquid_options["strict_variables"],
75
75
  }
76
76
 
77
+ execute_inline_ruby!
78
+
77
79
  output = document.content
78
80
  if document.render_with_liquid?
79
81
  Bridgetown.logger.debug "Rendering Liquid:", document.relative_path
@@ -91,25 +93,15 @@ module Bridgetown
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 execute_inline_ruby!
98
+ return unless site.config.should_execute_inline_ruby?
99
+
100
+ Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document, self)
111
101
  end
112
102
 
103
+ # rubocop: enable Metrics/AbcSize
104
+
113
105
  # Render the given content with the payload and info
114
106
  #
115
107
  # content -
@@ -133,6 +125,23 @@ module Bridgetown
133
125
  end
134
126
  # rubocop: enable Lint/RescueException
135
127
 
128
+ # Convert the document using the converters which match this renderer's document.
129
+ #
130
+ # Returns String the converted content.
131
+ def convert(content)
132
+ converters.reduce(content) do |output, converter|
133
+ begin
134
+ converter.convert output
135
+ rescue StandardError => e
136
+ Bridgetown.logger.error "Conversion error:",
137
+ "#{converter.class} encountered an error while "\
138
+ "converting '#{document.relative_path}':"
139
+ Bridgetown.logger.error("", e.to_s)
140
+ raise e
141
+ end
142
+ end
143
+ end
144
+
136
145
  # Checks if the layout specified in the document actually exists
137
146
  #
138
147
  # layout - the layout to check
@@ -192,6 +192,8 @@ module Bridgetown
192
192
 
193
193
  Bridgetown::Hooks.trigger :site, :pre_render, self, payload
194
194
 
195
+ execute_inline_ruby_for_layouts!
196
+
195
197
  render_docs(payload)
196
198
  render_pages(payload)
197
199
 
@@ -262,6 +264,10 @@ module Bridgetown
262
264
  @site_data ||= (config["data"] || data)
263
265
  end
264
266
 
267
+ def metadata
268
+ data["site_metadata"] || {}
269
+ end
270
+
265
271
  # The Hash payload containing site-wide data.
266
272
  #
267
273
  # Returns the Hash: { "site" => data } where data is a Hash with keys:
@@ -461,6 +467,14 @@ module Bridgetown
461
467
  self.file_read_opts = Bridgetown::Utils.merged_file_read_opts(self, {})
462
468
  end
463
469
 
470
+ def execute_inline_ruby_for_layouts!
471
+ return unless config.should_execute_inline_ruby?
472
+
473
+ layouts.each_value do |layout|
474
+ Bridgetown::Utils::RubyExec.search_data_for_ruby_code(layout, self)
475
+ end
476
+ end
477
+
464
478
  def render_docs(payload)
465
479
  collections.each_value do |collection|
466
480
  collection.docs.each do |document|
@@ -186,11 +186,7 @@ module Bridgetown
186
186
  private
187
187
 
188
188
  def copy_file(dest_path)
189
- if Bridgetown.env == "production"
190
- FileUtils.cp(path, dest_path)
191
- else
192
- FileUtils.copy_entry(path, dest_path)
193
- end
189
+ FileUtils.copy_entry(path, dest_path)
194
190
 
195
191
  unless File.symlink?(dest_path)
196
192
  File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
@@ -6,6 +6,7 @@ module Bridgetown
6
6
  autoload :Ansi, "bridgetown-core/utils/ansi"
7
7
  autoload :Exec, "bridgetown-core/utils/exec"
8
8
  autoload :Internet, "bridgetown-core/utils/internet"
9
+ autoload :RubyExec, "bridgetown-core/utils/ruby_exec"
9
10
  autoload :Platforms, "bridgetown-core/utils/platforms"
10
11
  autoload :ThreadEvent, "bridgetown-core/utils/thread_event"
11
12
  autoload :WinTZ, "bridgetown-core/utils/win_tz"
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Utils
5
+ module RubyExec
6
+ extend self
7
+
8
+ # rubocop:disable Metrics/AbcSize
9
+ def search_data_for_ruby_code(convertible, renderer)
10
+ return if convertible.data.empty?
11
+
12
+ # Iterate using `keys` here so inline Ruby script can add new data keys
13
+ # if necessary without an error
14
+ data_keys = convertible.data.keys
15
+ data_keys.each do |k|
16
+ v = convertible.data[k]
17
+ next unless v.is_a?(Rb) || v.is_a?(Hash)
18
+
19
+ if v.is_a?(Hash)
20
+ v.each do |nested_k, nested_v|
21
+ next unless nested_v.is_a?(Rb)
22
+
23
+ Bridgetown.logger.warn("Executing inline Ruby…", convertible.relative_path)
24
+ convertible.data[k][nested_k] = run(nested_v, convertible, renderer)
25
+ Bridgetown.logger.warn("Inline Ruby completed!", convertible.relative_path)
26
+ end
27
+ else
28
+ Bridgetown.logger.warn("Executing inline Ruby…", convertible.relative_path)
29
+ convertible.data[k] = run(v, convertible, renderer)
30
+ Bridgetown.logger.warn("Inline Ruby completed!", convertible.relative_path)
31
+ end
32
+ end
33
+ end
34
+ # rubocop:enable Metrics/AbcSize
35
+
36
+ # Sets up a new context in which to eval Ruby coming from front matter.
37
+ #
38
+ # ruby_code - a string of code
39
+ # convertible - the Document/Page/Layout with the Ruby front matter
40
+ # renderer - the Renderer instance that's processing the document (optional)
41
+ #
42
+ # Returns the transformed output of the code
43
+ def run(ruby_code, convertible, renderer)
44
+ return unless ruby_code.is_a?(Rb)
45
+
46
+ klass = Class.new
47
+ obj = klass.new
48
+
49
+ if convertible.is_a?(Layout)
50
+ klass.attr_accessor :layout, :site, :data
51
+ obj.layout = convertible
52
+ else
53
+ klass.attr_accessor :document, :page, :renderer, :site, :data
54
+ obj.document = obj.page = convertible
55
+ obj.renderer = renderer
56
+ end
57
+ obj.site = convertible.site
58
+ obj.data = convertible.data
59
+
60
+ # This is where the magic happens! DON'T BE EVIL!!! ;-)
61
+ output = obj.instance_eval(ruby_code)
62
+
63
+ output = Bridgetown::Utils.stringify_hash_keys(output) if output.is_a?(Hash)
64
+
65
+ output
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.12.1"
5
- CODE_NAME = "Lovejoy"
4
+ VERSION = "0.13.0"
5
+ CODE_NAME = "Klickitat"
6
6
  end
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-01 00:00:00.000000000 Z
11
+ date: 2020-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: i18n
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +286,7 @@ files:
272
286
  - lib/bridgetown-core/utils/exec.rb
273
287
  - lib/bridgetown-core/utils/internet.rb
274
288
  - lib/bridgetown-core/utils/platforms.rb
289
+ - lib/bridgetown-core/utils/ruby_exec.rb
275
290
  - lib/bridgetown-core/utils/thread_event.rb
276
291
  - lib/bridgetown-core/utils/win_tz.rb
277
292
  - lib/bridgetown-core/version.rb
@@ -294,6 +309,7 @@ files:
294
309
  - lib/site_template/src/_layouts/post.html
295
310
  - lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb
296
311
  - lib/site_template/src/about.md
312
+ - lib/site_template/src/favicon.ico
297
313
  - lib/site_template/src/index.md
298
314
  - lib/site_template/start.js
299
315
  - lib/site_template/sync.js