Class: Rote::Page
- Inherits:
-
Object
- Object
- Rote::Page
- Defined in:
- lib/rote/page.rb
Overview
A Page
object represents an individual template source file, taking input from that file and (optionally) some ruby code, and producing rendered (or ‘merged’) output as a String
. All user-supplied code (COMMON.rb or page code, for example) is executed in the binding of an instance of this class.
When a page is created, ruby source will be sought alongside the file, with same basename and an ‘.rb’ extension. If found it will run through instance_eval
. That source can call methods and set any instance variables, for use later in the template. Such variables or methods may also be defined in a COMMON.rb file in or above the page’s directory, in code associated with the layout
applied to a page, or (less often) in a block supplied to new
.
Rendering happens only once for a given page object, when the render
method is first called. Once a page has been rendered it is frozen.
Instance Attribute Summary collapse
-
#base_path ⇒ Object
readonly
The base paths for this page’s template and layout.
-
#layout_name ⇒ Object
readonly
The names from which this page’s template and layout (if any) were read, relative to the
base_path
. -
#layout_path ⇒ Object
readonly
The base paths for this page’s template and layout.
-
#layout_text ⇒ Object
readonly
The text of the layout to use for this page.
-
#page_filters ⇒ Object
readonly
The array of page filters (applied to this page output before layout is applied) and post filters (three gueses).
-
#post_filters ⇒ Object
readonly
The array of page filters (applied to this page output before layout is applied) and post filters (three gueses).
-
#template_name ⇒ Object
readonly
The names from which this page’s template and layout (if any) were read, relative to the
base_path
. -
#template_text ⇒ Object
readonly
The text of the template to use for this page.
Class Method Summary collapse
-
.page_ruby_filename(template_fn) ⇒ Object
Helper that returns a page-code filename given a template filename.
-
.resolve_common_rubys(dir, arr = []) ⇒ Object
Find all COMMON.rb files from given dir up to FS root.
Instance Method Summary collapse
-
#initialize(template_name, pages_dir = '.', layout_dir = pages_dir, &blk) ⇒ Page
constructor
Reads the template, and evaluates the global and page scripts, if available, using the current binding.
-
#layout(basename) ⇒ Object
Sets the layout from the specified file, or disables layout if
nil
is passed in. -
#layout_filename ⇒ Object
Returns the full filename of this Page’s template.
-
#page_filter(filter = nil, &block) ⇒ Object
Append
filter
to this page’s page-filter chain, or create a new Rote::Filters::TextFilter with the supplied block. -
#post_filter(filter = nil, &block) ⇒ Object
Append
filter
to this page’s post-filter chain. -
#render ⇒ Object
(also: #to_s)
Render this page’s textile and ERB, and apply layout.
-
#ruby_filename ⇒ Object
Returns the full filename of this Page’s ruby source.
-
#template_filename ⇒ Object
Returns the full filename of this Page’s template.
Constructor Details
#initialize(template_name, pages_dir = '.', layout_dir = pages_dir, &blk) ⇒ Page
Reads the template, and evaluates the global and page scripts, if available, using the current binding. You may define any instance variables or methods you like in that code for use in the template, as well as accessing the predefined @template and @template_text variables.
If specified, the layout path will be used to find layouts referenced from templates.
If a block is supplied, it is executed before the global / page code. This will be the block supplied by the file-extension mapping.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/rote/page.rb', line 100 def initialize(template_name, pages_dir = '.', layout_dir = pages_dir, &blk) @template_text = nil @template_name = nil @layout_text = nil @layout_name = nil @content_for_layout = nil @result = nil @layout_defext = File.extname(template_name) @layout_path = layout_dir[STRIP_SLASHES,1] @base_path = pages_dir[STRIP_SLASHES,1] @page_filters, @post_filters = [], [] # read in the template. Layout _may_ get configured later in page code # We only add the pages_dir if it's not already there, because it's # easier to pass the whole relative fn from rake... # template_name always needs with no prefix. tfn = template_name read_template(tfn) blk[self] if blk # Eval COMMON.rb's eval_common_rubys # get script filenames, and eval them if found tfn = ruby_filename # nil if no file instance_eval(File.read(tfn),tfn) if tfn end |
Instance Attribute Details
#base_path ⇒ Object (readonly)
The base paths for this page’s template and layout. These point to the directories configured in the Rake tasks.
80 81 82 |
# File 'lib/rote/page.rb', line 80 def base_path @base_path end |
#layout_name ⇒ Object (readonly)
The names from which this page’s template and layout (if any) were read, relative to the base_path
.
76 77 78 |
# File 'lib/rote/page.rb', line 76 def layout_name @layout_name end |
#layout_path ⇒ Object (readonly)
The base paths for this page’s template and layout. These point to the directories configured in the Rake tasks.
80 81 82 |
# File 'lib/rote/page.rb', line 80 def layout_path @layout_path end |
#layout_text ⇒ Object (readonly)
The text of the layout to use for this page. This is read in when (if) the page source calls layout(basename).
72 73 74 |
# File 'lib/rote/page.rb', line 72 def layout_text @layout_text end |
#page_filters ⇒ Object (readonly)
The array of page filters (applied to this page output before layout is applied) and post filters (three gueses). You can use append_page_filter
and append_post_filter
to add new filters, which gives implicit block => Filters::Proc conversion and checks for nil.
87 88 89 |
# File 'lib/rote/page.rb', line 87 def page_filters @page_filters end |
#post_filters ⇒ Object (readonly)
The array of page filters (applied to this page output before layout is applied) and post filters (three gueses). You can use append_page_filter
and append_post_filter
to add new filters, which gives implicit block => Filters::Proc conversion and checks for nil.
87 88 89 |
# File 'lib/rote/page.rb', line 87 def post_filters @post_filters end |
#template_name ⇒ Object (readonly)
The names from which this page’s template and layout (if any) were read, relative to the base_path
.
76 77 78 |
# File 'lib/rote/page.rb', line 76 def template_name @template_name end |
#template_text ⇒ Object (readonly)
The text of the template to use for this page.
68 69 70 |
# File 'lib/rote/page.rb', line 68 def template_text @template_text end |
Class Method Details
.page_ruby_filename(template_fn) ⇒ Object
Helper that returns a page-code filename given a template filename. This does not check that the source exists - use the ruby_filename
instance method to get the actual filename (if any) of source associated with a given page instance.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rote/page.rb', line 44 def page_ruby_filename(template_fn) fn = nil if (template_fn) if (fn = template_fn.dup) =~ FILE_EXT fn[FILE_EXT] = '.rb' else fn << '.rb' unless fn.empty? end end fn end |
.resolve_common_rubys(dir, arr = []) ⇒ Object
Find all COMMON.rb files from given dir up to FS root.
57 58 59 60 61 62 63 64 |
# File 'lib/rote/page.rb', line 57 def resolve_common_rubys(dir, arr = []) # defer to parent dir first parent = File.(File.join(dir, '..')) resolve_common_rubys(parent,arr) unless parent == dir # at root fn = File.join(dir,'COMMON.rb') arr << fn if (File.exists?(fn) && File.readable?(fn)) arr end |
Instance Method Details
#layout(basename) ⇒ Object
Sets the layout from the specified file, or disables layout if nil
is passed in. The specified basename should be the name of the layout file relative to the layout_dir
, with no extension.
The layout is not read by this method. It, and it’s source, are loaded only at rendering time. This prevents multiple calls by various scoped COMMON code, for example, from making a mess in the Page binding.
This can only be called before the first call to render
. After that the instance is frozen.
195 196 197 198 199 200 201 202 |
# File 'lib/rote/page.rb', line 195 def layout(basename) if basename # layout text @layout_name = "#{basename}#{@layout_defext if File.extname(basename).empty?}" else @layout_name = nil end end |
#layout_filename ⇒ Object
Returns the full filename of this Page’s template. This is obtained by joining the base path with template name.
138 139 140 |
# File 'lib/rote/page.rb', line 138 def layout_filename layout_name ? File.join(layout_path,layout_name) : nil end |
#page_filter(filter = nil, &block) ⇒ Object
Append filter
to this page’s page-filter chain, or create a new Rote::Filters::TextFilter with the supplied block. This method should be preferred over direct manipulation of the filters
array if you are simply building a chain.
153 154 155 156 157 158 159 160 161 |
# File 'lib/rote/page.rb', line 153 def page_filter(filter = nil, &block) if filter page_filters << filter else if block page_filters << Filters::Proc.new(block) end end end |
#post_filter(filter = nil, &block) ⇒ Object
Append filter
to this page’s post-filter chain. Behaviour is much the same as append_page_filter
.
165 166 167 168 169 170 171 172 173 |
# File 'lib/rote/page.rb', line 165 def post_filter(filter = nil, &block) if filter post_filters << filter else if block post_filters << Filters::Proc.new(block) end end end |
#render ⇒ Object Also known as: to_s
Render this page’s textile and ERB, and apply layout. This is only done once - after that, it’s cached for next time. You can also circumvent rendering by setting @result yourself in your page’s ruby.
178 179 180 |
# File 'lib/rote/page.rb', line 178 def render @result or do_render! # sets up result for next time... end |
#ruby_filename ⇒ Object
Returns the full filename of this Page’s ruby source. If no source is found for this page (not including common source) this returns nil
.
144 145 146 147 |
# File 'lib/rote/page.rb', line 144 def ruby_filename fn = Page::page_ruby_filename(template_filename) File.exists?(fn) ? fn : nil end |
#template_filename ⇒ Object
Returns the full filename of this Page’s template. This is obtained by joining the base path with template name.
132 133 134 |
# File 'lib/rote/page.rb', line 132 def template_filename template_name ? File.join(base_path,template_name) : nil end |