bridgetown-core 2.0.0.beta2 → 2.0.0.beta4

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 (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': {