Class: Erector::Widgets::Page
- Inherits:
-
InlineWidget
- Object
- AbstractWidget
- XMLWidget
- HTMLWidget
- Erector::Widget
- InlineWidget
- Erector::Widgets::Page
- Defined in:
- lib/erector/widgets/page.rb
Overview
Erector Page base class.
Allows for accumulation of script and style tags (see example below) with either external or inline content. External references are ‘uniq’d, so it’s a good idea to declare a js script in all widgets that use it, so you don’t accidentally lose the script if you remove the one widget that happened to declare it.
The script and style declarations are accumulated at class load time, as ‘dependencies’. This technique allows all widgets to add their own requirements to the page header without extra logic for declaring which pages include which nested widgets. Fortunately, Page is now smart enough to figure out which widgets were actually rendered during the body_content run, so it only emits into its HEAD the dependencies that are relevant. If it misses some, or if you want to add some extra dependencies – for instance, styles that apply to widgets that are rendered later via AJAX – then return an array of those widget classes in your subclass by overriding the #extra_widgets method.
If you want something to show up in the headers for just one page type (subclass), then override #head_content, call super, and then emit it yourself.
Body content can be supplied in several ways:
* In a Page subclass, by overriding the #body_content method:
class MyPage < Erector::Widgets::Page
def body_content
text "body content"
end
end
* Or by overriding #content and passing a block to super:
class MyPage < Erector::Widgets::Page
def content
super do
text "body content"
end
end
end
* Or by passing a block to Page.new:
Erector::Widgets::Page.new do
text "body content"
end
This last trick (passing a block to Page.new) works because Page is an InlineWidget so its block is evaluated in the context of the newly instantiated widget object, and not in the context of its caller. But this means you can’t access instance variables of the caller, e.g.
@name = "fred"
Erector::Widgets::Page.new do
text "my name is #{@name}"
end
will emit “my name is ” because @name is nil inside the new Page. However, you can call methods in the parent class, thanks to some method_missing magic. Confused? You should be. See Erector::Inline#content for more documentation.
- Author
-
Alex Chaffee, [email protected]
Example Usage:
class MyPage < Page
external :js, "lib/jquery.js"
external :script, "$(document).ready(function(){...});"
external :css, "stuff.css"
external :style, "li.foo { color: red; }"
def page_title
"my app"
end
def body_content
h1 "My App"
p "welcome to my app"
WidgetWithExternalStyle
end
end
class WidgetWithExternalStyle < Erector::Widget
external :style, "div.custom { border: 2px solid green; }"
def content
div :class => "custom" do
text "green is good"
end
end
end
Thoughts:
* It may be desirable to unify #js and #script, and #css and #style, and
have the routine be smart enough to analyze its parameter to decide
whether to make it a file or a script.
Instance Method Summary collapse
-
#body_attributes ⇒ Object
override me to add attributes (e.g. a css class) to the body.
-
#body_content ⇒ Object
override me (or instantiate Page with a block).
- #content ⇒ Object
-
#doctype ⇒ Object
Emit the Transitional doctype.
- #extra_widgets ⇒ Object
-
#head_content ⇒ Object
emit the contents of the head element.
-
#html_attributes ⇒ Object
override me to change the attributes of the HTML element.
- #included_head_content ⇒ Object
-
#page_title ⇒ Object
override me to provide a page title (default = name of the Page subclass).
Methods included from Inline
Methods inherited from Erector::Widget
Methods included from Sass
Methods included from JQuery
#jquery, #jquery_load, #jquery_ready
Methods included from Convenience
#css, #dom_id, #javascript, #join, #to_pretty, #to_text, #url
Methods included from Externals
included, #render_externals, #render_with_externals
Methods included from Caching
#cache, included, #should_cache?
Methods included from Needs
Methods inherited from HTMLWidget
Methods inherited from XMLWidget
#comment, full_tags, #instruct, #newliney?, self_closing_tags, tag, tag_named
Methods inherited from AbstractWidget
#call_block, #capture_content, #emit, hyphenize_underscores, hyphenize_underscores=, #initialize, inline, prettyprint_default, #prettyprint_default, prettyprint_default=, #to_a, #to_s, #widget
Methods included from AfterInitialize
Methods included from Text
#character, #h, #nbsp, #raw, #text, #text!
Methods included from Attributes
#format_attributes, #format_sorted, #sort_attributes
Methods included from Element
#_element, #_empty_element, #element, #empty_element
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Erector::Inline
Instance Method Details
#body_attributes ⇒ Object
override me to add attributes (e.g. a css class) to the body
142 143 144 |
# File 'lib/erector/widgets/page.rb', line 142 def body_attributes {} end |
#body_content ⇒ Object
override me (or instantiate Page with a block)
147 148 149 |
# File 'lib/erector/widgets/page.rb', line 147 def body_content call_block end |
#content ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/erector/widgets/page.rb', line 110 def content extra_head_slot = nil rawtext doctype html(html_attributes) do head do head_content extra_head_slot = output.placeholder end body(body_attributes) do if block_given? yield else body_content end end end # after everything's been rendered, use the placeholder to # insert all the head's dependencies extra_head_slot << included_head_content end |
#doctype ⇒ Object
Emit the Transitional doctype. TODO: allow selection from among different standard doctypes
105 106 107 108 |
# File 'lib/erector/widgets/page.rb', line 105 def doctype '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' end |
#extra_widgets ⇒ Object
164 165 166 |
# File 'lib/erector/widgets/page.rb', line 164 def [] end |
#head_content ⇒ Object
emit the contents of the head element. Override and call super if you want to put more stuff in there.
152 153 154 155 |
# File 'lib/erector/widgets/page.rb', line 152 def head_content 'http-equiv' => 'content-type', :content => 'text/html;charset=UTF-8' title page_title end |
#html_attributes ⇒ Object
override me to change the attributes of the HTML element
137 138 139 |
# File 'lib/erector/widgets/page.rb', line 137 def html_attributes {:xmlns => 'http://www.w3.org/1999/xhtml', 'xml:lang' => 'en', :lang => 'en'} end |
#included_head_content ⇒ Object
157 158 159 160 161 162 |
# File 'lib/erector/widgets/page.rb', line 157 def included_head_content # now that we've rendered the whole page, it's the right time # to ask what all widgets were rendered to the output stream = [self.class] + output..to_a + ExternalRenderer.new(:classes => ).to_html end |
#page_title ⇒ Object
override me to provide a page title (default = name of the Page subclass)
132 133 134 |
# File 'lib/erector/widgets/page.rb', line 132 def page_title self.class.name end |