1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Create runtime attribute builder

This commit is contained in:
Takashi Kokubun 2015-03-30 12:36:07 +09:00
parent eeec03feaf
commit 28ef521ced
6 changed files with 73 additions and 18 deletions

View file

@ -1,5 +1,4 @@
require 'hamlit/engine'
require 'hamlit/helpers'
require 'hamlit/template'
require 'hamlit/version'

29
lib/hamlit/attribute.rb Normal file
View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -63,5 +63,14 @@ describe Hamlit::Engine do
<body class='bb' data-confirm='really?' data-disable id='a'></body>
HTML
end
it 'renders runtime hash attribute' do
assert_render(<<-'HAML', <<-HTML)
- hash = { foo: 'bar' }
%span{ hash }
HAML
<span foo='bar'></span>
HTML
end
end
end