Class: DryHamlHandlebars::Handler

Inherits:
Haml::Plugin
  • Object
show all
Defined in:
lib/dry_haml_handlebars/handler.rb

Class Method Summary collapse

Class Method Details

.call(template, options = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/dry_haml_handlebars/handler.rb', line 56

def call(template, options = {})
  
  view_match         = template.identifier.match(/^#{Rails.root.join('app', 'views')}[\/](?<view_path>[\/\w]+)[\/](?<view_name>\w+).html/)
  relative_view_path = view_match[:view_path]
  view_name          = view_match[:view_name]
  view_type          = get_view_type(template, relative_view_path, view_name)
  
  env = Rails.env.to_sym
  out = []
  
  #when in dev mode we can set this variable to true on each request (in the app controller)
  #and we scan for all changed partials (whether needed for the current view or not)
  #this is intended to ensure that all changes are picked up ready for deployment
  #even if the dev forgets to run the view that requires a changed partial
  #the rule is, render ANY page, and ALL partials should be re-compiled (if needed)
  #while for changed templates, you MUST run the view that you have changed
  if DryHamlHandlebars.on_next_request and DryHamlHandlebars.on_next_request.values.any?
    DryHamlHandlebars.on_next_request.keys.each do |method|
      DryHamlHandlebars.on_next_request[method] = false
      case method
      when :compile_all_partials
        out += compile_and_load_all_partials
      else
        DryHamlHandlebars.send method
      end
    end
  end
  
  if [:layout, :ignored_partial].include? view_type
    out << super(template)
    return out.join("\n")
  end
  
  partial_name = [relative_view_path.gsub('/', '_'), view_name[1..-1]].join('_')
  rabl_path, template_path, compiled_template_path = generate_file_names(relative_view_path, view_name)
  
  Rails.logger.info <<-INFO_STRING
    template_path = #{template_path}
    options[:force_handlebars_compile] = #{options[:force_handlebars_compile]}
    File.exist?(compiled_template_path) = #{File.exist?(compiled_template_path)}
    env = #{env}
  INFO_STRING
  
  if options[:force_handlebars_compile] or !File.exist?(compiled_template_path) or ( [:development, :test].include?(env) and ( File.mtime(compiled_template_path) < File.mtime(template.identifier) ) )
    source = template.source
    source = DryHamlHandlebars.dedent_hbs(source)
    template.instance_variable_set "@source", source
    rendered_haml = <<-RUBY
      rendered_haml = eval(%q( #{super(template)} )).html_safe
    RUBY
  else
    rendered_haml = nil
  end
  
  runner = Runner.new(
    template,
    rendered_haml,
    view_type,
    view_name,
    partial_name,
    relative_view_path,
    rabl_path,
    template_path,
    compiled_template_path
  )
  
  out << runner.run
  out.join("\n")
    
end

.compile_and_load_all_partialsObject



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/dry_haml_handlebars/handler.rb', line 127

def compile_and_load_all_partials
  partials = Dir.glob(Rails.root.join('app', 'views', '**', '_*.html.haml'))
  out = []
  partials.each do |fname|
    File.open(fname) do |file|
      source = file.read
      next unless source.starts_with?('-#handlebars_partial')
      source = DryHamlHandlebars.dedent_hbs(source)
      template = ActionView::Template.new(source, fname, nil, {:locals => ["__handlebars_partial"]})
      out << call(template, :force_handlebars_compile => true)
    end
  end
  out
end

.generate_file_names(relative_view_path, view_name) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/dry_haml_handlebars/handler.rb', line 162

def generate_file_names(relative_view_path, view_name)
  
  template_partial_path           = Rails.root.join( *%w(app assets templates)          << "#{relative_view_path}" )
  compiled_template_partial_path  = Rails.root.join( *%w(app assets compiled_templates) << "#{relative_view_path}" )
  
  rabl_path               = Rails.root.join( 'app', 'views', relative_view_path, "#{view_name}.rabl" )
  template_path           = File.join( template_partial_path, "#{view_name}.hbs" )
  compiled_template_path  = File.join( compiled_template_partial_path, "#{view_name}.js" )
  
  FileUtils.mkdir_p template_partial_path             unless File.directory? template_partial_path
  FileUtils.mkdir_p compiled_template_partial_path    unless File.directory? compiled_template_partial_path
  
  return rabl_path, template_path, compiled_template_path
  
end

.get_view_type(template, relative_view_path, view_name) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/dry_haml_handlebars/handler.rb', line 142

def get_view_type(template, relative_view_path, view_name)
  
  #we have 4 types of view;
  # 1) layout           - always handled by haml, no hbs/js versions are generated
  # 2) template         - rendered as handlebars, we expect there to be html.haml AND .rabl for the JSON
  # 3) partial          - pulled into view by handlebars syntax {{>name}}
  # 4) ignored_partial  - a regular partial, it will be rendered by Haml, with no handlebars-related processing
  
  if relative_view_path == 'layouts'
    :layout
  elsif template.locals.include?("__handlebars_partial")
    :partial
  elsif view_name.starts_with? "_"
    :ignored_partial
  else
    :template
  end
        
end