A programmatically generated element. Elements are a form of macros to allow for cleaner templates. They are evaluated at compile time, so there is no performance hit when you use them (at the expense of slightly reduced functionality).
Nitro provides an additional method of defining elements. Instead of creating a lot of small classes, you can put .htmlx templates in the Element template_root. These templates are automatically converted into Element classes.
For extra safety, you are advised to place your classes in the Nitro::Element namespace. If your classes do not extend Nitro::Element, the Nitro::ElementMixin is automatically injected in the class.
An element can have and access a hierarchy of sub-elements. use #{content :sub_element_name} to access the render output of the subelement. Additionaly you can access the whole subelement object: _children[:sub_element_name]
Design
An underscore is used for the standard attibutes to avoid name clashes.
| [RW] | _children | The children of this element. |
| [RW] | _parent | The parent of this element. |
| [RW] | _text | The text of this element. |
| [RW] | _view | The view of this element. |
| [RW] | id | The id of this element. |
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 57
57: def initialize(*args)
58: @_children = {}
59: @_text = ''
60: @id = self.class.to_s.demodulize.underscore
61: end
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 153
153: def add_child(child)
154: child._parent = self
155: @_children[child.instance_variable_get('@id')] = child
156: end
Append this code to the element content.
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 135
135: def close
136: end
If an optional name parameter is passed renders the content of the named child element.
eg. #{content :child_element_id}
Example
<Page>
..
<Box id="hello">
..
</Box>
<Box id="world">
..
</Box>
<Sidebar>
..
</Sidebar>
..
</Page>
Access children content from within the enclosing element (Page) like this:
{content :hello} {content :world} {content :sidebar}
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 101
101: def content(cname = nil)
102: if cname
103: if c = @_children[cname.to_s]
104: c.content
105: else
106: return nil
107: end
108: else
109: @_text
110: end
111: end
Include a text file in the element template. All the conventions of the StaticInclude compiler apply here. Please not that unless you pass an absolute path (starting with ’/’) you have to pass a controller instance as well.
Example:
def render
%~
<div>
#{include '/links/latest'}
</div>
~
end
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 128
128: def include(href, controller = nil)
129: filename = StaticIncludeFilter.new.resolve_include_filename(href)
130: return File.read(filename)
131: end
Prepend this code to the element content.
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 65
65: def open
66: end
Override this.
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 140
140: def render
141: "#{open}#{content}#{close}"
142: end
[ show source ]
# File lib/raw/compiler/filter/elements/element.rb, line 144
144: def render_children
145: str = ''
146: for c in @_children.values
147: str << c.render
148: end
149:
150: return str
151: end