Roda Reference Guide
Bridgetown comes with what we like to call an “opinionated distribution” of the Roda web toolkit, meaning we’ve configured a number of plugins right out of the box for enhanced developer experience.
For a general overview of how to author server-side code, see Server-Rendered Routes.
This base configuration is itself provided by the bridgetown_server
plugin. On a fresh install of a Bridgetown site, you’ll get a server/roda_app.rb
file with the following:
class RodaApp < Roda
plugin :bridgetown_server
route do |r|
r.bridgetown
end
end
The r.bridgetown
method call spins up Bridgetown’s own routing system which is comprised of subclasses of Bridgetown::Rack::Routes
and if the bridgetown-routes
plugin is active, file-based routing (in src/_routes
) as well.
The bridgetown_server
plugin configures the following Roda plugins:
- common_logger - connects Roda up with Bridgetown’s logger
- json - allows arrays or hashes returned from a route block to be converted to JSON output automatically, along with setting
application/json
as the content type for the response - json_parser - parses incoming JSON data and provides it via
r.POST
and alsor.params
Bridgetown also sets up the not_found, exception_page, and error_handler plugins to deal with errors that may arise when processing a request.
We also load our custom ssg
plugin which is loosely based on Roda’s public
plugin and provides serving of static assets using “pretty URLs”, aka:
/path/to/page
->/path/to/page.html
or/path/to/page/index.html
/path/to/page/
->/path/to/page/index.html
If you add init :ssr
to your Initializers config, the bridgetown_ssr
plugin is loaded which configures these additional plugins:
- all_verbs - adds routing methods for additional HTTP verbs like PUT, PATCH, DELETE, etc.
- cookies - adds response methods for setting or deleting cookies, default path is root (
/
) - indifferent_params - lets you access request params using symbols in addition to strings, and also provides a
params
instance method (no need to user.
) - route_csrf - this helps protect against cross-site request forgery in form submissions
- custom_block_results - lets Roda route blocks return arbitrary objects which can be processed with custom handlers. We use this to enable our RodaCallable functionality
method_override
- this Bridgetown-supplied plugin looks for the presence of a_method
form param and will use that to override the incoming HTTP request method. Thus even if a form comes in as POST, if_method
equalsPUT
the request method will bePUT
.
If you pass sessions: true
to the ssr
initializer in your config, you’ll get these plugins added:
- sessions - adds support for cookie-based session storage (aka a small amount of key-val data storage which persists across requests for a single client). You’ll need to have
RODA_SECRET_KEY
defined in your environment. To make this easy in local development, you should set up the Dotenv gem. Setting up a secret key is a matter of runningbin/bridgetown secret
and then copying the key toRODA_SECRET_KEY
. - flash - provides a
flash
object you can access from both routes and view templates.
The following flash
methods are available:
flash.info = "..."
/flash.info
- set an informational message in a route which can then be read once after a redirect.flash.alert = "..."
/flash.alert
- set an alert message in a route which can then be read once after a redirect.flash.now
- lets you set and retrieve flash messages (both.info
and.alert
) for the current request/response cycle.
Bridgetown Route Classes #
If you’ve come to Bridgetown already familiar with Roda, you may be wondering what Bridgetown::Rack::Routes
is and how it works.
Because a traditional Roda application isn’t oriented towards an architecture which plays well with Zeitwerk-based reloading in development, we decided to eschew Roda’s recommended solutions for creating multiple route files (such as the hash_branches
plugin) in favor of a class-based solution.
During the r.bridgetown
routing process, every loaded Bridgetown::Rack::Routes
class is evaluated in turn (sorted by priority) until a route handler has been found (or in lieu of that, a generic 404 response is returned). Route handlers are provided via the route
class method, and the block you provide is evaluated in an instance of that class (not the Roda application itself).
You can still access methods of the Roda application from within a route block because Bridgetown::Rack::Routes
defines method_missing
and delegates calls accordingly. So for example if you were to call flash
in your route block, that call would be passed along to the Roda application. However, if for some reason you were to write def flash
to create an instance method, you’d no longer have access to Roda’s flash
. So it’s recommended that if you do write custom instance methods, you avoid using names which interfere with typical Roda app methods.