Class: Markaby::Builder
- Defined in:
- lib/gems/markaby-0.5/lib/markaby/builder.rb,
lib/gems/markaby-0.5/lib/markaby/rails.rb
Overview
The Markaby::Builder class is the central gear in the system. When using from Ruby code, this is the only class you need to instantiate directly.
mab = Markaby::Builder.new
mab.html do
head { title "Boats.com" }
body do
h1 "Boats.com has great deals"
ul do
li "$49 for a canoe"
li "$39 for a raft"
li "$29 for a huge boot that floats and can fit 5 people"
end
end
end
puts mab.to_s
Constant Summary collapse
- @@default =
{ :indent => 0, :output_helpers => true, :output_xml_instruction => true, :output_meta_tag => true, :auto_validation => true, :tagset => Markaby::XHTMLTransitional }
Instance Attribute Summary collapse
-
#output_helpers ⇒ Object
Returns the value of attribute output_helpers.
-
#tagset ⇒ Object
Returns the value of attribute tagset.
Class Method Summary collapse
Instance Method Summary collapse
-
#_erbout ⇒ Object
Emulate ERB to satisfy helpers like
form_for
. -
#capture(&block) ⇒ Object
Captures the HTML code built inside the
block
. -
#content_for(name, &block) ⇒ Object
Content_for will store the given block in an instance variable for later use in another template or in the layout.
-
#head(*args, &block) ⇒ Object
Builds a head tag.
-
#html_tag(sym, *args, &block) ⇒ Object
Every HTML tag method goes through an html_tag call.
-
#initialize(assigns = {}, helpers = nil, &block) ⇒ Builder
constructor
Create a Markaby builder object.
-
#method_missing(sym, *args, &block) ⇒ Object
This method is used to intercept calls to helper methods and instance variables.
-
#tag!(tag, *args, &block) ⇒ Object
Create a tag named
tag
. -
#text(string) ⇒ Object
(also: #<<, #concat)
Write a
string
to the HTML stream without escaping it. -
#to_s ⇒ Object
Returns a string containing the HTML stream.
-
#xhtml_strict(&block) ⇒ Object
Builds an html tag with XHTML 1.0 Strict doctype instead.
-
#xhtml_transitional(&block) ⇒ Object
Builds an html tag.
Constructor Details
#initialize(assigns = {}, helpers = nil, &block) ⇒ Builder
Create a Markaby builder object. Pass in a hash of variable assignments to assigns
which will be available as instance variables inside tag construction blocks. If an object is passed in to helpers
, its methods will be available from those same blocks.
Pass in a block
to new and the block will be evaluated.
mab = Markaby::Builder.new {
html do
body do
h1 "Matching Mole"
end
end
}
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 61 def initialize(assigns = {}, helpers = nil, &block) @streams = [[]] @assigns = assigns @elements = {} @@default.each do |k, v| instance_variable_set("@#{k}", @assigns[k] || v) end if helpers.nil? @helpers = nil else @helpers = helpers.dup for iv in helpers.instance_variables instance_variable_set(iv, helpers.instance_variable_get(iv)) end end unless assigns.nil? || assigns.empty? for iv, val in assigns instance_variable_set("@#{iv}", val) unless @helpers.nil? @helpers.instance_variable_set("@#{iv}", val) end end end @builder = ::Builder::XmlMarkup.new(:indent => @indent, :target => @streams.last) class << @builder attr_accessor :target, :level end if block text(capture(&block)) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
This method is used to intercept calls to helper methods and instance variables. Here is the order of interception:
-
If
sym
is a helper method, the helper method is called and output to the stream. -
If
sym
is a Builder::XmlMarkup method, it is passed on to the builder object. -
If
sym
is also the name of an instance variable, the value of the instance variable is returned. -
If
sym
has come this far and notagset
is found,sym
and its arguments are passed to tag! -
If a tagset is found, though,
NoMethodError
is raised.
method_missing used to be the lynchpin in Markaby, but it’s no longer used to handle HTML tags. See html_tag for that.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 177 def method_missing(sym, *args, &block) if @helpers.respond_to?(sym, true) && !self.class.ignored_helpers.include?(sym) r = @helpers.send(sym, *args, &block) if @output_helpers and r.respond_to? :to_str fragment { @builder << r } else r end elsif ::Builder::XmlMarkup.instance_methods.include?(sym.to_s) @builder.__send__(sym, *args, &block) elsif instance_variables.include?("@#{sym}") instance_variable_get("@#{sym}") elsif @tagset.nil? tag!(sym, *args, &block) else raise NoMethodError, "no such method `#{sym}'" end end |
Instance Attribute Details
#output_helpers ⇒ Object
Returns the value of attribute output_helpers.
44 45 46 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 44 def output_helpers @output_helpers end |
#tagset ⇒ Object
Returns the value of attribute tagset.
44 45 46 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 44 def @tagset end |
Class Method Details
.ignore_helpers(*helpers) ⇒ Object
40 41 42 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 40 def self.ignore_helpers(*helpers) ignored_helpers.concat helpers end |
.ignored_helpers ⇒ Object
36 37 38 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 36 def self.ignored_helpers @@ignored_helpers ||= [] end |
.set(option, value) ⇒ Object
32 33 34 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 32 def self.set(option, value) @@default[option] = value end |
Instance Method Details
#_erbout ⇒ Object
Emulate ERB to satisfy helpers like form_for
.
25 |
# File 'lib/gems/markaby-0.5/lib/markaby/rails.rb', line 25 def _erbout; self end |
#capture(&block) ⇒ Object
Captures the HTML code built inside the block
. This is done by creating a new stream for the builder object, running the block and passing back its stream as a string.
>> Markaby::Builder.new.capture { h1 "TEST"; h2 "CAPTURE ME" }
=> "<h1>TITLE</h1>\n<h2>CAPTURE ME</h2>\n"
120 121 122 123 124 125 126 127 128 129 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 120 def capture(&block) @streams.push(builder.target = []) @builder.level += 1 str = instance_eval(&block) str = @streams.last.join if @streams.last.any? @streams.pop @builder.level -= 1 builder.target = @streams.last str end |
#content_for(name, &block) ⇒ Object
Content_for will store the given block in an instance variable for later use in another template or in the layout.
The name of the instance variable is content_for_<name> to stay consistent with @content_for_layout which is used by ActionView’s layouts.
Example:
content_for("header") do
h1 "Half Shark and Half Lion"
end
If used several times, the variable will contain all the parts concatenated.
40 41 42 43 |
# File 'lib/gems/markaby-0.5/lib/markaby/rails.rb', line 40 def content_for(name, &block) @helpers.assigns["content_for_#{name}"] = eval("@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)") end |
#head(*args, &block) ⇒ Object
Builds a head tag. Adds a meta
tag inside with Content-Type set to text/html; charset=utf-8
.
230 231 232 233 234 235 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 230 def head(*args, &block) tag!(:head, *args) do tag!(:meta, "http-equiv" => "Content-Type", "content" => "text/html; charset=utf-8") if @output_meta_tag instance_eval(&block) end end |
#html_tag(sym, *args, &block) ⇒ Object
Every HTML tag method goes through an html_tag call. So, calling div
is equivalent to calling html_tag(:div)
. All HTML tags in Markaby’s list are given generated wrappers for this method.
If the @auto_validation setting is on, this method will check for many common mistakes which could lead to invalid XHTML.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 202 def html_tag(sym, *args, &block) if @auto_validation and @tagset.self_closing.include?(sym) and block raise InvalidXhtmlError, "the `\#{sym}' element is self-closing, please remove the block" end if args.empty? and block.nil? and not NO_PROXY.include?(sym) return CssProxy.new do |args, block| if @tagset.forms.include?(sym) and args.last.respond_to?(:to_hash) and args.last[:id] args.last[:name] ||= args.last[:id] end tag!(sym, *args, &block) end end if not @tagset.self_closing.include?(sym) and args.first.respond_to?(:to_hash) block ||= proc{} end tag!(sym, *args, &block) end |
#tag!(tag, *args, &block) ⇒ Object
Create a tag named tag
. Other than the first argument which is the tag name, the arguments are the same as the tags implemented via method_missing.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 133 def tag!(tag, *args, &block) ele_id = nil if @auto_validation and @tagset if !@tagset..has_key?(tag) raise InvalidXhtmlError, "no element `#{tag}' for #{.doctype}" elsif args.last.respond_to?(:to_hash) attrs = args.last.to_hash attrs.each do |k, v| atname = k.to_s.downcase.intern unless k =~ /:/ or @tagset.[tag].include? atname raise InvalidXhtmlError, "no attribute `#{k}' on #{tag} elements" end if atname == :id ele_id = v.to_s if @elements.has_key? ele_id raise InvalidXhtmlError, "id `#{ele_id}' already used (id's must be unique)." end end end end end if block str = capture &block block = proc { text(str) } end f = fragment { @builder.method_missing(tag, *args, &block) } @elements[ele_id] = f if ele_id f end |
#text(string) ⇒ Object Also known as: <<, concat
Write a string
to the HTML stream without escaping it.
104 105 106 107 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 104 def text(string) @builder << "#{string}" nil end |
#to_s ⇒ Object
Returns a string containing the HTML stream. Internally, the stream is stored as an Array.
99 100 101 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 99 def to_s @streams.last.to_s end |
#xhtml_strict(&block) ⇒ Object
Builds an html tag with XHTML 1.0 Strict doctype instead.
246 247 248 249 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 246 def xhtml_strict(&block) self. = Markaby::XHTMLStrict xhtml_html &block end |
#xhtml_transitional(&block) ⇒ Object
Builds an html tag. An XML 1.0 instruction and an XHTML 1.0 Transitional doctype are prepended. Also assumes :xmlns => "http://www.w3.org/1999/xhtml", :lang => "en"
.
240 241 242 243 |
# File 'lib/gems/markaby-0.5/lib/markaby/builder.rb', line 240 def xhtml_transitional(&block) self. = Markaby::XHTMLTransitional xhtml_html &block end |