I’m not going to talk about setup and configuration cuz it’s trivial! Instead lets see how jekyll is served from heroku.
Jekyll generated site is a static site, so having something serving static files is just fine. There’s Rack::Static middleware shipped with Rack and you can use it for this purpose, ie with sample config.ru:
use ::Rack::Static,
:root => "public", # or _site/ where *.html are generated
:urls => %w[/] # match all requests
# otherwise 404 NotFound
run lambda { [404, {'Content-Type' => 'text/plain'}, ['whoops! Not Found']]}
starting rackup and pointing browser to http://localhost:9292/index.html
should yield a jekyll homepage!
Pretty cool, huh?
But there’s a problem: noone types /index.html
these days!
rack/contrib/try_static
TryStatic
is part of the rack-contrib-1.1.0
gem since this commit
With rack-contrib
gem it’s even more simple! So now my config.ru
looks like:
require 'rack'
require 'rack/contrib/try_static'
use Rack::TryStatic,
:root => "public", # static files root dir
:urls => %w[/], # match all requests
:try => ['.html', 'index.html', '/index.html'] # try these postfixes sequentially
# otherwise 404 NotFound
run lambda { [404, {'Content-Type' => 'text/html'}, ['whoops! Not Found']]}
# vi: ft=ruby
And all we need to add a heroku gem manifest: .gems
file, with content
rack-contrib
that’s it! Now you can push your app to heroku.
Outdated
Solutions below are obsolete and for reference only! Use rack-contrib
gem instead as described above.
rack-try_static gem
Using gem it’s even more simple! So now my config.ru
looks like:
require 'rack'
require 'rack/contrib/try_static'
use Rack::TryStatic,
:root => "public", # static files root dir
:urls => %w[/], # match all requests
:try => ['.html', 'index.html', '/index.html'] # try these postfixes sequentially
# otherwise 404 NotFound
run lambda { [404, {'Content-Type' => 'text/html'}, ['whoops! Not Found']]}
# vi: ft=ruby
And all we need to add a heroku gem manifest: .gems
file, with content
rack-try_static
that’s it! Now you can push your app to heroku.
my initial quick solution
module ::Rack
class TryStatic < Static
def initialize(app, options)
super
@try = ([''] + Array(options.delete(:try)) + [''])
end
def call(env)
@next = 0
while @next < @try.size && 404 == (resp = super(try_next(env)))[0]
@next += 1
end
404 == resp[0] ? @app.call : resp
end
private
def try_next(env)
env.merge('PATH_INFO' => env['PATH_INFO'] + @try[@next])
end
end
end
use Rack::TryStatic,
:root => "public", # static files root dir
:urls => %w[/], # match all requests
:try => ['.html', 'index.html', '/index.html'] # try these postfixes sequentially
# otherwise 404 NotFound
run lambda { [404, {'Content-Type' => 'text/plain'}, ['whoops! Not Found']]}
# vi: ft=ruby
I’ve called it Rack::TryStatic as it sequentially tries to serve a static file according :try
option.
TODO
- improve code
- spec
- merge to rack-contrib