Class: Markaby::Builder
- Inherits:
-
Object
- Object
- Markaby::Builder
- Includes:
- BuilderTags
- Defined in:
- lib/markaby/builder.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_OPTIONS =
{ :indent => 0, :output_helpers => true, :output_xml_instruction => true, :output_meta_tag => 'xhtml', :auto_validation => true, :tagset => Markaby::XHTMLTransitional, :root_attributes => { :xmlns => 'http://www.w3.org/1999/xhtml', :'xml:lang' => 'en', :lang => 'en' } }
- HTML5_OPTIONS =
{ :indent => 0, :output_helpers => true, :output_xml_instruction => false, :output_meta_tag => 'html5', :auto_validation => true, :tagset => Markaby::HTML5, :root_attributes => {} }
- @@options =
DEFAULT_OPTIONS.dup
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
- .get(option) ⇒ Object
- .ignore_helpers(*helpers) ⇒ Object
- .ignored_helpers ⇒ Object
- .restore_defaults! ⇒ Object
- .set(option, value) ⇒ Object
- .set_html5_options! ⇒ Object
Instance Method Summary collapse
-
#capture(&block) ⇒ Object
Captures the HTML code built inside the
block
. - #helper=(helper) ⇒ Object
-
#initialize(assigns = {}, helper = nil, &block) ⇒ Builder
constructor
Create a Markaby builder object.
- #locals=(locals) ⇒ Object
-
#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.
Methods included from BuilderTags
#enable_html5!, #head, #html5, #html_tag, #xhtml_frameset, #xhtml_strict, #xhtml_transitional
Constructor Details
#initialize(assigns = {}, helper = 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 helper
, 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
}
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/markaby/builder.rb', line 94 def initialize(assigns = {}, helper = nil, &block) @streams = [Stream.new] @assigns = assigns.dup @_helper = helper @used_ids = {} @@options.each do |k, v| instance_variable_set("@#{k}", @assigns.delete(k) || v) end @assigns.each do |k, v| instance_variable_set("@#{k}", v) end if helper helper.instance_variables.each do |iv| instance_variable_set(iv, helper.instance_variable_get(iv)) end end @builder = XmlMarkup.new(:indent => @indent, :target => @streams.last) text(capture(&block)) if block end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object (private)
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.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/markaby/builder.rb', line 231 def method_missing(sym, *args, &block) if @_helper.respond_to?(sym, true) && !self.class.ignored_helpers.include?(sym) r = @_helper.send(sym, *args, &block) if @output_helpers && r.respond_to?(:to_str) fragment { @builder << r } else r end elsif @assigns.has_key?(sym) @assigns[sym] elsif @assigns.has_key?(stringy_key = sym.to_s) # Rails' ActionView assigns hash has string keys for # instance variables that are defined in the controller. @assigns[stringy_key] elsif instance_variables_for(self).include?(ivar = "@#{sym}".to_sym) instance_variable_get(ivar) elsif @_helper && instance_variables_for(@_helper).include?(ivar) @_helper.instance_variable_get(ivar) elsif instance_methods_for(::Builder::XmlMarkup).include?(sym) @builder.__send__(sym, *args, &block) elsif !@tagset tag!(sym, *args, &block) else super end end |
Instance Attribute Details
#output_helpers ⇒ Object
Returns the value of attribute output_helpers.
77 78 79 |
# File 'lib/markaby/builder.rb', line 77 def output_helpers @output_helpers end |
#tagset ⇒ Object
Returns the value of attribute tagset.
77 78 79 |
# File 'lib/markaby/builder.rb', line 77 def @tagset end |
Class Method Details
.get(option) ⇒ Object
65 66 67 |
# File 'lib/markaby/builder.rb', line 65 def self.get(option) @@options[option] end |
.ignore_helpers(*helpers) ⇒ Object
73 74 75 |
# File 'lib/markaby/builder.rb', line 73 def self.ignore_helpers(*helpers) ignored_helpers.concat helpers end |
.ignored_helpers ⇒ Object
69 70 71 |
# File 'lib/markaby/builder.rb', line 69 def self.ignored_helpers @@ignored_helpers ||= [] end |
.restore_defaults! ⇒ Object
53 54 55 |
# File 'lib/markaby/builder.rb', line 53 def self.restore_defaults! @@options = DEFAULT_OPTIONS.dup end |
.set(option, value) ⇒ Object
61 62 63 |
# File 'lib/markaby/builder.rb', line 61 def self.set(option, value) @@options[option] = value end |
.set_html5_options! ⇒ Object
57 58 59 |
# File 'lib/markaby/builder.rb', line 57 def self. @@options = HTML5_OPTIONS.dup end |
Instance Method Details
#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>TEST</h1><h2>CAPTURE ME</h2>"
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/markaby/builder.rb', line 159 def capture(&block) @streams.push(@builder.target = Stream.new) @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 |
#helper=(helper) ⇒ Object
119 120 121 |
# File 'lib/markaby/builder.rb', line 119 def helper=(helper) @_helper = helper end |
#locals=(locals) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/markaby/builder.rb', line 130 def locals=(locals) locals.each do |key, value| do define_method key do value end end end 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.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/markaby/builder.rb', line 172 def tag!(tag, *args, &block) ele_id = nil if @auto_validation && @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 if @tagset.forms.include?(tag) && attrs[:id] attrs[:name] ||= attrs[:id] end 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 @used_ids.has_key? ele_id raise InvalidXhtmlError, "id `#{ele_id}' already used (id's must be unique)." end end if AttrsBoolean.include? atname if v attrs[k] = atname.to_s else attrs.delete k end end end end end if block str = capture(&block) block = proc { text(str) } end f = fragment { @builder.tag!(tag, *args, &block) } @used_ids[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.
146 147 148 149 |
# File 'lib/markaby/builder.rb', line 146 def text(string) @builder << string.to_s nil end |
#to_s ⇒ Object
Returns a string containing the HTML stream. Internally, the stream is stored as an Array.
141 142 143 |
# File 'lib/markaby/builder.rb', line 141 def to_s @streams.last.to_s end |