Allow rendering of <input checked>-style attributes in HTML mode.

This commit is contained in:
Nathan Weizenbaum 2008-02-29 17:56:38 -08:00
parent 71e3678b18
commit ae3c44f574
6 changed files with 67 additions and 8 deletions

View File

@ -144,6 +144,8 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
# </script>
# </head>
#
# ===== 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:
#
# <sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' />
#
# ===== Boolean Attributes
#
# Some attributes, such as "checked" for <tt>input</tt> tags or "selected" for <tt>option</tt> 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
#
# <input selected>
#
# To do this in Haml, just assign a Ruby true value to the attribute:
#
# %input{:selected => true}
#
# Note that <b>a false value will not cause the attribute not to be rendered</b>.
# The following:
#
# %input{:selected => false}
#
# will compile to
#
# <input selected="false">
#
# which is not the same as having no "selected" attribute.
#
# ==== []
#

View File

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

View File

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

View File

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

View File

@ -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 == '"' ? "&quot;" : "&apos;"
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

View File

@ -437,4 +437,8 @@ class EngineTest < Test::Unit::TestCase
def test_html5_doctype
assert_equal %{<!DOCTYPE html>\n}, render('!!!', :format => :html5)
end
def test_html_attributes
assert_equal "<p bar baz='true' foo='bar'>\n</p>\n", render("%p{:foo => 'bar', :bar => true, :baz => 'true'}", :format => :html4)
end
end