bridgetown-core 2.0.0.beta2 → 2.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/bridgetown-core.gemspec +43 -42
  4. data/lib/bridgetown-core/cache.rb +3 -19
  5. data/lib/bridgetown-core/cleaner.rb +17 -19
  6. data/lib/bridgetown-core/collection.rb +6 -5
  7. data/lib/bridgetown-core/commands/base.rb +7 -0
  8. data/lib/bridgetown-core/commands/build.rb +35 -22
  9. data/lib/bridgetown-core/commands/concerns/actions.rb +4 -0
  10. data/lib/bridgetown-core/commands/console.rb +0 -1
  11. data/lib/bridgetown-core/commands/esbuild/esbuild.config.js +7 -6
  12. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +14 -13
  13. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -1
  14. data/lib/bridgetown-core/commands/esbuild/update.rb +17 -3
  15. data/lib/bridgetown-core/commands/esbuild.rb +1 -1
  16. data/lib/bridgetown-core/commands/start.rb +12 -2
  17. data/lib/bridgetown-core/component.rb +1 -1
  18. data/lib/bridgetown-core/concerns/intuitive_expectations.rb +67 -0
  19. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  20. data/lib/bridgetown-core/concerns/publishable.rb +2 -0
  21. data/lib/bridgetown-core/concerns/site/content.rb +4 -1
  22. data/lib/bridgetown-core/concerns/site/extensible.rb +6 -1
  23. data/lib/bridgetown-core/concerns/site/fast_refreshable.rb +33 -18
  24. data/lib/bridgetown-core/concerns/site/localizable.rb +2 -0
  25. data/lib/bridgetown-core/concerns/site/processable.rb +2 -0
  26. data/lib/bridgetown-core/concerns/site/renderable.rb +3 -0
  27. data/lib/bridgetown-core/concerns/site/ssr.rb +1 -2
  28. data/lib/bridgetown-core/concerns/site/writable.rb +1 -0
  29. data/lib/bridgetown-core/concerns/viewable.rb +46 -0
  30. data/lib/bridgetown-core/configuration.rb +29 -23
  31. data/lib/bridgetown-core/configurations/gh-pages/gh-pages.yml +5 -5
  32. data/lib/bridgetown-core/configurations/minitesting.rb +24 -64
  33. data/lib/bridgetown-core/converter.rb +2 -7
  34. data/lib/bridgetown-core/converters/erb_templates.rb +11 -7
  35. data/lib/bridgetown-core/converters/identity.rb +3 -11
  36. data/lib/bridgetown-core/converters/liquid_templates.rb +3 -5
  37. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  38. data/lib/bridgetown-core/converters/markdown.rb +11 -14
  39. data/lib/bridgetown-core/converters/serbea_templates.rb +10 -8
  40. data/lib/bridgetown-core/drops/drop.rb +29 -42
  41. data/lib/bridgetown-core/drops/resource_drop.rb +3 -12
  42. data/lib/bridgetown-core/errors.rb +2 -8
  43. data/lib/bridgetown-core/filters/condition_helpers.rb +6 -9
  44. data/lib/bridgetown-core/filters/date_filters.rb +22 -35
  45. data/lib/bridgetown-core/filters/grouping_filters.rb +11 -11
  46. data/lib/bridgetown-core/filters.rb +53 -72
  47. data/lib/bridgetown-core/front_matter/defaults.rb +14 -19
  48. data/lib/bridgetown-core/generated_page.rb +6 -6
  49. data/lib/bridgetown-core/generators/prototype_generator.rb +0 -2
  50. data/lib/bridgetown-core/helpers.rb +2 -2
  51. data/lib/bridgetown-core/hooks.rb +0 -1
  52. data/lib/bridgetown-core/layout.rb +3 -4
  53. data/lib/bridgetown-core/liquid_extensions.rb +3 -5
  54. data/lib/bridgetown-core/log_adapter.rb +37 -56
  55. data/lib/bridgetown-core/plugin_manager.rb +7 -3
  56. data/lib/bridgetown-core/rack/boot.rb +7 -57
  57. data/lib/bridgetown-core/rack/default_config.ru +14 -0
  58. data/lib/bridgetown-core/rack/loader_hooks.rb +83 -0
  59. data/lib/bridgetown-core/rack/logger.rb +0 -2
  60. data/lib/bridgetown-core/rack/routes.rb +3 -2
  61. data/lib/bridgetown-core/resource/base.rb +8 -8
  62. data/lib/bridgetown-core/resource/permalink_processor.rb +1 -1
  63. data/lib/bridgetown-core/resource/relations.rb +3 -1
  64. data/lib/bridgetown-core/ruby_template_view.rb +0 -1
  65. data/lib/bridgetown-core/static_file.rb +15 -20
  66. data/lib/bridgetown-core/tags/class_map.rb +1 -1
  67. data/lib/bridgetown-core/tags/post_url.rb +2 -32
  68. data/lib/bridgetown-core/utils/initializers.rb +2 -2
  69. data/lib/bridgetown-core/utils/require_gems.rb +1 -3
  70. data/lib/bridgetown-core/utils.rb +41 -44
  71. data/lib/bridgetown-core/watcher.rb +2 -3
  72. data/lib/bridgetown-core.rb +29 -10
  73. data/lib/roda/plugins/bridgetown_server.rb +13 -25
  74. data/lib/roda/plugins/bridgetown_ssr.rb +21 -3
  75. data/lib/roda/plugins/flashier.rb +57 -0
  76. data/lib/roda/plugins/generic_index.html +127 -0
  77. data/lib/roda/plugins/ssg.rb +3 -2
  78. data/lib/site_template/config/initializers.rb +2 -0
  79. data/lib/site_template/package.json.erb +1 -0
  80. data/lib/site_template/postcss.config.js.erb +1 -1
  81. metadata +26 -7
  82. data/lib/bridgetown-core/commands/doctor.rb +0 -147
@@ -49,15 +49,12 @@ module Bridgetown
49
49
  deep_merge_hashes!(master_hash.dup, other_hash)
50
50
  end
51
51
 
52
- # Merges a master hash with another hash, recursively.
52
+ # Merges a master hash with another hash, recursively. This code was lovingly stolen from
53
+ # some random gem: https://rubygems.org/gems/tartan Thanks to whoever made it.
53
54
  #
54
- # master_hash - the "parent" hash whose values will be overridden
55
- # other_hash - the other hash whose values will be persisted after the merge
56
- #
57
- # This code was lovingly stolen from some random gem:
58
- # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
59
- #
60
- # Thanks to whoever made it.
55
+ # @param target [Hash] the "parent" hash whose values will be overridden
56
+ # @param overwrite [Hash] the other hash whose values will be persisted after the merge
57
+ # @return [Hash]
61
58
  def deep_merge_hashes!(target, overwrite)
62
59
  merge_values(target, overwrite)
63
60
  merge_default_proc(target, overwrite)
@@ -110,11 +107,9 @@ module Bridgetown
110
107
 
111
108
  # Parse a date/time and throw an error if invalid
112
109
  #
113
- # input - the date/time to parse
114
- # msg - (optional) the error message to show the user
115
- #
116
- # Returns the parsed date if successful, throws a FatalException
117
- # if not
110
+ # @param input [String] the date/time to parse
111
+ # @param msg [String] the error message to show the user
112
+ # @return [Time] the parsed date if successful, throws a FatalException if not
118
113
  def parse_date(input, msg = "Input could not be parsed.")
119
114
  Time.parse(input).localtime
120
115
  rescue ArgumentError
@@ -140,35 +135,30 @@ module Bridgetown
140
135
  FrontMatter::Loaders::Ruby.header?(file)
141
136
  end
142
137
 
143
- # Slugify a filename or title.
138
+ # Slugify a filename or title
144
139
  #
145
- # string - the filename or title to slugify
146
- # mode - how string is slugified
147
- # cased - whether to replace all uppercase letters with their
148
- # lowercase counterparts
140
+ # When mode is `none`, return the given string.
149
141
  #
150
- # When mode is "none", return the given string.
151
- #
152
- # When mode is "raw", return the given string,
142
+ # When mode is `raw`, return the given string,
153
143
  # with every sequence of spaces characters replaced with a hyphen.
154
144
  #
155
- # When mode is "default", "simple", or nil, non-alphabetic characters are
145
+ # When mode is `default`, `simple`, or `nil`, non-alphabetic characters are
156
146
  # replaced with a hyphen too.
157
147
  #
158
- # When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@)
148
+ # When mode is `pretty`, some non-alphabetic characters (`._~!$&'()+,;=@`)
159
149
  # are not replaced with hyphen.
160
150
  #
161
- # When mode is "ascii", some everything else except ASCII characters
162
- # a-z (lowercase), A-Z (uppercase) and 0-9 (numbers) are not replaced with hyphen.
151
+ # When mode is `ascii`, some everything else except ASCII characters
152
+ # `a-z` (lowercase), `A-Z` (uppercase) and `0-9` (numbers) are not replaced with hyphen.
163
153
  #
164
- # When mode is "latin", the input string is first preprocessed so that
154
+ # When mode is `latin`, the input string is first preprocessed so that
165
155
  # any letters with accents are replaced with the plain letter. Afterwards,
166
- # it follows the "default" mode of operation.
156
+ # it follows the `default` mode of operation.
167
157
  #
168
- # If cased is true, all uppercase letters in the result string are
158
+ # If `cased` is `true`, all uppercase letters in the result string are
169
159
  # replaced with their lowercase counterparts.
170
160
  #
171
- # Examples:
161
+ # @example
172
162
  # slugify("The _config.yml file")
173
163
  # # => "the-config-yml-file"
174
164
  #
@@ -184,7 +174,11 @@ module Bridgetown
184
174
  # slugify("The _config.yml file", "latin")
185
175
  # # => "the-config-yml-file"
186
176
  #
187
- # Returns the slugified string.
177
+ # @param string [String] filename or title to slugify
178
+ # @param mode [String] how string is slugified
179
+ # @param cased [Boolean] whether to replace all uppercase letters with their
180
+ # lowercase counterparts
181
+ # @return [String] the slugified string.
188
182
  def slugify(string, mode: nil, cased: false)
189
183
  mode ||= "default"
190
184
  return nil if string.nil?
@@ -210,13 +204,13 @@ module Bridgetown
210
204
  end
211
205
 
212
206
  # Work the same way as Dir.glob but seperating the input into two parts
213
- # ('dir' + '/' + 'pattern') to make sure the first part('dir') does not act
207
+ # (`'dir' + '/' + 'pattern'`) to make sure the first part(`'dir'`) does not act
214
208
  # as a pattern.
215
209
  #
216
- # For example, Dir.glob("path[/*") always returns an empty array,
217
- # because the method fails to find the closing pattern to '[' which is ']'
210
+ # For example, `Dir.glob("path[/*")` always returns an empty array,
211
+ # because the method fails to find the closing pattern to `[` which is `]`
218
212
  #
219
- # Examples:
213
+ # @example
220
214
  # safe_glob("path[", "*")
221
215
  # # => ["path[/file1", "path[/file2"]
222
216
  #
@@ -226,12 +220,13 @@ module Bridgetown
226
220
  # safe_glob("path", ["**", "*"])
227
221
  # # => ["path[/file1", "path[/folder/file2"]
228
222
  #
229
- # dir - the dir where glob will be executed under
230
- # (the dir will be included to each result)
231
- # patterns - the patterns (or the pattern) which will be applied under the dir
232
- # flags - the flags which will be applied to the pattern
233
- #
234
- # Returns matched pathes
223
+ # @param dir [String] the dir where glob will be executed under
224
+ # (the dir will be included to each result)
225
+ # @param patterns [String, Array<String>] the patterns (or the pattern) which will be applied
226
+ # under the dir
227
+ # @param flags [Integer] the flags which will be applied to the pattern,
228
+ # a bitwise OR of the `File::FNM_XXX` constants
229
+ # @return [Array<String>] matched pathes
235
230
  def safe_glob(dir, patterns, flags = 0)
236
231
  return [] unless Dir.exist?(dir)
237
232
 
@@ -243,8 +238,8 @@ module Bridgetown
243
238
  end
244
239
  end
245
240
 
246
- # Returns merged option hash for File.read of self.site (if exists)
247
- # and a given param
241
+ # @return [Hash] merged option hash for `File.read` of `site` (if exists)
242
+ # and a given param
248
243
  def merged_file_read_opts(site, opts)
249
244
  merged = (site ? site.file_read_opts : {}).merge(opts)
250
245
  if merged[:encoding] && !merged[:encoding].start_with?("bom|")
@@ -256,8 +251,10 @@ module Bridgetown
256
251
  merged
257
252
  end
258
253
 
259
- # Returns a string that's been reindented so that Markdown's four+ spaces =
260
- # code doesn't get triggered for nested Liquid components
254
+ # Provides a string that's been reindented so that Markdown's four+ spaces =
255
+ # code doesn't get triggered for nested components
256
+ # @param input [String]
257
+ # @return [String]
261
258
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
262
259
  def reindent_for_markdown(input)
263
260
  lines = input.lines
@@ -159,9 +159,8 @@ module Bridgetown
159
159
 
160
160
  # Paths to ignore for the watch option
161
161
  #
162
- # options - A Hash of options passed to the command
163
- #
164
- # Returns a list of relative paths from source that should be ignored
162
+ # @param options [Bridgetown::Configuration] options loaded from config and/or CLI
163
+ # @return [Array<String>] list of relative paths from source that should be ignored
165
164
  def listen_ignore_paths(options)
166
165
  source = Pathname.new(options["source"]).expand_path
167
166
  paths = to_exclude(options)
@@ -35,7 +35,7 @@ require "yaml"
35
35
  require "bridgetown-foundation"
36
36
 
37
37
  # 3rd party
38
- require "active_support" # TODO: remove by the end of 2024
38
+ require "active_support" # TODO: remove by the end of 2025
39
39
  require "active_support/core_ext/object/blank"
40
40
  require "active_support/core_ext/string/inflections"
41
41
  require "active_support/core_ext/string/output_safety"
@@ -54,8 +54,9 @@ I18n::Backend::Simple.include I18n::Backend::Fallbacks
54
54
 
55
55
  # Monkey patches:
56
56
 
57
+ # @!visibility private
57
58
  module HashWithDotAccess
58
- class Hash # :nodoc:
59
+ class Hash
59
60
  def to_liquid
60
61
  to_h.to_liquid
61
62
  end
@@ -76,7 +77,6 @@ module Bridgetown
76
77
  autoload :DefaultsReader, "bridgetown-core/readers/defaults_reader"
77
78
  autoload :Deprecator, "bridgetown-core/deprecator"
78
79
  autoload :EntryFilter, "bridgetown-core/entry_filter"
79
- # TODO: we have too many errors! This is silly
80
80
  autoload :Errors, "bridgetown-core/errors"
81
81
  autoload :FrontMatter, "bridgetown-core/front_matter"
82
82
  autoload :GeneratedPage, "bridgetown-core/generated_page"
@@ -100,6 +100,7 @@ module Bridgetown
100
100
  autoload :Slot, "bridgetown-core/slot"
101
101
  autoload :StaticFile, "bridgetown-core/static_file"
102
102
  autoload :Transformable, "bridgetown-core/concerns/transformable"
103
+ autoload :Viewable, "bridgetown-core/concerns/viewable"
103
104
  autoload :Utils, "bridgetown-core/utils"
104
105
  autoload :VERSION, "bridgetown-core/version"
105
106
  autoload :Watcher, "bridgetown-core/watcher"
@@ -132,10 +133,16 @@ module Bridgetown
132
133
 
133
134
  # Set up the Bridgetown execution environment before attempting to load any
134
135
  # plugins or gems prior to a site build
135
- def begin!
136
+ def begin!(with_config: :preflight)
136
137
  ENV["RACK_ENV"] ||= environment
137
138
 
138
- Bridgetown::Current.preloaded_configuration = Bridgetown::Configuration::Preflight.new
139
+ if with_config == :preflight
140
+ Bridgetown::Current.preloaded_configuration ||= Bridgetown::Configuration::Preflight.new
141
+ elsif with_config == :initializers &&
142
+ !Bridgetown::Current.preloaded_configuration.is_a?(Bridgetown::Configuration)
143
+ Bridgetown::Current.preloaded_configuration = Bridgetown.configuration
144
+ end
145
+
139
146
  Bridgetown::PluginManager.setup_bundler
140
147
  end
141
148
 
@@ -366,11 +373,23 @@ module Bridgetown
366
373
  #
367
374
  # @return [String] the path to the cached errors file
368
375
  def build_errors_path
369
- File.join(
370
- (Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration).root_dir,
371
- ".bridgetown-cache",
372
- "build_errors.txt"
373
- )
376
+ site_config = Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration
377
+ File.join(site_config.root_dir, site_config.cache_dir, "build_errors.txt")
378
+ end
379
+
380
+ # This file gets touched each time there's a new build, which then triggers live reload
381
+ # in the browser.
382
+ #
383
+ # @see Bridgetown::Rack::Routes.setup_live_reload
384
+ # @return [String] the path to the empty file being watched
385
+ def live_reload_path
386
+ site_config = Bridgetown::Current.site&.config || Bridgetown::Current.preloaded_configuration
387
+ File.join(site_config.root_dir, site_config.cache_dir, "live_reload.txt")
388
+ end
389
+
390
+ def touch_live_reload_file(path = live_reload_path)
391
+ FileUtils.mkdir_p File.dirname(path)
392
+ FileUtils.touch path
374
393
  end
375
394
  end
376
395
 
@@ -13,20 +13,15 @@ class Roda
13
13
 
14
14
  app.extend ClassMethods # we need to do this here because Roda hasn't done it yet
15
15
  app.plugin :initializers
16
- app.plugin :method_override
17
- app.plugin :all_verbs
18
- app.plugin :hooks
19
16
  app.plugin :common_logger, Bridgetown::Rack::Logger.new($stdout), method: :info
20
17
  app.plugin :json
21
18
  app.plugin :json_parser
22
- app.plugin :indifferent_params
23
- app.plugin :cookies, path: "/"
24
19
  app.plugin :ssg, root: Bridgetown::Current.preloaded_configuration.destination
25
20
  app.plugin :not_found do
26
21
  output_folder = Bridgetown::Current.preloaded_configuration.destination
27
22
  File.read(File.join(output_folder, "404.html"))
28
23
  rescue Errno::ENOENT
29
- "404 Not Found"
24
+ "<h1>404 Not Found</h1>"
30
25
  end
31
26
  app.plugin :exception_page
32
27
  app.plugin :error_handler do |e|
@@ -35,10 +30,10 @@ class Roda
35
30
  )
36
31
  next exception_page(e) if ENV.fetch("RACK_ENV", nil) == "development"
37
32
 
38
- output_folder = Bridgetown::Current.preloaded_configuration.destination
33
+ output_folder = self.class.opts[:bridgetown_preloaded_config].destination
39
34
  File.read(File.join(output_folder, "500.html"))
40
35
  rescue Errno::ENOENT
41
- "500 Internal Server Error"
36
+ "<h1>500 Internal Server Error</h1>"
42
37
  end
43
38
 
44
39
  # TODO: there may be a better way to do this, see `exception_page_css` instance method
@@ -123,9 +118,12 @@ class Roda
123
118
  hook_result = instance_exec(&self.class.opts[:root_hook]) if self.class.opts[:root_hook]
124
119
  next hook_result if hook_result
125
120
 
126
- status, headers, body = self.class.opts[:ssg_server].serving(
127
- request, File.join(self.class.opts[:ssg_root], "index.html")
128
- )
121
+ root_file = [
122
+ File.join(self.class.opts[:ssg_root], "index.html"),
123
+ File.expand_path("generic_index.html", __dir__),
124
+ ].find { File.exist?(_1) }
125
+
126
+ status, headers, body = self.class.opts[:ssg_server].serving(request, root_file)
129
127
  response_headers = response.headers
130
128
  response_headers.replace(headers)
131
129
 
@@ -133,7 +131,7 @@ class Roda
133
131
  rescue StandardError => e
134
132
  Bridgetown.logger.debug("Root handler error: #{e.message}")
135
133
  response.status = 500
136
- "<p>ERROR: cannot find <code>index.html</code> in the output folder.</p>"
134
+ "<p>ERROR: cannot serve the root <code>index</code> file.</p>"
137
135
  end
138
136
  end
139
137
 
@@ -158,21 +156,11 @@ class Roda
158
156
  scope.initialize_bridgetown_context
159
157
  scope.initialize_bridgetown_root
160
158
 
161
- # Run the static file server
162
- ssg
163
-
164
- # There are two different code paths depending on if there's a site `base_path` configured
165
- if Bridgetown::Current.preloaded_configuration.base_path == "/"
159
+ base_path = Bridgetown::Current.preloaded_configuration.base_path.delete_prefix("/")
160
+ on(base_path.empty? ? true : base_path) do
161
+ ssg # static file server
166
162
  Bridgetown::Rack::Routes.load_all scope
167
- return
168
163
  end
169
-
170
- # Support custom base_path configurations
171
- on(Bridgetown::Current.preloaded_configuration.base_path.delete_prefix("/")) do
172
- Bridgetown::Rack::Routes.load_all scope
173
- end
174
-
175
- nil
176
164
  end
177
165
  end
178
166
  end
@@ -13,13 +13,31 @@ class Roda
13
13
  alias_method :site, :bridgetown_site
14
14
  end
15
15
 
16
- def self.load_dependencies(app)
17
- app.plugin :custom_block_results
16
+ def self.load_dependencies(app, opts = { sessions: false })
17
+ app.plugin :all_verbs
18
+ app.plugin :cookies, path: "/"
19
+ app.plugin :indifferent_params
20
+ app.plugin :method_override
21
+ app.plugin :route_csrf
18
22
 
19
23
  # This lets us return callable objects directly in Roda response blocks
24
+ app.plugin :custom_block_results
20
25
  app.handle_block_result(Bridgetown::RodaCallable) do |callable|
21
- callable.(self)
26
+ request.send :block_result_body, callable.(self)
27
+ end
28
+
29
+ return unless opts[:sessions]
30
+
31
+ secret_key = ENV.fetch("RODA_SECRET_KEY", nil)
32
+ unless secret_key
33
+ raise Bridgetown::Errors::InvalidConfigurationError,
34
+ "The Roda sessions plugin can't find a valid secret. Run " \
35
+ "`bin/bridgetown secret' and put the key in your ENV as the " \
36
+ "RODA_SECRET_KEY variable"
22
37
  end
38
+
39
+ app.plugin :sessions, secret: secret_key
40
+ app.plugin :flashier
23
41
  end
24
42
 
25
43
  def self.configure(app, _opts = {}, &)
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Roda
4
+ module RodaPlugins
5
+ module Flashier
6
+ module FlashHashAdditions
7
+ def info
8
+ self["info"]
9
+ end
10
+
11
+ def info=(val)
12
+ self["info"] = val
13
+ end
14
+
15
+ def alert
16
+ self["alert"]
17
+ end
18
+
19
+ def alert=(val)
20
+ self["alert"] = val
21
+ end
22
+ end
23
+
24
+ module FlashHashIndifferent
25
+ def []=(key, val)
26
+ @next[key.to_s] = val
27
+ end
28
+ end
29
+
30
+ module FlashNowHashIndifferent
31
+ def []=(key, val)
32
+ super(key.to_s, val)
33
+ end
34
+
35
+ def [](key)
36
+ super(key.to_s)
37
+ end
38
+ end
39
+
40
+ def self.load_dependencies(app)
41
+ require "roda/plugins/flash"
42
+
43
+ Roda::RodaPlugins::Flash::FlashHash.include FlashHashAdditions, FlashHashIndifferent
44
+ Roda::RodaPlugins::Flash::FlashHash.class_eval do
45
+ def initialize(hash = {})
46
+ super(hash || {})
47
+ now.singleton_class.include FlashHashAdditions, FlashNowHashIndifferent
48
+ @next = {}
49
+ end
50
+ end
51
+ app.plugin :flash
52
+ end
53
+ end
54
+
55
+ register_plugin :flashier, Flashier
56
+ end
57
+ end
@@ -0,0 +1,127 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Bridgetown has loaded</title>
7
+ <style>
8
+ html {
9
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
10
+ }
11
+ a:link, a:visited {
12
+ color: rgb(30,40,38);
13
+ }
14
+ header {
15
+ margin-block: 2rem;
16
+ }
17
+ main {
18
+ margin-block: 2rem;
19
+ margin-inline: auto;
20
+ max-inline-size: 70ch;
21
+ }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <header style="text-align: center">
26
+ <svg aria-label="Bridgetown" width="300" viewBox="0 0 1863 572" version="1.1" xmlns="http://www.w3.org/2000/svg" style="display: inline-block; fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
27
+ <g transform="matrix(1,0,0,1,-1520.67,-710.833)">
28
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
29
+ <g transform="matrix(1,0,0,1,374.543,268.081)">
30
+ <path d="M0,13.784C1.387,13.784 2.283,12.968 2.283,11.664C2.283,10.48 1.387,9.502 0,9.502L-3.629,9.502L-3.629,13.784L0,13.784ZM-0.775,4.404C0.611,4.404 1.591,3.466 1.591,2.12C1.591,0.856 0.611,-0.122 -0.775,-0.122L-3.629,-0.122L-3.629,4.404L-0.775,4.404ZM-9.583,-5.342L0.286,-5.342C4.363,-5.342 7.626,-2.324 7.626,1.508C7.626,3.792 6.687,5.22 4.975,6.524L4.975,6.606C7.504,8.4 8.563,10.114 8.563,12.642C8.563,16.026 5.873,19.126 1.224,19.126L-9.583,19.126L-9.583,-5.342Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
31
+ </g>
32
+ </g>
33
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
34
+ <g transform="matrix(1,0,0,1,404.955,276.605)">
35
+ <path d="M0,-3.264C1.345,-3.264 2.242,-4.65 2.242,-6.078C2.242,-7.504 1.182,-8.77 -0.165,-8.77L-4.813,-8.77L-4.813,-3.264L0,-3.264ZM-10.808,-13.866L-0.571,-13.866C4.688,-13.866 8.114,-10.686 8.114,-6.078C8.114,-1.796 5.954,0.61 2.323,1.508L8.931,10.602L1.427,10.602L-4.813,1.468L-4.813,10.602L-10.808,10.602L-10.808,-13.866Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
36
+ </g>
37
+ </g>
38
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
39
+ <g transform="matrix(1,0,0,1,0,76.979)">
40
+ <rect x="424.149" y="185.76" width="5.995" height="24.468" style="fill:rgb(30,40,38);"/>
41
+ </g>
42
+ </g>
43
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
44
+ <g transform="matrix(1,0,0,1,450.609,268.203)">
45
+ <path d="M0,13.54C3.834,13.54 6.77,10.848 6.77,6.728C6.77,2.936 4.201,-0.04 0,-0.04L-2.406,-0.04L-2.406,13.54L0,13.54ZM-8.401,-5.464L0.123,-5.464C7.341,-5.464 12.928,-0.164 12.928,6.728C12.928,13.254 7.953,19.004 0.123,19.004L-8.401,19.004L-8.401,-5.464Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
46
+ </g>
47
+ </g>
48
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
49
+ <g transform="matrix(1,0,0,1,485.832,288.024)">
50
+ <path d="M0,-26.101C4.527,-26.101 7.667,-24.429 10.236,-21.819L6.076,-17.985C4.404,-19.495 2.325,-20.433 0,-20.433C-4.364,-20.433 -7.177,-17.171 -7.177,-13.051C-7.177,-8.525 -3.956,-5.668 0.122,-5.668C4.404,-5.668 6.484,-8.035 6.646,-10.401L-0.326,-10.401L-0.326,-15.579L13.132,-15.579L13.132,-13.255C13.132,-6.037 8.89,0 0,0C-7.748,0 -13.254,-5.75 -13.254,-13.051C-13.254,-20.351 -7.748,-26.101 0,-26.101" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
51
+ </g>
52
+ </g>
53
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
54
+ <g transform="matrix(1,0,0,1,507.961,287.207)">
55
+ <path d="M0,-24.468L16.191,-24.468L16.191,-19.168L5.995,-19.168L5.995,-14.762L15.417,-14.762L15.417,-9.542L5.995,-9.542L5.995,-5.138L16.64,-5.138L16.64,0L0,0L0,-24.468Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
56
+ </g>
57
+ </g>
58
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
59
+ <g transform="matrix(1,0,0,1,539.963,281.907)">
60
+ <path d="M0,-13.868L-5.464,-13.868L-5.464,-19.168L11.583,-19.168L11.583,-13.868L6.036,-13.868L6.036,5.3L0,5.3L0,-13.868Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
61
+ </g>
62
+ </g>
63
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
64
+ <g transform="matrix(1,0,0,1,574.253,267.591)">
65
+ <path d="M0,14.765C4.322,14.765 7.095,11.5 7.095,7.383C7.095,3.263 4.322,0 0,0C-4.364,0 -7.096,3.263 -7.096,7.383C-7.096,11.5 -4.364,14.765 0,14.765M0,-5.668C7.707,-5.668 13.172,0.082 13.172,7.383C13.172,14.683 7.707,20.433 0,20.433C-7.749,20.433 -13.173,14.683 -13.173,7.383C-13.173,0.082 -7.749,-5.668 0,-5.668" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
66
+ </g>
67
+ </g>
68
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
69
+ <g transform="matrix(1,0,0,1,595.415,288.023)">
70
+ <path d="M0,-25.284L6.28,-25.284L11.216,-13.744L14.192,-21.41L15.683,-25.284L18.842,-25.284L20.489,-21.412L23.735,-13.784L28.221,-25.284L34.461,-25.284L24.266,0L23.449,0L17.413,-14.11L11.583,0L10.808,0L0,-25.284Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
71
+ </g>
72
+ </g>
73
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
74
+ <g transform="matrix(1,0,0,1,639.899,287.207)">
75
+ <path d="M0,-24.468L6.322,-24.468L15.825,-9.95L15.825,-24.468L21.779,-24.468L21.779,0L15.539,0L5.995,-14.558L5.995,0L0,0L0,-24.468Z" style="fill:rgb(30,40,38);fill-rule:nonzero;"/>
76
+ </g>
77
+ </g>
78
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
79
+ <g transform="matrix(1,0,0,1,724.324,209.37)">
80
+ <path d="M0,29.41C-72.335,-66.167 -179.131,-55.549 -222.588,25.781C-227.373,34.738 -221.818,40.631 -219.109,39.985C-214.298,38.838 -197.926,32.314 -192.966,30.318C-190.894,29.485 -189.207,25.502 -187.375,21.877C-150.071,-51.956 -100.392,-60.124 -29.16,95.577C-32.607,77.837 -25.455,57.889 -2.274,37.237C0.394,34.86 2.589,32.831 0,29.41" style="fill:rgb(58,109,98);fill-rule:nonzero;"/>
81
+ </g>
82
+ </g>
83
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
84
+ <g transform="matrix(0.249711,-0.96832,-0.96832,-0.249711,486.176,197.302)">
85
+ <path d="M-12.21,-30.272C-28.365,-22.83 -44.336,-18.635 -46.819,-29.09C-48.223,-18.969 -9.68,-0.335 -12.21,21.62C-12.329,22.654 -10.713,22.914 -10.274,21.97C-1.487,3.05 -6.95,-23.042 -12.21,-30.272" style="fill:rgb(58,109,98);fill-rule:nonzero;"/>
86
+ </g>
87
+ </g>
88
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
89
+ <g transform="matrix(1,0,0,1,810.402,309.68)">
90
+ <path d="M0,-88.196C1.54,-88.196 2.104,-85.899 0.603,-85.55C-30.253,-78.37 -43.813,-48.307 -44.559,-31.561C-44.807,-26.006 -49.573,-25.025 -55.084,-22.473C-61.232,-19.625 -90.024,-7.312 -100.946,-3.404C-106.293,-1.49 -114.206,0.003 -114.576,-8.251C-116.052,-41.137 -81.521,-88.199 0,-88.196" style="fill:rgb(58,109,98);fill-rule:nonzero;"/>
91
+ </g>
92
+ </g>
93
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
94
+ <g transform="matrix(-126.776,-126.776,-126.776,126.776,684.306,302.422)">
95
+ <path d="M0.982,0.451C0.969,0.497 0.927,0.51 0.915,0.489C0.908,0.475 0.904,0.461 0.922,0.407C1.064,-0.03 0.945,-0.409 -0,-0.064C0.038,-0.102 0.068,-0.161 0.081,-0.234C0.45,-0.351 0.717,-0.297 0.868,-0.146C1.006,-0.008 1.047,0.21 0.982,0.451Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/>
96
+ </g>
97
+ </g>
98
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
99
+ <g transform="matrix(0,-49.0052,-49.0052,0,756.207,273.884)">
100
+ <path d="M1,-0.813C0.989,-0.345 0.777,0.495 0.044,0.821C0.016,0.833 -0.014,0.798 0.007,0.775C0.271,0.479 0.447,0.027 0.429,-0.27C0.429,-0.28 0.427,-0.288 0.436,-0.292C0.61,-0.373 0.828,-0.554 0.969,-0.821C0.977,-0.837 1,-0.831 1,-0.814L1,-0.813Z" style="fill:url(#_Linear2);fill-rule:nonzero;"/>
101
+ </g>
102
+ </g>
103
+ <g transform="matrix(4.16667,0,0,4.16667,0,0)">
104
+ <g transform="matrix(30.5248,-8.50108,-8.50108,-30.5248,478.044,231.713)">
105
+ <path d="M0.489,-0.516C0.521,-0.344 0.815,-0.062 1.05,0.111C0.884,0.153 0.635,0.169 0.489,0.081C0.474,0.152 0.308,0.424 0.152,0.616C0.317,0.306 0.438,-0.424 0.489,-0.516Z" style="fill:url(#_Linear3);fill-rule:nonzero;"/>
106
+ </g>
107
+ </g>
108
+ </g>
109
+ <defs>
110
+ <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,0.100447)"><stop offset="0" style="stop-color:rgb(58,109,98);stop-opacity:1"/><stop offset="0.95" style="stop-color:rgb(44,73,73);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(44,73,73);stop-opacity:1"/></linearGradient>
111
+ <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,-0.00347458)"><stop offset="0" style="stop-color:rgb(58,109,98);stop-opacity:1"/><stop offset="0.95" style="stop-color:rgb(44,73,73);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(44,73,73);stop-opacity:1"/></linearGradient>
112
+ <linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.268287,-0.963339,-0.963339,0.268287,0.634136,0.481664)"><stop offset="0" style="stop-color:rgb(58,109,98);stop-opacity:1"/><stop offset="0.95" style="stop-color:rgb(44,73,73);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(44,73,73);stop-opacity:1"/></linearGradient>
113
+ </defs>
114
+ </svg>
115
+ <h1>The server has booted successfully.</h1>
116
+ </header>
117
+
118
+ <main>
119
+ <p>However, it seems like the <code>index</code> file is missing from your source folder.</p>
120
+
121
+ <p>If you add a file like <code>index.erb</code> or <code>index.md</code> to your source folder,
122
+ you'll be able to see that instead of this generic message.</p>
123
+
124
+ <p>Still stuck? <a href="https://www.bridgetownrb.com/community">Our developer community may be able to lend you a hand</a>. Good luck!</p>
125
+ </main>
126
+ </body>
127
+ </html>
@@ -5,7 +5,7 @@ require "rack/files"
5
5
 
6
6
  class Roda
7
7
  module RodaPlugins
8
- # This is a simplifed and modified variant of Roda's Public core plugin. It adds additional
8
+ # This is a simplified and modified variant of Roda's Public core plugin. It adds additional
9
9
  # functionality so that you can host an entire static site through Roda. What's necessary for
10
10
  # this to work is handling "pretty" URLs, aka:
11
11
  #
@@ -29,6 +29,7 @@ class Roda
29
29
  path = PARSER.unescape(real_remaining_path)
30
30
  return if path.include?("\0")
31
31
 
32
+ # @type [Rack::Files]
32
33
  server = roda_class.opts[:ssg_server]
33
34
  path = File.join(server.root, *segments_for_path(path))
34
35
 
@@ -40,7 +41,7 @@ class Roda
40
41
  halt [status, response_headers, body]
41
42
  end
42
43
 
43
- # TODO: this could be refactored a bit
44
+ # TODO: this could be refactored a bit for clarity
44
45
  def segments_for_path(path) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
45
46
  segments = []
46
47
 
@@ -68,6 +68,8 @@ Bridgetown.configure do |config|
68
68
  #
69
69
  # init :ssr
70
70
  #
71
+ # Add `sessions: true` if you need to use session data, flash, etc.
72
+ #
71
73
 
72
74
  # Uncomment to use file-based dynamic template routing via Roda (make sure you
73
75
  # uncomment the gem dependency in your `Gemfile` as well):
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "<%= @site_name %>",
3
3
  "version": "1.0.0",
4
+ "type": "module",
4
5
  "private": true,
5
6
  "scripts": {
6
7
  "esbuild": "node esbuild.config.js --minify",
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  plugins: {
3
3
  'postcss-flexbugs-fixes': {},
4
4
  'postcss-preset-env': {