Monkey Patch!

February 22nd, 2008

So after missing the wisdom[1] of this:

http://xkcd.com/386/

And responding to this:

http://b.lesseverything.com/2008/2/19/haml-doesn-t-like-javascript

I went to bed.

This morning I wrote my first Rails (really Haml) Monkey Patch[2]. This adds some of what Steve wanted: undisturbed inline javascript with variable interpolation. I am not sure what else he wanted as I did not read his blog carefully :)

Throw this into lib/inline_javascript.rb

module Haml
  module Filters
    class InlineJavascript
      HEAD =<<EOH
<script type="text/javascript">
//<![CDATA[
EOH

      FOOT =<<EOF
//]]>
</script>
EOF

      def initialize(text)
        @text = HEAD + text + FOOT
      end

      def render
        @text
      end
    end
  end

  module Precompiler
    def close_filtered(filter)
      @flat_spaces = -1
      filtered = filter.new(@filter_buffer).render

      if filter == Haml::Filters::Preserve
        push_silent("_hamlout.buffer << #{filtered.dump} << \"\\n\";")
      elsif filter == Haml::Filters::InlineJavascript
        # suppress eval option does not apply to us
        flush_merged_text
        js = unescape_interpolation(filtered)
        @precompiled  << "_hamlout.buffer << #{js};"
      else
        push_text(filtered.rstrip.gsub("\n", "\n#{'  ' * @output_tabs}"))
      end

      @filter_buffer = nil
      @template_tabs -= 1
    end
  end
end

Throw this at the bottom of your environment.rb, taken from here http://groups.google.com/group/haml/msg/2d890cf1ede761ea

require 'inline_javascript'

Haml::Template.options = {
   :filters => {
     'javascript' => Haml::Filters::InlineJavascript
   }
}

And then do this in your Haml:

:javascript
  function oh_yea() {
    alert('Hello' + '#{@message}')
  }
%a{ :href =>"javascript:oh_yea()" } Oh Yea!

Update

I decided to make a patch and submit it to the Haml folks directly. This gave me the ‘opportunity’ to get git going.

Nathan Weizenbaum took the time to put in a more comprehensive fix to expose the interpolation functionality to all filters – look for it in an upcoming release.

[1] It’s turtles all the way down.

[2] You do not want to know what my subconscious originally thought up as the way to do this – that was twisted.

Leave a Reply