diff --git a/lib/haml.rb b/lib/haml.rb index 89704aac..cbcb0342 100644 --- a/lib/haml.rb +++ b/lib/haml.rb @@ -144,6 +144,8 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir) # # # +# ===== Attribute Methods +# # A Ruby method call that returns a hash # can be substituted for the hash contents. # For example, Haml::Helpers defines the following method: @@ -182,6 +184,30 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir) # would compile to: # # +# +# ===== Boolean Attributes +# +# Some attributes, such as "checked" for input tags or "selected" for option tags, +# are "boolean" in the sense that their values don't matter - +# it only matters whether or not they're present. +# In HTML (but not XHTML), these attributes can be written as +# +# +# +# To do this in Haml, just assign a Ruby true value to the attribute: +# +# %input{:selected => true} +# +# Note that a false value will not cause the attribute not to be rendered. +# The following: +# +# %input{:selected => false} +# +# will compile to +# +# +# +# which is not the same as having no "selected" attribute. # # ==== [] # diff --git a/lib/haml/buffer.rb b/lib/haml/buffer.rb index 89d237b7..dcf96e1d 100644 --- a/lib/haml/buffer.rb +++ b/lib/haml/buffer.rb @@ -18,6 +18,26 @@ module Haml # The options hash passed in from Haml::Engine. attr_accessor :options + # True if the format is XHTML + def xhtml? + not html? + end + + # True if the format is any flavor of HTML + def html? + html4? or html5? + end + + # True if the format is HTML4 + def html4? + @options[:format] == :html4 + end + + # True if the format is HTML5 + def html5? + @options[:format] == :html5 + end + # Gets the current tabulation of the document. def tabulation @real_tabs + @tabulation @@ -33,7 +53,8 @@ module Haml def initialize(options = {}) @options = { :attr_wrapper => "'", - :ugly => false + :ugly => false, + :format => :xhtml }.merge options @buffer = "" @tabulation = 0 @@ -110,7 +131,8 @@ module Haml str = ">\n" end - @buffer << "#{@options[:ugly] ? '' : tabs(tabulation)}<#{name}#{Precompiler.build_attributes(@options[:attr_wrapper], attributes)}#{str}" + attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes) + @buffer << "#{@options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}" if content if @options[:ugly] || Buffer.one_liner?(content) diff --git a/lib/haml/engine.rb b/lib/haml/engine.rb index 926a659a..7190e70a 100644 --- a/lib/haml/engine.rb +++ b/lib/haml/engine.rb @@ -259,11 +259,12 @@ END end # Returns a hash of options that Haml::Buffer cares about. - # This should remain loadable form #inspect. + # This should remain loadable from #inspect. def options_for_buffer { :attr_wrapper => @options[:attr_wrapper], - :ugly => @options[:ugly] + :ugly => @options[:ugly], + :format => @options[:format] } end end diff --git a/lib/haml/helpers.rb b/lib/haml/helpers.rb index 0e4e8236..cee7fb21 100644 --- a/lib/haml/helpers.rb +++ b/lib/haml/helpers.rb @@ -292,12 +292,14 @@ module Haml attributes = alt_atts end + attributes = Haml::Precompiler.build_attributes(haml_buffer.html?, + haml_buffer.options[:attr_wrapper], attributes) if text.nil? && block.nil? - puts "<#{name}#{Haml::Precompiler.build_attributes(haml_buffer.options[:attr_wrapper], attributes)} />" + puts "<#{name}#{attributes} />" return nil end - puts "<#{name}#{Haml::Precompiler.build_attributes(haml_buffer.options[:attr_wrapper], attributes)}>" + puts "<#{name}#{attributes}>" unless text && text.empty? tab_up # Print out either the text (using push_text) or call the block and add an endline diff --git a/lib/haml/precompiler.rb b/lib/haml/precompiler.rb index 54fa3d67..e0e76d26 100644 --- a/lib/haml/precompiler.rb +++ b/lib/haml/precompiler.rb @@ -452,13 +452,17 @@ END end # This is a class method so it can be accessed from Buffer. - def self.build_attributes(attr_wrapper, attributes = {}) + def self.build_attributes(is_html, attr_wrapper, attributes = {}) quote_escape = attr_wrapper == '"' ? """ : "'" other_quote_char = attr_wrapper == '"' ? "'" : '"' result = attributes.collect do |attr, value| next if value.nil? + if value == true && is_html + next " #{attr}" + end + value = value.to_s this_attr_wrapper = attr_wrapper if value.include? attr_wrapper @@ -474,7 +478,7 @@ END end def prerender_tag(name, self_close, attributes) - attributes_string = Precompiler.build_attributes(@options[:attr_wrapper], attributes) + attributes_string = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes) "<#{name}#{attributes_string}#{self_close && xhtml? ? ' /' : ''}>" end diff --git a/test/haml/engine_test.rb b/test/haml/engine_test.rb index 4594f4dd..4f6ce4f8 100644 --- a/test/haml/engine_test.rb +++ b/test/haml/engine_test.rb @@ -437,4 +437,8 @@ class EngineTest < Test::Unit::TestCase def test_html5_doctype assert_equal %{\n}, render('!!!', :format => :html5) end + + def test_html_attributes + assert_equal "

\n

\n", render("%p{:foo => 'bar', :bar => true, :baz => 'true'}", :format => :html4) + end end