Using Phlex in Sinatra with phlex-sinatra
Phlex already works with Sinatra (and everything else) but its normal usage leaves you without access to Sinatra’s standard helper methods. That’s why I created phlex-sinatra which lets you use Sinatra’s url()
helper from within Phlex (along with the rest of the usual helper methods available in a Sinatra action).
To enable the integration use the phlex
method in your Sinatra action and pass an instance of the Phlex view (instead of using .call
to get its output):
get '/foo' do
phlex MyView.new
end
You can now use Sinatra’s url()
helper method directly and its other methods (params
, request
, etc) via the helpers
proxy:
class MyView < Phlex::HTML
def template
h1 { 'Phlex / Sinatra integration' }
p {
a(href: url('/foo', false)) { 'link to foo' }
}
pre { helpers.params.inspect }
end
end
Why?
It might not seem obvious at first why you’d use url()
at all given that you mostly just pass the string you want to output 🤷🏻♂️ but I hit the issue immediately when I switched to Phlex in my Wordle results Sinatra/Parklife microsite hosted on GitHub Pages.
One of the main features of using Parklife is that your development flow remains completely unchanged. In development you start the server as usual which means the app is almost certainly served from the root /
, but if the static site is hosted as a GitHub Pages repository site it’ll be served from /my-repository-name
– which means all your links will be broken in production! It’s incredibly frustrating but luckily easily fixed.
Step 1 is to use Sinatra’s url()
helper method wherever you need a URL (the false
second argument means the scheme/host isn’t included):
link(href: url('/app.css', false), rel: 'stylesheet', type: 'text/css')
Step 2, configure a Parklife base
:
Parklife.application.config.base = '/wordle'
It’s also possible to pass --base
at build-time, in fact if you used Parklife to generate a GitHub Actions workflow (parklife init --github-pages
) then it’s already configured to fetch your GitHub Pages site URL – whether it’s a custom domain or a standard repository site – and pass it to the build script so you won’t need to manually configure it as above.
Step 3 (profit?). The result is that when Parklife generates the static build Sinatra will know to serve the site from the /wordle
subpath and will include the prefix on all url()
-generated URLs:
<link href="/wordle/app.css" rel="stylesheet" type="text/css">
Another main reason to use the url()
helper is to generate a full URL – for instance from within a feed or for an og:image
social media preview link. In this case don’t pass the false
second argument (it defaults to true
) and the full URL will be generated. Once again you’ll need to configure Parklife with the correct base but once again it’s already taken care of if you generated the GitHub Actions workflow with parklife init --github-pages
.