diff --git a/.rubocop.yml b/.rubocop.yml
index 82c6d296b..efcd70e96 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -11,9 +11,6 @@ inherit_gem:
Bridgetown/NoPutsAllowed:
Exclude:
- rake/*.rake
- - bridgetown-core/lib/bridgetown-core/commands/base.rb
- - bridgetown-core/lib/bridgetown-core/commands/plugins.rb
- - bridgetown-core/lib/bridgetown-core/rack/roda.rb
AllCops:
TargetRubyVersion: 2.7
diff --git a/bridgetown-core/.rubocop.yml b/bridgetown-core/.rubocop.yml
index 1b02eeeac..333cc662b 100644
--- a/bridgetown-core/.rubocop.yml
+++ b/bridgetown-core/.rubocop.yml
@@ -12,11 +12,15 @@ AllCops:
- tmp/**/*
- test/source/**/*
- test/resources/src/_pages/*.rb
+ - lib/bridgetown-core/commands/base.rb
+ - lib/bridgetown-core/commands/plugins.rb
+ - lib/bridgetown-core/rack/roda.rb
- lib/site_template/TEMPLATES/**/*
- lib/site_template/Rakefile
- lib/site_template/config.ru
- lib/site_template/config/**/*
- lib/site_template/plugins/site_builder.rb
+ - lib/site_template/server/roda_app.rb
Lint/ConstantDefinitionInBlock:
Exclude:
diff --git a/bridgetown-core/lib/bridgetown-core/rack/roda.rb b/bridgetown-core/lib/bridgetown-core/rack/roda.rb
index 5e46d4875..beeccf77b 100644
--- a/bridgetown-core/lib/bridgetown-core/rack/roda.rb
+++ b/bridgetown-core/lib/bridgetown-core/rack/roda.rb
@@ -2,6 +2,13 @@
require "rack/indifferent"
+begin
+ # If it's in the Gemfile's :bridgetown_plugins group it's already been required, but we'll try
+ # again just to be on the safe side:
+ require "bridgetown-routes"
+rescue LoadError
+end
+
class Roda
module RodaPlugins
module BridgetownSSR
@@ -12,6 +19,34 @@ def self.configure(app, _opts = {}, &block)
end
register_plugin :bridgetown_ssr, BridgetownSSR
+
+ module BridgetownBoot
+ module InstanceMethods
+ # Helper shorthand for Bridgetown::Current.site
+ # @return [Bridgetown::Site]
+ def bridgetown_site
+ Bridgetown::Current.site
+ end
+ end
+
+ Roda::RodaRequest.alias_method :_previous_roda_cookies, :cookies
+
+ module RequestMethods
+ # Monkeypatch Roda/Rack's Request object so it returns a hash which allows for
+ # indifferent access
+ def cookies
+ # TODO: maybe replace with a simpler hash that offers an overloaded `[]` method
+ _previous_roda_cookies.with_indifferent_access
+ end
+
+ # Starts up the Bridgetown routing system
+ def bridgetown
+ Bridgetown::Rack::Routes.start!(scope)
+ end
+ end
+ end
+
+ register_plugin :bridgetown_boot, BridgetownBoot
end
end
@@ -24,6 +59,7 @@ class Roda < ::Roda
plugin :json_parser
plugin :cookies
plugin :streaming
+ plugin :bridgetown_boot
plugin :public, root: Bridgetown::Current.preloaded_configuration.destination
plugin :not_found do
output_folder = Bridgetown::Current.preloaded_configuration.destination
@@ -56,12 +92,6 @@ class Roda < ::Roda
"
ERROR: cannot find index.html
in the output folder.
"
end
end
-
- # Helper shorthand for Bridgetown::Current.site
- # @return [Bridgetown::Site]
- def bridgetown_site
- Bridgetown::Current.site
- end
end
end
end
diff --git a/bridgetown-core/lib/site_template/server/roda_app.rb b/bridgetown-core/lib/site_template/server/roda_app.rb
index bfd452e85..eaebb69ae 100644
--- a/bridgetown-core/lib/site_template/server/roda_app.rb
+++ b/bridgetown-core/lib/site_template/server/roda_app.rb
@@ -4,21 +4,18 @@
#
# Learn more at: http://roda.jeremyevans.net
-# Uncomment to use file-based dynamic routing in your project (make sure you
-# uncomment the gem dependency in your Gemfile as well):
-# require "bridgetown-routes"
-
class RodaApp < Bridgetown::Rack::Roda
# Add additional Roda configuration here if needed
# Uncomment to use Bridgetown SSR:
# plugin :bridgetown_ssr
- # And optionally file-based routing:
+ # Uncomment to use file-based dynamic routing in your project (make sure you
+ # uncomment the gem dependency in your `Gemfile` as well):
# plugin :bridgetown_routes
route do |r|
# Load Roda routes in server/routes (and src/_routes via `bridgetown-routes`)
- Bridgetown::Rack::Routes.start! self
+ r.bridgetown
end
end
diff --git a/bridgetown-core/test/ssr/server/roda_app.rb b/bridgetown-core/test/ssr/server/roda_app.rb
index 7c7570f66..ecdff6a3c 100644
--- a/bridgetown-core/test/ssr/server/roda_app.rb
+++ b/bridgetown-core/test/ssr/server/roda_app.rb
@@ -6,7 +6,5 @@ class RodaApp < Bridgetown::Rack::Roda
site.data.iterations += 1
end
- route do |_r|
- Bridgetown::Rack::Routes.start! self
- end
+ route(&:bridgetown)
end
diff --git a/bridgetown-core/test/ssr/server/routes/cookies.rb b/bridgetown-core/test/ssr/server/routes/cookies.rb
new file mode 100644
index 000000000..9da5d964c
--- /dev/null
+++ b/bridgetown-core/test/ssr/server/routes/cookies.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class Routes::Cookies < Bridgetown::Rack::Routes
+ route do |r|
+ # route: GET /cookies
+ r.get "cookies" do
+ { value: r.cookies[:test_key] }
+ end
+
+ # route: POST /cookies
+ r.post "cookies" do
+ response.set_cookie :test_key, {
+ value: r.params[:value],
+ httponly: true,
+ }
+
+ { value: r.cookies[:test_key] }
+ end
+ end
+end
diff --git a/bridgetown-core/test/ssr/server/routes/ooh_json.rb b/bridgetown-core/test/ssr/server/routes/ooh_json.rb
new file mode 100644
index 000000000..85ecf5446
--- /dev/null
+++ b/bridgetown-core/test/ssr/server/routes/ooh_json.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class Routes::OohJson < Bridgetown::Rack::Routes
+ route do |r|
+ # route: POST /cookies
+ r.post "ooh_json" do
+ next { keep_on: "running" } unless r.params[:tell_me] == "what you're chasin'"
+
+ { because_the_night: "will never give you what you want" }
+ end
+ end
+end
diff --git a/bridgetown-core/test/test_ssr.rb b/bridgetown-core/test/test_ssr.rb
index 502eff9f5..e00091158 100644
--- a/bridgetown-core/test/test_ssr.rb
+++ b/bridgetown-core/test/test_ssr.rb
@@ -9,6 +9,10 @@ def app
@@ssr_app ||= Rack::Builder.parse_file(File.expand_path("ssr/config.ru", __dir__)).first # rubocop:disable Style/ClassVars
end
+ def site
+ app.opts[:bridgetown_site]
+ end
+
context "Roda-powered Bridgetown server" do
setup do
Bridgetown::Current.site = nil
@@ -32,11 +36,22 @@ def app
end
should "preserve site data between live reloads" do
- app # ensure it's been run
- site = @@ssr_app.opts[:bridgetown_site]
assert_equal 1, site.data.iterations
site.reset(soft: true)
assert_equal 2, site.data.iterations
end
+
+ should "support indifferent cookies" do
+ post "/cookies", value: "Gookie!"
+ get "/cookies"
+ assert last_response.ok?
+ assert_equal({ value: "Gookie!" }.to_json, last_response.body)
+ end
+
+ should "support incoming JSON payloads" do
+ post "/ooh_json", { tell_me: "what you're chasin'" }
+ assert last_response.ok?
+ assert_equal({ because_the_night: "will never give you what you want" }.to_json, last_response.body)
+ end
end
end
diff --git a/bridgetown-routes/lib/bridgetown-routes.rb b/bridgetown-routes/lib/bridgetown-routes.rb
index 87ff0e6c6..fb23397d1 100644
--- a/bridgetown-routes/lib/bridgetown-routes.rb
+++ b/bridgetown-routes/lib/bridgetown-routes.rb
@@ -16,6 +16,7 @@ module Routes
# rubocop:disable Bridgetown/NoPutsAllowed
def self.print_roda_routes
+ # TODO: this needs to be fully documented, currently no info on how to generate .routes.json
routes = begin
JSON.parse(File.read("#{Dir.pwd}/.routes.json"))
rescue StandardError
diff --git a/bridgetown-website/server/roda_app.rb b/bridgetown-website/server/roda_app.rb
index 619d1f7e7..8efa8a48f 100644
--- a/bridgetown-website/server/roda_app.rb
+++ b/bridgetown-website/server/roda_app.rb
@@ -7,9 +7,7 @@
class RodaApp < Bridgetown::Rack::Roda
plugin :bridgetown_ssr
- route do
- # Load all the files in server/routes
- # see hello.rb.sample
- Bridgetown::Rack::Routes.start! self
+ route do |r|
+ r.bridgetown
end
end
diff --git a/bridgetown-website/src/_docs/routes.md b/bridgetown-website/src/_docs/routes.md
index da0d8699f..dbe732c4e 100644
--- a/bridgetown-website/src/_docs/routes.md
+++ b/bridgetown-website/src/_docs/routes.md
@@ -157,12 +157,6 @@ To opt-into the `bridgetown-routes` gem, make sure it's enabled in your `Gemfile
gem "bridgetown-routes", group: :bridgetown_plugins
```
-and required at the top of your `server/roda_app.rb` file:
-
-```ruby
-require "bridgetown-routes"
-```
-
and added in as a Roda plugin below the SSR plugin:
```ruby