diff --git a/lib/hamlit.rb b/lib/hamlit.rb index 1b32562f..6dde93ef 100644 --- a/lib/hamlit.rb +++ b/lib/hamlit.rb @@ -1,5 +1,4 @@ require 'hamlit/engine' -require 'hamlit/helpers' require 'hamlit/template' require 'hamlit/version' diff --git a/lib/hamlit/attribute.rb b/lib/hamlit/attribute.rb new file mode 100644 index 00000000..91f3f3d3 --- /dev/null +++ b/lib/hamlit/attribute.rb @@ -0,0 +1,29 @@ +require 'hamlit/concerns/attribute_builder' + +# Hamlit::Attribute is a module to compile old-style attributes which +# can be compiled only on runtime. If you write old-style attributes +# which is not valid as Ruby hash, the attributes are compiled on runtime. +# +# Note that you should avoid writing such a template for performance. +module Hamlit + class Attribute + include Concerns::AttributeBuilder + + def self.build(quote, attributes) + builder = self.new(quote) + builder.build(attributes) + end + + def initialize(quote) + @quote = quote + end + + def build(attributes) + result = '' + flatten_attributes(attributes).each do |key, value| + result += " #{key}=#{@quote}#{value}#{@quote}" + end + result + end + end +end diff --git a/lib/hamlit/compilers/attributes.rb b/lib/hamlit/compilers/attributes.rb index 681c6820..0beabae3 100644 --- a/lib/hamlit/compilers/attributes.rb +++ b/lib/hamlit/compilers/attributes.rb @@ -10,7 +10,7 @@ module Hamlit include Compilers::OldAttribute included do - define_options :format + define_options :format, :attr_quote end def on_haml_attrs(*attrs) diff --git a/lib/hamlit/compilers/old_attribute.rb b/lib/hamlit/compilers/old_attribute.rb index 5acf8968..fe567a36 100644 --- a/lib/hamlit/compilers/old_attribute.rb +++ b/lib/hamlit/compilers/old_attribute.rb @@ -1,3 +1,5 @@ +require 'hamlit/attribute' +require 'hamlit/concerns/attribute_builder' require 'hamlit/concerns/balanceable' require 'hamlit/concerns/ripperable' @@ -6,9 +8,13 @@ require 'hamlit/concerns/ripperable' module Hamlit module Compilers module OldAttribute + include Concerns::AttributeBuilder include Concerns::Balanceable + include Concerns::Ripperable def compile_old_attribute(str) + return runtime_build(str) unless Ripper.sexp(str) + attrs = parse_old_attributes(str) flatten_attributes(attrs).map do |key, value| next true_attribute(key) if value == 'true' @@ -40,22 +46,6 @@ module Hamlit attributes end - def flatten_attributes(attributes) - flattened = {} - - attributes.each do |key, value| - case value - when Hash - flatten_attributes(value).each do |k, v| - flattened["#{key}-#{k}"] = v - end - else - flattened[key] = value - end - end - flattened - end - def read_hash_key!(tokens) skip_tokens!(tokens, :on_sp) @@ -92,6 +82,13 @@ module Hamlit raise SyntaxError unless type == :on_op && str == '=>' end + def runtime_build(str) + str = str.gsub(/(\A\{|\}\Z)/, '') + quote = options[:attr_quote].inspect + code = "::Hamlit::Attribute.build(#{quote}, #{str})" + [[:dynamic, code]] + end + def split_hash(str) columns = HashParser.assoc_columns(str) columns = reject_nested_columns(str, columns) diff --git a/lib/hamlit/concerns/attribute_builder.rb b/lib/hamlit/concerns/attribute_builder.rb new file mode 100644 index 00000000..27d6def4 --- /dev/null +++ b/lib/hamlit/concerns/attribute_builder.rb @@ -0,0 +1,21 @@ +module Hamlit + module Concerns + module AttributeBuilder + def flatten_attributes(attributes) + flattened = {} + + attributes.each do |key, value| + case value + when Hash + flatten_attributes(value).each do |k, v| + flattened["#{key}-#{k}"] = v + end + else + flattened[key] = value + end + end + flattened + end + end + end +end diff --git a/spec/hamlit/engine/old_attributs_spec.rb b/spec/hamlit/engine/old_attributes_spec.rb similarity index 89% rename from spec/hamlit/engine/old_attributs_spec.rb rename to spec/hamlit/engine/old_attributes_spec.rb index 001c7237..da4eebf0 100644 --- a/spec/hamlit/engine/old_attributs_spec.rb +++ b/spec/hamlit/engine/old_attributes_spec.rb @@ -63,5 +63,14 @@ describe Hamlit::Engine do
HTML end + + it 'renders runtime hash attribute' do + assert_render(<<-'HAML', <<-HTML) + - hash = { foo: 'bar' } + %span{ hash } + HAML + + HTML + end end end