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