Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I embed CoffeeScript in Haml outside of Ruby/Rails?

It's easy to use coffee-haml-filter within Rails. Under Rails 2, run

script/plugin install git://github.com/gerad/coffee-haml-filter.git

Under Rails 3, you can add the line

gem 'coffee-haml-filter', :git => 'git://github.com/gerad/coffee-haml-filter.git'

to your Gemfile and do a bundle install. (This is all assuming that you want to use gerad's fork, which is more up-to-date than inem's original version, as of this writing.).

In any other Ruby application, it's slightly trickier but still fairly easy to do this (for instance, using a Gemfile and Bundler.require; or more simply by downloading the coffee.rb file directly from gerad's repo, sticking it in a folder, and require-ing it).

But what if I'm just using haml on the command line, for instance? Is there a way to install a custom filter in such a way that Haml uses it system-wide? Or could I perhaps use a require statement from within the Haml template to get the needed filter?

like image 758
Trevor Burnham Avatar asked Feb 24 '23 22:02

Trevor Burnham


2 Answers

Just recently, a new CoffeeScript Haml filter came out that's installable at the system level, just like I wanted: https://github.com/paulnicholson/coffee-filter

You have to run Haml with the arguments -r 'coffee-filter' on the command line, though. See this discussion.

like image 129
Trevor Burnham Avatar answered Mar 05 '23 09:03

Trevor Burnham


Making a custom HAML filter should be as easy as including the Haml::Filters::Base module in your class and overriding the render method, but I was unable to make it work with the -r option of the haml script, or trying to put the filter code into the HAML template directly. The script just failed too early on with a Filter "coffee" is not defined error.

So I ended up writing my own script. It is not using the coffee-haml-filter you mentioned, but implements a :coffee filter on its own. It takes the haml script filename as an argument. It could definitely have been written better, but it works well for my purposes.

#! /usr/bin/env ruby
require 'tempfile'
require 'haml'

TEMPDIR = '/dev/shm'

module Haml::Filters::Coffee
  include Haml::Filters::Base

  def render(text)
    tmpf = Tempfile.new('hamlcoffee', TEMPDIR)
    tmpf.write text
    tmpf.close
    output = `coffee -pl '#{tmpf.path}'`

    # strip the first and last line,
    # since the js code is wrapped as a function
    output = output.lines.collect[1..-2].join
    return output
  end
end

template = File.read(ARGV[0])
haml_engine = Haml::Engine.new(template)
output = haml_engine.render
puts output
like image 30
mykhal Avatar answered Mar 05 '23 07:03

mykhal