HAML Caching CGI
Mike Zillion asked about how to make HAML a processor (of haml files) for Apache on the HAML Group on Google. That inspired me to write a proper wrapper with caching that will Hamlize templates into HTML and cache those for speedy access on subsequent requests.
This is what I came up with:
#!/bin/env ruby
exit if ARGV[0].nil?
exit unless File.exists?(ARGV[0])
CACHE_DIR_NAME='cache'
haml_file = ARGV[0]
haml_time = File.stat(haml_file).mtime
html_file = CACHE_DIR_NAME + '/' + haml_file.sub(/aml$/,'tml')
if File.exists?(html_file)
html_time = File.stat(html_file).mtime
if html_time > haml_time
output = File.read(html_file)
end
end
if output.nil?
require 'rubygems'
require 'haml'
template = File.read(haml_file)
haml_engine = Haml::Engine.new(template)
output = haml_engine.to_html()
# cache the output
Dir.mkdir(CACHE_DIR_NAME) unless File.directory?(CACHE_DIR_NAME)
html_file_io = File.open(html_file,"w")
html_file_io.print(output)
File.utime(Time.now, haml_time, html_file)
end
# unbuffer output
$stdout.sync = true
require 'cgi'
ENV['SERVER_SOFTWARE'] ||= 'not set'
cgi = CGI.new('html3')
print cgi.header(
'type' => 'text/html',
'charset' => 'UTF-8',
'length' => output.length,
'server' => ENV['SERVER_SOFTWARE'],
'expires' => Time.now + 10*3600*24, # 10 days
'Pragma' => 'no-cache',
'Last-Modified' => haml_time,
'Cache-Control' => 'no-cache'
)
print output
And as Mike suggested, adding a couple lines to your Apache configuration makes all the difference:
AddType text/haml .haml AddHandler haml-file .haml Action haml-file /dev/bin/haml_cache_cgi.rb Action text/haml /dev/bin/haml_cache_cgi.rb
3 Comments