Hanami on Papercraft
05·10·2025
Lately I’ve been really excited about Papercraft and the possibilities it brings to developing web apps with Ruby. Frankly, the more I use it, the more I see how simple and joyful it can be to write beautiful HTML templates in plain Ruby.
Now that the Papercraft website is up, I’d like to concentrate on making it easier for everyone to use Papercraft in their apps, whatever their web framework. So this is exactly what I set out to do this weekend. First on my list: Hanami, an established Ruby web framework with a substantial following.
Since I never used Hanami, I decided to follow the Getting Started guide and then started to peek under the hood to see how I could replace the ERB templates with Papercraft ones.
After a few hours and a quite a bit of fiddling, I had a working proof of concept. I then proceeded to extract the code into a new gem I’m releasing today called hanami-papercraft.
To use it, do the following:
1. Add hanami-papercraft
In your Gemfile
, add the following line:
gem "hanami-papercraft"
Then run bundle install
to update your dependencies.
2. Set your app’s basic view class
In app/view.rb
, change the View
classes superclass to Hanami::PapercraftView
:
# app/view.rb
module Bookshelf
class View < Hanami::PapercraftView
end
end
3. Use a Papercraft layout template
Replace the app’s layout template stored in app/templates/layouts/app.html.erb
with a file named app/templates/layouts/app.papercraft.rb
:
# app/templates/layouts/app.papercraft.rb
->(config:, context:, **props) {
html(lang: "en") {
head {
meta charset: "UTF-8"
meta name: "viewport", content: "width=device-width, initial-scale=1.0"
title "Bookshelf"
favicon_tag
stylesheet_tag(context, "app")
}
body {
render_children(config:, context:, **props)
javascript_tag(context, "app")
}
}
}
4. Use Papercraft view templates
You can now start writing your view templates with Papercraft, e.g.:
# app/templates/books/index.papercraft.rb
->(context:, books:, **props) {
h1 "Books"
ul {
books.each do |book|
Kernel.p book
li book[:title]
end
}
}
Passing Template Parameters
While theoretically you have access to the view class in your templates (through
self
), you should use explicit arguments in your templates, as shown in the
examples above. The PapercraftView
class always passes template parameters as
keyword arguments to the layout and the view templates.
In the view template above, the books
keyword argument is defined because the
view class exposes such a parameter:
# app/views/books/index.rb
module Bookshelf
module Views
module Books
class Index < Bookshelf::View
expose :books do
[
{title: "Test Driven Development"},
{title: "Practical Object-Oriented Design in Ruby"}
]
end
end
end
end
end
That’s it for now. There’s probably a lot of stuff that won’t work. If you run into any problems, please let me know. I’ll gladly accept contributions in the form of bug reports or PR’s. Just head on over to the hanami-papercraft repo…