Skip to content
Browse files

Rdoc love

  • Loading branch information...
1 parent e4afa0b commit d8359fb632399b6127cb28c86e9f0cadebf0a643 Iain Hecker committed Nov 6, 2008
Showing with 84 additions and 24 deletions.
  1. +51 −23 lib/model_based_html/base.rb
  2. +8 −1 lib/model_based_html/definition_list.rb
  3. +25 −0 lib/model_based_html/table.rb
View
74 lib/model_based_html/base.rb
@@ -2,58 +2,71 @@ module ModelBasedHtml
class Base
- # References the default method, for overriding purposes
- def initialize(type, object, template, &block)
- default(type, object, template, &block)
- end
-
- # Sets all the defaults and stuff
- def default(type, object, template, options = {}, &block)
- object = object.to_s.camelize.constantize.new if object.is_a?(Symbol)
- @object = object
- @template = template
- options = { :object_html => @object }.merge(options)
- open_tag(start_tag(type, options))
- yield self
- close_tag("</#{type}>")
- end
-
- def start_tag(type, options = {})
- options = html_attrs(options) if options[:object_html]
- @template.content_tag(type, '', options).sub(/<\/#{type}>$/, '')
- end
-
- def h(string)
- @template.send(:h, string)
+ # The initialize method just passes everything to <tt>default</tt>.
+ # Please override in inherited classes for more complex logic.
+ def initialize(type, object, template, options = {}, &block)
+ default(type, object, template, options => {}, &block)
end
+ # Makes an html-tag with a value in it. If the value is a symbol it
+ # will send it to the object. If you specify a block, it will yield
+ # with the value of the attribute specified.
def value_tag(tag, method_or_value, options, &block)
open_tag(start_tag(tag, attributes(method_or_value, options)))
concat_or_yield(value(method_or_value), "</#{tag}>", &block)
end
+ # Same as <tt>value_tag</tt>, but escapes method_or_value.
def value_tag_h(tag, method_or_value, options, &block)
open_tag(start_tag(tag, attributes(method_or_value, options)))
concat_or_yield(h(value(method_or_value)), "</#{tag}>", &block)
end
+ # Similar to value_tag, this will render a tag, but instead of
+ # getting the value of the attribute specified it will try to
+ # get the human_attribute_name, if a Symbol is specified. Pass a
+ # block to modify the resulting value.
def name_tag(tag, method_or_value, options, &block)
open_tag(start_tag(tag, attributes(method_or_value, options)))
concat_or_yield(name(method_or_value), "</#{tag}>", &block)
end
private
+ # Sets all the defaults and stuff. Pass :object_html to an object or
+ # collection for automatic class and id.
+ def default(type, object, template, options = {}, &block)
+ object = object.to_s.camelize.constantize.new if object.is_a?(Symbol)
+ @object = object
+ @template = template
+ options = { :object_html => @object }.merge(options)
+ open_tag(start_tag(type, options))
+ yield self
+ close_tag("</#{type}>")
+ end
+
+
+ # Returns a normal start_tag.
+ def start_tag(type, options = {})
+ options = html_attrs(options) if options[:object_html]
+ @template.content_tag(type, '', options).sub(/<\/#{type}>$/, '')
+ end
+
+ # Returns a class and id for the object specified.
+ # Similar to haml: %tag[object]
def html_attrs_for_object(object)
id = object_name(object)
id = object.new_record? ? "new_#{id}" : "#{id}_#{object.id}"
{ :class => object_name(object), :id => id }
end
+ # Returns a class for a collection. Actually just the class name pluralized.
def html_attrs_for_collection(collection)
{ :class => object_name(collection.first).pluralize }
end
+ # Switches approriately based on a collection or single object
+ # to return html attributes.
def html_attrs(options = {})
object = options.delete(:object_html) or @object
if object.is_a?(Array)
@@ -65,14 +78,19 @@ def html_attrs(options = {})
object_options.merge(options)
end
+ # A lowercased and underscored version of the current object
def object_name(object = @object)
@object_name ||= object.class.to_s.underscore.gsub('/','_')
end
+ # Provides a class name for html tags coupled to an attribute.
+ # This will make it possible to use css per attribute.
def attributes(method, options = {})
(method.is_a?(Symbol) ? { :class => method.to_s } : {}).merge(options)
end
+ # Switcher for name and value tags. The first argument gets passed
+ # to the block, the others will be concatted after that.
def concat_or_yield(*args, &block)
str = args.shift
if block_given?
@@ -83,11 +101,13 @@ def concat_or_yield(*args, &block)
close_tag(args.join) unless args.empty?
end
+ # Performs the actual check on the object to get the value of an attribute.
def value(method_or_value)
return method_or_value unless method_or_value.is_a?(Symbol)
@object.send(method_or_value)
end
+ # Performs the actual check on the object to get the human_attribute_name.
def name(method_or_value)
return method_or_value unless method_or_value.is_a?(Symbol)
@object.class.human_attribute_name(method_or_value.to_s)
@@ -105,18 +125,26 @@ def concat(*args)
""
end
+ # Use this to open a tag to get some sort of failing indentation...
def open_tag(*args)
@tags_opened ||= 0
concat(*args)
@tags_opened += 1
end
+ # Use this to close a tag to get some sort of failing indentation...
def close_tag(*args)
@tags_opened ||= 1
@tags_opened = (@tags_opened - 1).abs
concat(*args)
end
+ # escapes html shortcut
+ def h(string)
+ @template.send(:h, string)
+ end
+
+
end
end
View
9 lib/model_based_html/definition_list.rb
@@ -2,24 +2,31 @@ module ModelBasedHtml
class DefinitionList < ModelBasedHtml::Base
+ # Renders a dt-element. Specify a block to alter it's contents.
+ # When method_or_value is a symbol, it will look up human_attribute_name.
def dt(method_or_value = nil, options = {}, &block)
name_tag(:dt, method_or_value, options, &block)
end
+ # Renders a dd-element. Specify a block to alter it's contents.
+ # When method_or_value is a symbol, it will look up the value of the object.
def dd(method_or_value = nil, options = {}, &block)
value_tag(:dd, method_or_value, options, &block)
end
+ # Same as dd, but escapes the html in method_or_value.
def dd_h(method_or_value = nil, options = {}, &block)
value_tag_h(:dd, method_or_value, options, &block)
end
+ # Perform both dt and dd, the block applies to dd.
def dt_and_dd(method_or_value = nil, options = {}, &block)
dt(method_or_value, options)
dd(method_or_value, options, &block)
end
- def dt_and_dd_h
+ # Same as dt_and_dd, but escapes the html in method_or_value.
+ def dt_and_dd_h(method_or_value = nil, options = {}, &block)
dt(method_or_value, options)
dd_h(method_or_value, options, &block)
end
View
25 lib/model_based_html/table.rb
@@ -19,6 +19,8 @@ def initialize(type, collection, template, options = {}, &block)
default(:table, object, template, { :object_html => collection }, &block)
end
+ # Renders a thead. You need this to register th's for automatic
+ # rendering using <tt>body</tt> without a block.
def head(options = {}, &block)
return "" if @collection.empty? and not @force
reset_cell_count
@@ -31,6 +33,9 @@ def head(options = {}, &block)
close_tag("</thead>")
end
+ # Loops your collection inside a tbody tag. If you don't specify a block
+ # it will try to render a tbody-element based on the columns specified in
+ # the thead.
def body(options = {}, &block)
when_not_empty do
reset_cell_count
@@ -58,23 +63,31 @@ def body(options = {}, &block)
end
end
+ # Renders a td. When method or value is a symbol, it will try
+ # to get the value from the object, if you're currently in a
+ # <tt>body</tt>
def td(method_or_value = nil, options = {}, &block)
count_cell
value_tag(:td, method_or_value, options, &block)
end
+ # Renders a td while escaping method_or_value.
def td_h(method_or_value = nil, options = {}, &block)
count_cell
value_tag_h(:td, method_or_value, options, &block)
end
+ # Render a th as a name_tag, so it calls human_attribute_name if
+ # a symbol has been specified. You will need to do this for <tt>head</tt>
+ # to render automatically.
def th(method_or_value = nil, options = {}, &block)
count_cell
@columns ||= []
@columns << method_or_value if @inside_head
name_tag(:th, method_or_value, options, &block)
end
+ # Render a tr-block. Specify :object_html to bind it to an object.
def tr(options = {}, &block)
reset_cell_count
options = {:object_html => @object}.merge(options)
@@ -84,10 +97,20 @@ def tr(options = {}, &block)
close_tag("</tr>")
end
+ # Returns odd or even
def odd_or_even
@template.cycle("odd", "even", :name => "table_#{self.object_id}")
end
+ # Resets the odd or even cycle
+ def reset_odd_or_even
+ @template.reset_cycle("table_#{self.object_id}")
+ end
+
+ # Yields or displays a message when the collection is not empty.
+ # When no message has been specified, it'll try to translate a message.
+ # If a forcing class has been specified in table_for, it will automatically
+ # render a td with a colspan to cover the entire row.
def when_empty(message = nil, &block)
if @collection.empty?
if @force
@@ -102,10 +125,12 @@ def when_empty(message = nil, &block)
end
end
+ # Yields only when the collection specified is not empty.
def when_not_empty(&block)
yield unless @collection.empty?
end
+ # Returns the maximum amount of cells used in one row.
def width
@table_width
end

0 comments on commit d8359fb

Please sign in to comment.
Something went wrong with that request. Please try again.