class CGI
# Base module for HTML-generation mixins.
#
# Provides methods for code generation for tags following
# the various DTD element types.
module TagMaker # :nodoc:
# Generate code for an element with required start and end tags.
#
# - -
def nn_element_def(element)
nOE_element_def(element, <<-END)
if block_given?
yield.to_s
else
""
end +
"</#{element.upcase}>"
END
end
# Generate code for an empty element.
#
# - O EMPTY
def nOE_element_def(element, append = nil)
s = <<-END
attributes={attributes=>nil} if attributes.kind_of?(String)
"<#{element.upcase}" + attributes.collect{|name, value|
next unless value
" " + CGI::escapeHTML(name.to_s) +
if true == value
""
else
'="' + CGI::escapeHTML(value.to_s) + '"'
end
}.join + ">"
END
s.sub!(/\Z/, " +") << append if append
s
end
# Generate code for an element for which the end (and possibly the
# start) tag is optional.
#
# O O or - O
def nO_element_def(element)
nOE_element_def(element, <<-END)
if block_given?
yield.to_s + "</#{element.upcase}>"
else
""
end
END
end
end # TagMaker
#
# Mixin module providing HTML generation methods.
#
# For example,
# cgi.a("http://www.example.com") { "Example" }
# # => "<A HREF=\"http://www.example.com\">Example</A>"
#
# Modules Http3, Http4, etc., contain more basic HTML-generation methods
# (:title, :center, etc.).
#
# See class CGI for a detailed example.
#
module HtmlExtension
# Generate an Anchor element as a string.
#
# +href+ can either be a string, giving the URL
# for the HREF attribute, or it can be a hash of
# the element's attributes.
#
# The body of the element is the string returned by the no-argument
# block passed in.
#
# a("http://www.example.com") { "Example" }
# # => "<A HREF=\"http://www.example.com\">Example</A>"
#
# a("HREF" => "http://www.example.com", "TARGET" => "_top") { "Example" }
# # => "<A HREF=\"http://www.example.com\" TARGET=\"_top\">Example</A>"
#
def a(href = "") # :yield:
attributes = if href.kind_of?(String)
{ "HREF" => href }
else
href
end
if block_given?
super(attributes){ yield }
else
super(attributes)
end
end
# Generate a Document Base URI element as a String.
#
# +href+ can either by a string, giving the base URL for the HREF
# attribute, or it can be a has of the element's attributes.
#
# The passed-in no-argument block is ignored.
#
# base("http://www.example.com/cgi")
# # => "<BASE HREF=\"http://www.example.com/cgi\">"
def base(href = "") # :yield:
attributes = if href.kind_of?(String)
{ "HREF" => href }
else
href
end
if block_given?
super(attributes){ yield }
else
super(attributes)
end
end
# Generate a BlockQuote element as a string.
#
# +cite+ can either be a string, give the URI for the source of
# the quoted text, or a hash, giving all attributes of the element,
# or it can be omitted, in which case the element has no attributes.
#
# The body is provided by the passed-in no-argument block
#
# blockquote("http://www.example.com/quotes/foo.html") { "Foo!" }
# #=> "<BLOCKQUOTE CITE=\"http://www.example.com/quotes/foo.html\">Foo!</BLOCKQUOTE>
def blockquote(cite = {}) # :yield:
attributes = if cite.kind_of?(String)
{ "CITE" => cite }
else
cite
end
if block_given?
super(attributes){ yield }
else
super(attributes)
end
end
# Generate a Table Caption element as a string.
#
# +align+ can be a string, giving the alignment of the caption
# (one of top, bottom, left, or right). It can be a hash of
# all the attributes of the element. Or it can be omitted.
#
# The body of the element is provided by the passed-in no-argument block.
#
# caption("left") { "Capital Cities" }
# # => <CAPTION ALIGN=\"left\">Capital Cities</CAPTION>
def caption(align = {}) # :yield:
attributes = if align.kind_of?(String)
{ "ALIGN" => align }
else
align
end
if block_given?
super(attributes){ yield }
else
super(attributes)
end
end
# Generate a Checkbox Input element as a string.
#
# The attributes of the element can be specified as three arguments,
# +name+, +value+, and +checked+. +checked+ is a boolean value;
# if true, the CHECKED attribute will be included in the element.
#
# Alternatively, the attributes can be specified as a hash.
#
# checkbox("name")
# # = checkbox("NAME" => "name")
#
# checkbox("name", "value")
# # = checkbox("NAME" => "name", "VALUE" => "value")
#
# checkbox("name", "value", true)
# # = checkbox("NAME" => "name", "VALUE" => "value", "CHECKED" => true)
def checkbox(name = "", value = nil, checked = nil)
attributes = if name.kind_of?(String)
{ "TYPE" => "checkbox", "NAME" => name,
"VALUE" => value, "CHECKED" => checked }
else
name["TYPE"] = "checkbox"
name
end
input(attributes)
end
# Generate a sequence of checkbox elements, as a String.
#
# The checkboxes will all have the same +name+ attribute.
# Each checkbox is followed by a label.
# There will be one checkbox for each value. Each value
# can be specified as a String, which will be used both
# as the value of the VALUE attribute and as the label
# for that checkbox. A single-element array has the
# same effect.
#
# Each value can also be specified as a three-element array.
# The first element is the VALUE attribute; the second is the
# label; and the third is a boolean specifying whether this
# checkbox is CHECKED.
#
# Each value can also be specified as a two-element
# array, by omitting either the value element (defaults
# to the same as the label), or the boolean checked element
# (defaults to false).
#
# checkbox_group("name", "foo", "bar", "baz")
# # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
# # <INPUT TYPE="checkbox" NAME="name" VALUE="bar">bar
# # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz
#
# checkbox_group("name", ["foo"], ["bar", true], "baz")
# # <INPUT TYPE="checkbox" NAME="name" VALUE="foo">foo
# # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="bar">bar
# # <INPUT TYPE="checkbox" NAME="name" VALUE="baz">baz
#
# checkbox_group("name", ["1", "Foo"], ["2", "Bar", true], "Baz")
# # <INPUT TYPE="checkbox" NAME="name" VALUE="1">Foo
# # <INPUT TYPE="checkbox" CHECKED NAME="name" VALUE="2">Bar
# # <INPUT TYPE="checkbox" NAME="name" VALUE="Baz">Baz
#
# checkbox_group("NAME" => "name",
# "VALUES" => ["foo", "bar", "baz"])
#
# checkbox_group("NAME" => "name",
# "VALUES" => [["foo"], ["bar", true], "baz"])
#
# checkbox_group("NAME" => "name",
# "VALUES" => [["1", "Foo"], ["2", "Bar", true], "Baz"])
def checkbox_group(name = "", *values)
if name.kind_of?(Hash)
values = name["VALUES"]
name = name["NAME"]
end
values.collect{|value|
if value.kind_of?(String)
checkbox(name, value) + value
else
if value[-1] == true || value[-1] == false
checkbox(name, value[0], value[-1]) +
value[-2]
else
checkbox(name, value[0]) +
value[-1]
end
end
}.join
end
# Generate an File Upload Input element as a string.
#
# The attributes of the element can be specified as three arguments,
# +name+, +size+, and +maxlength+. +maxlength+ is the maximum length
# of the file's _name_, not of the file's _contents_.
#
# Alternatively, the attributes can be specified as a hash.
#
# See #multipart_form() for forms that include file uploads.
#
# file_field("name")
# # <INPUT TYPE="file" NAME="name" SIZE="20">
#
# file_field("name", 40)
# # <INPUT TYPE="file" NAME="name" SIZE="40">
#
# file_field("name", 40, 100)
# # <INPUT TYPE="file" NAME="name" SIZE="40" MAXLENGTH="100">
#
# file_field("NAME" => "name", "SIZE" => 40)
# # <INPUT TYPE="file" NAME="name" SIZE="40">
def file_field(name = "", size = 20, maxlength = nil)
attributes = if name.kind_of?(String)
{ "TYPE" => "file", "NAME" => name,
"SIZE" => size.to_s }
else
name["TYPE"] = "file"
name
end
attributes["MAXLENGTH"] = maxlength.to_s if maxlength
input(attributes)
end
# Generate a Form element as a string.
#
# +method+ should be either "get" or "post", and defaults to the latter.
# +action+ defaults to the current CGI script name. +enctype+
# defaults to "application/x-www-form-urlencoded".
#
# Alternatively, the attributes can be specified as a hash.
#
# See also #multipart_form() for forms that include file uploads.
#
# form{ "string" }
# # <FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
#
# form("get") { "string" }
# # <FORM METHOD="get" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
#
# form("get", "url") { "string" }
# # <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
#
# form("METHOD" => "post", "ENCTYPE" => "enctype") { "string" }
# # <FORM METHOD="post" ENCTYPE="enctype">string</FORM>
def form(method = "post", action = script_name, enctype = "application/x-www-form-urlencoded")
attributes = if method.kind_of?(String)
{ "METHOD" => method, "ACTION" => action,
"ENCTYPE" => enctype }
else
unless method.has_key?("METHOD")
method["METHOD"] = "post"
end
unless method.has_key?("ENCTYPE")
method["ENCTYPE"] = enctype
end
method
end
if block_given?
body = yield
else
body = ""
end
if @output_hidden
body += @output_hidden.collect{|k,v|
"<INPUT TYPE=\"HIDDEN\" NAME=\"#{k}\" VALUE=\"#{v}\">"
}.join
end
super(attributes){body}
end
# Generate a Hidden Input element as a string.
#
Loading ...