Class: Aurita::GUI::HTML

Inherits:
Object
  • Object
show all
Defined in:
lib/aurita-gui/html.rb

Overview

About

Aurita::GUI is a library for convenient, simple HTML generation for web applications.

It is a stand-alone library isolated from the Aurita Web Application Framework, where Aurita::GUI is used to support design of OO-accessible GUI elements.

Other than other builder implementations (there are many), Aurita::GUI is not just a collection of template helpers. It is data persistent and maintains object hierarchies. That is: The HTML hierarchy you build is not just rendered to a string - you can access and modify a generated HTML hierarchy before rendering it.

This is especially useful (and necessary) when generating forms.

Aurita::GUI is designed to be especially useful for automated form generation (Lore ORM uses it to generate forms for models).

Of course there is also Aurita::GUI::Template_Helper for templates, but this is just one possible implementation that wraps common tasks in methods. You can easily write your own template helpers and use them e.g. in Rails, Merb or Ramaze projects.

Aurita::GUI::HTML is a convenient factory for Aurita::GUI::Element, the base class to almost every instance this library generates. HTML’s class methods are redirected to generate a correspoding Element instance.

It implements an object-oriented, minimalistic generator for HTML code. For tags without enclosed content (i.e. without closing tag):

HTML.br  
# --> '<br />'

HTML.hr(:class => 'divide')  
# --> '<hr class="divide" />'

This is effectively a wrapper for

Element.new(:tag => :hr, :class => 'divide')

Enclosed content is passed in a block:

HTML.a(:href => 'http://domain.com') { 'click me' }
# --> '<a href="http://domain.com">click me</a>'

Or as a constructor parameter:

HTML.a(:href => 'http://domain.com', :content => 'click me')

Further Examples

There are some few usage principles that are consistent for every class of Aurita::GUI. One of them: If a parameter can be passed as constructor argument, there are also getter and setter methods for this parameter:

d = HTML.div { 'the content' }
d.content = 'i changed the content'
d.onclick = "alert('you clicked me');"

The basics

This is the most convenient way to build HTML using aurita-gui. (Thanks to oGMo for demanding more magic)

t1 = HTML.build { 
  div(:class => :css_class, 
      :onmouseover => "do_something_with(this);") { 
    ul(:id => :the_list) { 
      li(:class => :first) { 'foo' } +
      li(:class => :second) { 'bar' } +
      li(:class => :third) { 'batz' }
    }
  }
}
puts t1.to_s

Note that all method calls are redirected to class HTML, so this won’t work as expected:

HTML.build { 
  div { 
    h2 { compute_string() } 
  } 
}.to_s

–> <div><h2><compute_string /></h2></div>

This is due to a class_eval restriction every builder struggles with at the moment. (There is mixico, but it is not portable).

To come by this inconvenience, use, for example:

HTML.build { 
  div { 
    HTML.h2 { compute_string() }
  }
}.to_s

–> <div><h2>computed string here</h2></div>

This works, as explicit calls to class methods of HTML are not rendered using class_eval.

The previous example effectively does the following:

t2 = HTML.div(:class => :css_class, 
              :onmouseover => "do_something_with(this);") { 
  HTML.ul(:id => :the_list) { 
      HTML.li(:class => :first) { 'foo' } +
      HTML.li(:class => :second) { 'bar' } + 
      HTML.li(:class => :third) { 'batz' }
  }
}
assert_equal(t1.to_s, t2.to_s)

Element is not a full Enumerable implementation (yet), but it offers random access operators …

assert_equal(t1[0].tag, :ul)  # First element of div is <ul>

t1[0][1] = HTML.li(:class => :changed) { 'wombat' }

… as well as #each …

t1[0].each { |element|
  element.id = 'each_change'
}

… empty? and length. More to come in future releases.

assert_equal(t1[0].length, 3) # List has 3 entries
assert_equal(t1[0].empty?, false) # List has 3 entries

Form builder

form = Form.new(:name   => :the_form, 
                :id     => :the_form_id, 
                :action => :where_to_send)

You can either set all attributes in the constructor call …

text = Input_Field.new(:name => :description, 
                       :class => :the_css_class, 
                       :onfocus => "alert('input focussed');", 
                       :value => 'some text')

Or set them afterwards:

text.onblur = "alert('i lost focus :(');"

Enable / disable:

text.disable! 
text.enable!

Set an element to readonly mode (display value only):

text.readonly!

And back to editable mode:

text.editable!

Add it to the form:

form.add(text)

Access it again, via name:

assert_equal(form[:description], text)

Or by using its index:

assert_equal(form[0], text)

This is useful!

form[:description].value = 'change value'

checkbox = Checkbox_Field.new(:name => :enable_me, 
                          :value => :foo, 
                          :label => 'Check me', 
                          :options => [ :foo, :bar ] )
form.add(checkbox)

puts form.to_s

Class Method Summary collapse

Class Method Details

.a(attrib_hash = {}, &block) ⇒ Object



234
235
236
# File 'lib/aurita-gui/html.rb', line 234

def self.a(attrib_hash={}, &block)
  render(:a, attrib_hash, &block)
end

.brObject

Statically defined as <br /> must not have any attributes.



216
217
218
# File 'lib/aurita-gui/html.rb', line 216

def self.br
  Element.new(:tag => :br)
end

.build(&block) ⇒ Object

Raises:

  • (::Exception)


228
229
230
231
# File 'lib/aurita-gui/html.rb', line 228

def self.build(&block)
  raise ::Exception.new('Missing block for HTML.render') unless block_given?
  self.class_eval(&block) 
end

.method_missing(meth_name, attrib_hash = {}, &block) ⇒ Object



245
246
247
# File 'lib/aurita-gui/html.rb', line 245

def self.method_missing(meth_name, attrib_hash={}, &block)
  render(meth_name, attrib_hash, &block) 
end

.p(attrib_hash = {}, &block) ⇒ Object

p is defined in Kernel, so we have to redirect it manually (method_missing won’t be triggered for it)



241
242
243
# File 'lib/aurita-gui/html.rb', line 241

def self.p(attrib_hash={}, &block)
  render(:p, attrib_hash, &block)
end

.render(meth_name, attrib_hash = {}, &block) ⇒ Object

Raises:

  • (::Exception)


220
221
222
223
224
225
226
# File 'lib/aurita-gui/html.rb', line 220

def self.render(meth_name, attrib_hash={}, &block)
  raise ::Exception.new('Missing attributes for HTML.' << meth_name.inspect) unless attrib_hash
  attrib_hash[:tag] = meth_name
  cont = yield if block_given?
  attrib_hash[:content] = cont
  Element.new(attrib_hash)
end