Skip to content

Instantly share code, notes, and snippets.

@gyulalaszlo
Last active December 13, 2015 20:39
Show Gist options
  • Save gyulalaszlo/4972073 to your computer and use it in GitHub Desktop.
Save gyulalaszlo/4972073 to your computer and use it in GitHub Desktop.
A Thor task to watch a (directory of .haml templates and compile them to another directory. See usage.md at the bottom.
# Script to watch a directory for any changes to a haml file
# and compile it.
# Copyright © 2013 Gyula László. Code released under the DWTFYW License.
require 'fssm'
require 'haml'
class HamlWatch < Thor
include Thor::Actions
desc 'compile FROM TO', 'Compile the haml files in FROM to TO'
method_option :extension, type: :string, default: '',
desc: 'The new extension to append to the file name instead of .haml'
method_option :encoding, type: :string, default: 'UTF-8',
desc: 'The default encoding to use'
method_option :glob, type: :string, default: '**/*.haml',
desc: 'The glob for the files to look for'
def compile from, to
watched_dir = File.join(File.dirname(__FILE__), from)
output_path = File.join(File.dirname(__FILE__), to)
opts = options
say_status "HamlWatch", "Monitoring for changes to '#{from}'..."
haml_watch = self
glob = options[:glob]
Dir[ File.join( watched_dir, glob ) ].each do |f|
rel_path = f.gsub watched_dir, ''
on_file_recompile watched_dir, rel_path, output_path
end
FSSM.monitor(watched_dir, glob ) do
update { |base, relative| haml_watch.on_file_recompile( base, relative, output_path ) }
create { |base, relative| haml_watch.on_file_recompile( base, relative, output_path ) }
end
end
no_tasks do
# Helper for unifying calls to compilations from fs events
def on_file_recompile base, relative, output_path
input = File.join(base, relative)
# remove the haml extension and replace it with the options provided
output = File.join output_path, relative.gsub!('.haml', options[:extension])
compile_haml_file input, output, encoding: options[:encoding]
end
# Helper for compiling a HAML template to an Html one
# it simply wraps the creation for the output
# and forwards it to run_haml_compiler
def compile_haml_file in_path, out_path, opts={}
opts = { create_directory: true }.merge opts
if opts[:create_directory]
base_path = File.dirname(out_path)
# Create the directory for the output file
empty_directory base_path, verbose: false
end
run_haml_compiler in_path, out_path, opts
end
# Helper method for wrapping the HAML compiler.
def run_haml_compiler in_path, out_path, opts={}
opts = { format: :html5, create_directory: true, encoding: 'UTF-8'}.merge opts
# Convert the format to sym so haml wont throw an error
opts[:format] = opts[:format].to_sym
nice_paths = [in_path, out_path].map {|p| p.gsub(File.dirname(__FILE__), '')}
# Load and compile the template
template = ""
begin
File.open(in_path, "r:#{opts[:encoding]}") { |f| template = f.read }
haml_engine = Haml::Engine.new(template, opts)
File.open(out_path, "w:#{opts[:encoding]}") { |f| f.puts haml_engine.render }
# Try to write out nice paths
say_status "HAML", "[#{Time.now.strftime("%H:%M")}] #{nice_paths[0]} -> #{nice_paths[1]}"
rescue Exception => e
say_status "ERROR", "[#{Time.now.strftime("%H:%M")}] #{nice_paths[0]} -> #{nice_paths[1]}"
puts e
end
end
end
end

Usage:

Install requirements

  $ gem install fssm thor

Get some help about options

  $ thor help haml_watch:help

Compile the .hbs.haml templates in templates/haml to handlebars (.hbs) templates in templates/hbs

  $ thor haml_watch:compile templates/haml templates/hbs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment