Generating Static Pages with Rails
When working on Filedart we wanted some statically served pages, but to use our site template(s) to have them fit the look and feel. Updating our site’s assets (javascript, css, images, etc) should be easy to update in our static pages as well. Here is a brief overview of how I made this happen.
The approach I took to achieve this was to create a controller (I called it static)
[code language=”shell”]$ rails g controller static page1 page2 page3 …[/code]
Then I added some routes for development only:
config/routes.rb
[code language=”ruby”]
if Rails.env.development?
get "static/page1"
get "static/page2"
get "static/page3"
end
[/code]
Then I wrote a rake task to generate the static pages:
lib/tasks/app.rake:
[code language=”ruby”]
namespace :app do
desc "Generate static pages"
task static: [:my_pages]
desc "Generates static pages"
task my_pages: :environment do
pages = {
‘static/page1’ => ‘page1.html’,
‘static/page2’ => ‘page2.html’,
‘static/page3’ => ‘page3.html’
}
app = ActionDispatch::Integration::Session.new(Rails.application)
pages.each do |route, output|
puts "Generating #{output}…"
outpath = File.join ([Rails.root, ‘public’, output])
resp = app.get(route)
if resp == 200
File.delete(outpath) unless not File.exists?(outpath)
File.open(outpath, ‘w’) do |f|
f.write(app.response.body)
end
else
puts "Error generating #{output}!"
end
end
end
end
[/code]
Once that was in place, regenerating our static pages is as simple as running:
[code language=”shell”]$ rake app:static[/code]
How it works
This works by using the integration testing features of rails to programmatically send requests to a controller, then writing the response to a string. The original static file is deleted, the request is generated, and the response is written to the destination file in public/.
Caveats
The static pages are only generated manually, so make sure you run the rake task when you want new pages built. This could be fixed by adding a capistrano task to run the generation on deploy (and removing the generated pages from vcs). Also be careful if you use things like request.host
as you’ll get www.example.com
or localhost.
We use this technique for some of our error pages, but also things that don’t change often.