masterview 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +31 -1
- data/README +70 -69
- data/RELEASE_NOTES +70 -64
- data/Rakefile +26 -27
- data/TODO +13 -29
- data/doc/about.html +246 -0
- data/doc/configuration.html +49 -36
- data/doc/developer.html +423 -41
- data/doc/directives.html +139 -51
- data/doc/guide.html +19 -9
- data/doc/index.html +90 -224
- data/doc/installation.html +36 -28
- data/doc/media_list.html +30 -20
- data/doc/simple_diagram.html +3 -5
- data/doc/stylesheets/masterview.css +16 -1
- data/examples/rails_app_config/masterview/settings.rb +2 -1
- data/init.rb +1 -1
- data/lib/#ChangeLog# +6 -0
- data/lib/masterview/analyzer.rb +48 -34
- data/lib/masterview/attr_string_parser.rb +5 -1
- data/lib/masterview/case_insensitive_hash.rb +69 -0
- data/lib/masterview/{pathname_extensions.rb → core_ext/pathname.rb} +0 -0
- data/lib/masterview/{string_extensions.rb → core_ext/string.rb} +0 -0
- data/lib/masterview/deprecated/directive_base.rb +362 -0
- data/lib/masterview/directive_base.rb +201 -179
- data/lib/masterview/directive_dsl.rb +457 -0
- data/lib/masterview/directive_helpers.rb +28 -141
- data/lib/masterview/directive_load_path.rb +388 -0
- data/lib/masterview/directive_metadata.rb +377 -0
- data/lib/masterview/directive_registry.rb +259 -69
- data/lib/masterview/directives/.metadata +16 -0
- data/lib/masterview/directives/attr.rb +9 -8
- data/lib/masterview/directives/block.rb +11 -14
- data/lib/masterview/directives/check_box.rb +13 -18
- data/lib/masterview/directives/collection_select.rb +15 -29
- data/lib/masterview/directives/content.rb +9 -3
- data/lib/masterview/directives/else.rb +15 -13
- data/lib/masterview/directives/elsif.rb +14 -13
- data/lib/masterview/directives/eval.rb +20 -0
- data/lib/masterview/directives/form.rb +56 -9
- data/lib/masterview/directives/form_remote.rb +26 -0
- data/lib/masterview/directives/global_inline_erb.rb +10 -14
- data/lib/masterview/directives/hidden_field.rb +11 -20
- data/lib/masterview/directives/if.rb +13 -12
- data/lib/masterview/directives/image_tag.rb +20 -28
- data/lib/masterview/directives/import.rb +5 -12
- data/lib/masterview/directives/import_render.rb +7 -19
- data/lib/masterview/directives/insert_generated_comment.rb +8 -11
- data/lib/masterview/directives/javascript_include.rb +21 -12
- data/lib/masterview/directives/link_to.rb +14 -8
- data/lib/masterview/directives/link_to_function.rb +22 -0
- data/lib/masterview/directives/link_to_if.rb +15 -13
- data/lib/masterview/directives/link_to_remote.rb +13 -8
- data/lib/masterview/directives/omit_tag.rb +32 -16
- data/lib/masterview/directives/password_field.rb +10 -22
- data/lib/masterview/directives/radio_button.rb +11 -22
- data/lib/masterview/directives/replace.rb +7 -8
- data/lib/masterview/directives/select.rb +11 -24
- data/lib/masterview/directives/stylesheet_link.rb +20 -12
- data/lib/masterview/directives/submit.rb +11 -5
- data/lib/masterview/directives/text_area.rb +10 -23
- data/lib/masterview/directives/text_field.rb +10 -22
- data/lib/masterview/exceptions.rb +21 -0
- data/lib/masterview/extras/app/controllers/masterview_controller.rb +102 -75
- data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +24 -23
- data/lib/masterview/extras/app/views/layouts/masterview_admin_config.rhtml +81 -0
- data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +5 -1
- data/lib/masterview/extras/app/views/masterview/admin/create.rhtml +2 -2
- data/lib/masterview/extras/app/views/masterview/admin/directives.rhtml +5 -0
- data/lib/masterview/extras/app/views/masterview/admin/features.rhtml +5 -79
- data/lib/masterview/extras/app/views/masterview/admin/interact.rhtml +5 -0
- data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +3 -71
- data/lib/masterview/extras/init_mv_admin_pages.rb +42 -23
- data/lib/masterview/filter_helpers.rb +26 -0
- data/lib/masterview/initializer.rb +99 -53
- data/lib/masterview/io.rb +19 -15
- data/lib/masterview/keyword_expander.rb +7 -2
- data/lib/masterview/masterview_info.rb +229 -23
- data/lib/masterview/masterview_version.rb +2 -2
- data/lib/masterview/parser.rb +275 -105
- data/lib/masterview/parser_helpers.rb +54 -0
- data/lib/masterview/rails_ext/action_controller_erb_direct.rb +29 -0
- data/lib/masterview/rails_ext/action_controller_reparse_checking.rb +27 -0
- data/lib/masterview/{extras/init_rails_erb_mv_direct.rb → rails_ext/action_view_erb_direct.rb} +12 -59
- data/lib/masterview/template_spec.rb +3 -2
- data/lib/masterview.rb +21 -12
- data/lib/rexml/parsers/baseparser_with_doctype_fix.rb +473 -0
- data/lib/rexml/parsers/sax2parser_with_doctype_fix.rb +243 -0
- data/test/directive_test_helper.rb +135 -0
- data/test/fixtures/directives/id_check.rb +18 -0
- data/test/fixtures/directives/test_directive_events.rb +70 -0
- data/test/test_helper.rb +18 -5
- data/test/tmp/views/layouts/product.rhtml +10 -10
- data/test/tmp/views/product/_form.rhtml +4 -4
- data/test/tmp/views/product/_product.rhtml +3 -3
- data/test/tmp/views/product/destroy.rhtml +5 -5
- data/test/tmp/views/product/edit.rhtml +4 -4
- data/test/tmp/views/product/list.rhtml +3 -3
- data/test/tmp/views/product/new.rhtml +4 -4
- data/test/tmp/views/product/show.rhtml +2 -2
- data/test/unit/attr_string_parser_test.rb +105 -0
- data/test/unit/case_insensitive_hash_mod_test.rb +104 -0
- data/test/unit/config_settings_test.rb +13 -1
- data/test/unit/default_generate_mio_filter_test.rb +3 -3
- data/test/unit/deprecated_directive_base_test.rb +30 -0
- data/test/unit/directive_attr_test.rb +111 -35
- data/test/unit/directive_base_test.rb +520 -1
- data/test/unit/directive_block_test.rb +30 -22
- data/test/unit/directive_content_test.rb +24 -11
- data/test/unit/directive_else_test.rb +18 -15
- data/test/unit/directive_elsif_test.rb +17 -15
- data/test/unit/directive_form_remote_test.rb +59 -0
- data/test/unit/directive_form_test.rb +31 -39
- data/test/unit/directive_global_inline_erb_test.rb +28 -17
- data/test/unit/directive_grid_test_notready.rb +38 -0
- data/test/unit/directive_helpers_test.rb +39 -0
- data/test/unit/directive_hidden_field_test.rb +44 -29
- data/test/unit/directive_if_test.rb +10 -7
- data/test/unit/directive_image_tag_test.rb +69 -61
- data/test/unit/directive_import_render_test.rb +28 -38
- data/test/unit/directive_import_test.rb +16 -14
- data/test/unit/directive_insert_generated_comment_test.rb +32 -0
- data/test/unit/directive_javascript_include_test.rb +40 -43
- data/test/unit/directive_link_to_function_test.rb +40 -0
- data/test/unit/directive_link_to_if_test.rb +52 -12
- data/test/unit/directive_link_to_remote_test.rb +58 -0
- data/test/unit/directive_link_to_test.rb +46 -31
- data/test/unit/directive_load_path_test.rb +257 -0
- data/test/unit/directive_metadata_test.rb +313 -0
- data/test/unit/directive_omit_tag_test.rb +73 -21
- data/test/unit/directive_password_field_test.rb +44 -38
- data/test/unit/directive_registry_test.rb +44 -0
- data/test/unit/directive_replace_test.rb +28 -12
- data/test/unit/directive_stylesheet_link_test.rb +43 -36
- data/test/unit/directive_submit_test.rb +29 -30
- data/test/unit/directive_text_area_test.rb +40 -36
- data/test/unit/directive_text_field_test.rb +44 -38
- data/test/unit/example_directive_child_events_test.rb +41 -0
- data/test/unit/example_test.rb +31 -4
- data/test/unit/file_mio_test.rb +18 -13
- data/test/unit/filter_helpers_test.rb +10 -8
- data/test/unit/find_directive_parent_test.rb +174 -0
- data/test/unit/keyword_expander_test.rb +4 -2
- data/test/unit/mio_test.rb +18 -11
- data/test/unit/mtime_string_hash_mio_tree_test.rb +5 -1
- data/test/unit/parser_test.rb +41 -29
- data/test/unit/pathname_extensions_test.rb +1 -1
- data/test/unit/run_parser_test.rb +2 -2
- data/test/unit/simplified_directive_base_test.rb +256 -0
- data/test/unit/string_hash_mio_test.rb +5 -1
- data/test/unit/template_file_watcher_test.rb +2 -2
- data/test/unit/template_test.rb +221 -46
- metadata +86 -45
- data/lib/masterview/directives/testfilter.rb +0 -55
- data/lib/masterview/extras/init_rails_reparse_checking.rb +0 -62
data/doc/developer.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
-
<!DOCTYPE html
|
2
|
+
<!DOCTYPE html
|
3
3
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
4
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
-
|
5
|
+
|
6
6
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
7
|
<head>
|
8
8
|
|
@@ -11,6 +11,16 @@
|
|
11
11
|
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
12
12
|
|
13
13
|
<link href="./stylesheets/masterview.css" rel="stylesheet" type="text/css" />
|
14
|
+
<style type="text/css">
|
15
|
+
table.eventDescription {
|
16
|
+
margin-left: 20px;
|
17
|
+
margin-right: 20px;
|
18
|
+
}
|
19
|
+
table.eventDescription th, table.eventDescription td {
|
20
|
+
text-align: left;
|
21
|
+
padding-right: 8px;
|
22
|
+
}
|
23
|
+
</style>
|
14
24
|
</head>
|
15
25
|
|
16
26
|
<body>
|
@@ -24,6 +34,8 @@
|
|
24
34
|
·
|
25
35
|
<a href="./index.html">Doc Home</a>
|
26
36
|
|
|
37
|
+
<a href="./about.html">About</a>
|
38
|
+
|
|
27
39
|
<a href="./installation.html">Installation</a>
|
28
40
|
|
|
29
41
|
<a href="./configuration.html">Configuration</a>
|
@@ -32,7 +44,9 @@
|
|
32
44
|
|
|
33
45
|
<a href="./directives.html">Directives</a>
|
34
46
|
|
|
35
|
-
<a href="./
|
47
|
+
<a href="./developer.html">Developers</a>
|
48
|
+
|
|
49
|
+
<a href="./media_list.html">Screencasts</a>
|
36
50
|
·
|
37
51
|
</div>
|
38
52
|
</div>
|
@@ -49,7 +63,7 @@ It is also designed to be easily extensible by adding custom directives, as desc
|
|
49
63
|
|
50
64
|
<p>
|
51
65
|
Before undertaking implementation of your own custom directive, we recommend that
|
52
|
-
you review the <a href="#processing_overview">Overview of Template Processing and Directives</a> section, which
|
66
|
+
you review the <a href="#processing_overview">Overview of Template Processing and Directives</a> section, which discusses the processing context within which a directive implementation executes.
|
53
67
|
Then read the <a href="#directive_framework">Directive Implementation Framework</a>
|
54
68
|
for a guide to the facilities provided by MasterView to
|
55
69
|
simplify the development effort required to implement a new directive.
|
@@ -58,7 +72,7 @@ simplify the development effort required to implement a new directive.
|
|
58
72
|
<a name="processing_overview"></a>
|
59
73
|
<h2>Overview of Template Processing and Directives</h2>
|
60
74
|
|
61
|
-
<p>A MasterView template is an <a href="http://www.w3.org/TR/xhtml1/" target="_blank">XHTML</a> document
|
75
|
+
<p>A MasterView template is an <a href="http://www.w3.org/TR/xhtml1/" target="_blank">XHTML</a> document
|
62
76
|
which uses attribute markup on the standard document elements to encode processing directives for the template engine.
|
63
77
|
The <a href="http://www.w3.org/TR/REC-xml-names/" target="_blank">XML namespace</a> facility is used to identify attributes containing processing instructions.
|
64
78
|
</p>
|
@@ -72,12 +86,14 @@ the <span class="directiveName">mv:</span> namespace name using the
|
|
72
86
|
<code>namespace_prefix</code> configuration setting.)
|
73
87
|
</p>
|
74
88
|
|
75
|
-
<
|
76
|
-
|
89
|
+
<div class="todo">
|
90
|
+
Note: an XML schema definition of the builtin MasterView directives namespace
|
91
|
+
should be published on the <code>masterview.org</code> site.
|
92
|
+
This would enable a proper declaration of the MasterView attribute namespace
|
77
93
|
on your <code><html></code> elements of the form
|
78
94
|
<code>xmlns:mv='http://masterview.org/schema/2006/directives'</code>
|
79
95
|
(specific URI tba when published), which is useful as a documentary aide as well as to enable validation.
|
80
|
-
</
|
96
|
+
</div>
|
81
97
|
|
82
98
|
<p>In addition to the builtin MasterView directives, custom directives can be
|
83
99
|
used by appending one or more directories containing directive implementation classes
|
@@ -88,12 +104,17 @@ the fully qualified name of the directive attribute (namespace + simple attribut
|
|
88
104
|
and the directive implementation class which is instantiated to process a directive attribute.
|
89
105
|
</p>
|
90
106
|
|
91
|
-
<
|
107
|
+
<div class="todo">
|
108
|
+
TODO: include recommendation on namespace usage for custom directives.
|
109
|
+
Believe we should use <span class="directiveName">mvx:</span> namespace
|
110
|
+
as the default for extension directives, to distinguish from the builtin directives namespace.
|
111
|
+
</div>
|
92
112
|
|
93
113
|
<h3>Template Document Processing</h3>
|
94
114
|
|
95
115
|
<p>When MasterView processes a template document, the document is processed
|
96
|
-
as a
|
116
|
+
as a
|
117
|
+
<a href="http://xml.coverpages.org/dom.html" target="_blank">DOM</a> node hierarchy of elements and attributes.
|
97
118
|
Template processing is essentially a tree transformation process: the elements and their attributes from the template source document are processed and emitted onto the output.
|
98
119
|
</p>
|
99
120
|
|
@@ -101,61 +122,416 @@ Template processing is essentially a tree transformation process: the elements a
|
|
101
122
|
in the output. The addition of MasterView directive attributes to an element allows for transformation and substitution to occur between the template source and the generated output.
|
102
123
|
</p>
|
103
124
|
|
125
|
+
<p>It can be useful to think of directives as providing several typical flavors of processing:</p>
|
126
|
+
<dl>
|
127
|
+
<dt>attribute modifiers</dt>
|
128
|
+
<dd>the directive operates on the attributes of the element (adds or removes attributes or changes values of existing attributes)</dd>
|
129
|
+
<dt>content modifiers</dt>
|
130
|
+
<dd>the directive operates on the content of the element (modifies or replaces the content of the element)</dd>
|
131
|
+
<dt>eval-only</dt>
|
132
|
+
<dd>the directive is evaluated such that it has some effect on the overall state of the document processing, but does not directly affect the attributes or content of its element in the output</dd>
|
133
|
+
</dl>
|
134
|
+
|
135
|
+
<p>Some directives provide combinations of these processing flavors.
|
136
|
+
<!--??, e.g., a simple directive may simply modify the value of a standard attribute on the element (e.g., <span class="directiveName">mv:attr</span>), while a more complex directive may generate ... blah blah... ??-->
|
137
|
+
</p>
|
138
|
+
|
139
|
+
<h3>Template Directive Processing</h3>
|
140
|
+
|
104
141
|
<p>
|
105
|
-
As each element in the document is processed, any attributes
|
106
|
-
directives are collected and sorted into processing order
|
107
|
-
<code>priority</code> order defined for each directive.
|
142
|
+
As each element in the source document is processed, any attributes in the element start tag
|
143
|
+
which are MasterView directives are collected and sorted into processing order
|
144
|
+
according to the <code>priority</code> order defined for each directive.
|
108
145
|
The <code>MasterView::DirectivePriorities</code> range from
|
109
146
|
<code>Lowest</code> to <code>Highest</code>, with
|
110
147
|
<code>DirectivePriorities::Medium</code> the default.
|
111
|
-
In most cases, you do not need to be concerned with priority
|
112
|
-
|
148
|
+
In most cases, you do not need to be concerned with priority - the default priority order
|
149
|
+
is acceptable for most directives.
|
113
150
|
</p>
|
114
151
|
|
115
152
|
<p>For each MasterView directive attribute on a document element,
|
116
153
|
the template engine creates an instance of the directive's implementation class to provide the directive processing for that element.
|
117
|
-
The directive handler is provided with
|
154
|
+
The directive handler is provided with its attribute value from the document element when it is constructed so that it has access to any parameters provided to control its operation.
|
118
155
|
</p>
|
119
156
|
|
120
|
-
<
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
<dt>content modifiers</dt>
|
127
|
-
<dd>the directive operates on the content of the element (modifies or replaces the content of the element)</dd>
|
128
|
-
<dt>eval-only</dt>
|
129
|
-
<dd>the directive is evaluated such that it has some effect on the overall state of the document processing, but does not directly affect the attributes or content of its element in the output</dd>
|
130
|
-
</dl>
|
157
|
+
<div class="todo">TODO: add note about "global directives" that can be activated
|
158
|
+
on all elements in the document or on selected elements,
|
159
|
+
e.g., all elements of a specific type (all <img> elements, all <table> elements...).
|
160
|
+
This may be something that we want to control on a per-document basis,
|
161
|
+
so we're considering the need for a masterview directive which would configure doc-specific options
|
162
|
+
</div>
|
131
163
|
|
132
|
-
<p>
|
133
|
-
|
164
|
+
<p>
|
165
|
+
A directive handler can be invoked to perform its processing at several points during the processing of the document element on which it is defined:
|
134
166
|
</p>
|
167
|
+
<ul>
|
168
|
+
<li>during the start tag processing for the element</li>
|
169
|
+
<li>when the complete content of the document element is available from the source</li>
|
170
|
+
<li>during the end tag processing for the element</li>
|
171
|
+
<li>when the complete document element (start/end tags + content) is available</li>
|
172
|
+
</ul>
|
135
173
|
|
136
|
-
<p class="explanation">
|
174
|
+
<p class="explanation">(The possible invocation points are actually slightly more detailed, but this simplified list of processing points is sufficient for discussing the behavior of most directives.)</p>
|
137
175
|
|
176
|
+
<p>By implementing processing logic at these various points during the overall document processing, a directive can accomplish its objectives by affecting the element attributes that are emitted to the output document, by manipulating the element content that is rendered, or by controlling the entire element (if any) that is rendered onto the output from the source.
|
177
|
+
</p>
|
178
|
+
|
179
|
+
<p>Recall also that a document element can contain other elements, in addition to or instead of text content. Directives on nested elements are processed along with the child elements in the source document, so a directive on an ancestor element sees the result of any nested directives at the point where it operates on the resulting element and its content.
|
180
|
+
</p>
|
138
181
|
|
139
182
|
<a name="directive_framework"></a>
|
140
183
|
<h2>Directive Implementation Framework</h2>
|
141
184
|
|
142
|
-
<p
|
185
|
+
<p>
|
186
|
+
When you create a custom MasterView template directive, you need to do several things:
|
187
|
+
</p>
|
188
|
+
|
189
|
+
<ul>
|
190
|
+
<li>define the directive - its name and purpose (semantics)</li>
|
191
|
+
<li>define the attribute syntax - what parameters, if any, are specified in the attribute value</li>
|
192
|
+
<li>define the processing logic - determine at what points in the source element processing your directive handler should be invoked and define the logic which determines its effect on the output document</li>
|
193
|
+
</ul>
|
194
|
+
|
195
|
+
<h3>Creating the Directive Implementation Class</h3>
|
196
|
+
|
197
|
+
<p>
|
198
|
+
A directive implementation extends the <code>MasterView::DirectiveBase</code> base class,
|
199
|
+
which provides the standard infrastructure for directives.
|
200
|
+
</p>
|
201
|
+
|
202
|
+
<pre class="code">
|
203
|
+
module MyAppDirectives
|
204
|
+
class MyDirective < MasterView::DirectiveBase
|
205
|
+
# ... directive metadata declarations ...
|
206
|
+
# ... directive attribute value argument definitions ...
|
207
|
+
# ... template element processing event handlers ...
|
208
|
+
end
|
209
|
+
end
|
210
|
+
</pre>
|
211
|
+
|
212
|
+
<p class="explanation">
|
213
|
+
<b>Note:</b> it is not mandatory to subclass <code>DirectiveBase</code> to implement a directive class, but it'll certainly make your life easier.
|
214
|
+
The key mixin classes which provide the essence of directive-nesss
|
215
|
+
in the <code>DirectiveBase</code> implementation framework
|
216
|
+
are <code>DirectiveMetadata</code> and <code>DirectiveDSL</code>, along with
|
217
|
+
some convenience services from <code>DirectiveHelpers</code>.
|
218
|
+
</p>
|
219
|
+
|
220
|
+
<h3>Directive Metadata Specification</h3>
|
221
|
+
|
222
|
+
<p>A directive is described by various standard properties which are associated
|
223
|
+
with the directive implementation class as metadata properties.
|
224
|
+
Some of the metadata properties affect the processing operations of the template engine,
|
225
|
+
while others are descriptive information for documentation purposes.
|
226
|
+
</p>
|
227
|
+
|
228
|
+
<p>The standard directive metadata properties recognized by MasterView are:</p>
|
229
|
+
|
230
|
+
<ul>
|
231
|
+
<li><code>:namespace</code> - the namespace used for the directive in template markup</li>
|
232
|
+
<li><code>:attribute_name</code> - the attribute name used for the directive in template markup</li>
|
233
|
+
<li><code>:priority</code> - processing priority level of the directive</li>
|
234
|
+
<li><code>:description</code> - a short (1-liner) description of the directive</li>
|
235
|
+
</ul>
|
236
|
+
|
237
|
+
<!--PUNT: not yet clear what we want to say about this [DJL 17-Oct02006]
|
238
|
+
<p class="explanation">(Note: the documentation metadata attributes are not yet fully exploited in ways that we might like. The <code>:summary</code> attribute is used on the Directives information page by the MasterView Admin controller; we would like in the future to provide easier access automate the directive documentation to build rdoc-style)
|
239
|
+
</p>
|
240
|
+
-->
|
241
|
+
|
242
|
+
<p>The default attribute name for a directive is derived from the class name,
|
243
|
+
similar to the name association schemes used by Rails for controllers, helpers, and views,
|
244
|
+
so this metadata attribute typically does not need an explicit declaration.
|
245
|
+
By default, directive class <code>Foo</code> is associated with attribute <code>foo</code> in template markup, while <code>FooBar</code> is associated with attribute <code>foo_bar</code>, etc.
|
246
|
+
</p>
|
247
|
+
|
248
|
+
<p>The default directive priority level is <code>Medium</code>, on the spectrum ranging from
|
249
|
+
<code>Highest</code>...<code>VeryHigh</code>...<code>High</code>...<code>Medium</code>...<code>Low</code>...<code>VeryLow</code>...<code>Lowest</code>.
|
250
|
+
</p>
|
251
|
+
|
252
|
+
<p>Directive metadata can be specified in several ways, with a precedence hierarchy allowing for application-specific customization:</p>
|
253
|
+
|
254
|
+
<ul>
|
255
|
+
<li><code>metadata</code> declaration in the directive class
|
256
|
+
<div>typically used for <code>:summary</code> and optionally to modify the default <code>:priority</code>; used to specify <code>:attribute_name</code> if necessary
|
257
|
+
</div>
|
258
|
+
</li>
|
259
|
+
<li><code>.metadata</code> specification file in the directory on the load path
|
260
|
+
<div>YAML notation specification of the <code>default:</code> metadata values for directive classes contained in this directory. Typically used to specify the <code>:namespace</code> for a set of directives.</div>
|
261
|
+
</li>
|
262
|
+
<li><code>metadata settings hash associated with a directive load path directory entry</code>
|
263
|
+
<div>hash containing <code>default:</code> hash for metadata defaults.
|
264
|
+
Allows a client application to override the metadata defaults; can be used to modify the namespace for the directives used in template document markup by this application (e.g., to mediate directive namespace collisions if multiple sources of addon directives are used)
|
265
|
+
</div>
|
266
|
+
</li>
|
267
|
+
</ul>
|
268
|
+
|
269
|
+
<h4>Directive Argument Definition Examples</h4>
|
270
|
+
|
271
|
+
<pre class="code">
|
272
|
+
module MyAppDirectives
|
273
|
+
class MyDirective < MasterView::DirectiveBase
|
274
|
+
|
275
|
+
metadata :priority => 'High',
|
276
|
+
:description => 'My really cool directive'
|
277
|
+
|
278
|
+
# ... directive attribute value argument definitions ...
|
279
|
+
# ... template element processing event handlers ...
|
280
|
+
end
|
281
|
+
end
|
282
|
+
</pre>
|
283
|
+
|
284
|
+
<p>A <code>.metadata</code> file in the directory containing directive class .rb code files:</p>
|
285
|
+
|
286
|
+
<pre class="code">
|
287
|
+
# MasterView directive metadata specifications
|
288
|
+
# Built-in MasterView directives
|
289
|
+
|
290
|
+
# default metadata values for directives loaded from this directory
|
291
|
+
# template document attribute qnames: <xxx coolops:foo="bar">...</xxx>
|
292
|
+
default:
|
293
|
+
namespace: coolops
|
294
|
+
</pre>
|
295
|
+
|
296
|
+
<p>An application-specific override of the default namespace for the directives loaded from a directory specified in the application's <code>masterview/settings.rb</code> configuration:</p>
|
297
|
+
|
298
|
+
<pre class="code">
|
299
|
+
config.add_directive_path '/path/to/custom/directives', { :default: => {:namespace => 'xops'}, }
|
300
|
+
</pre>
|
301
|
+
|
302
|
+
<h3>Directive Attribute Syntax Specification</h3>
|
303
|
+
|
304
|
+
<p>
|
305
|
+
When you create a directive, you need to specify the syntax that will be used for
|
306
|
+
writing the directive attribute and its value in template document markup.
|
307
|
+
Your directive will generally need to be provided with arguments which control the
|
308
|
+
processing of the document element on which the directive attribute is defined.
|
309
|
+
</p>
|
310
|
+
|
311
|
+
<p>In some cases, the entire directive attribute value is used as a single argument.
|
312
|
+
For example, the <code>mv:content</code> directive which replaces the content of the element on which it is defined with the results of evaluating a ruby expression uses its attribute value string to generate an embedded ruby block <code><%= ...attr value... %></code> in the output.
|
313
|
+
A directive implementation can access its attribute value using the <code>attr_value</code> accessor.
|
314
|
+
</p>
|
315
|
+
|
316
|
+
<p>
|
317
|
+
A directive can also use its attribute value as an argument list, just as arguments are used when invoking a Ruby method.
|
318
|
+
The MasterView directive implementation framework provides a simple declarative notation
|
319
|
+
for defining the argument list signature of an attribute. Each argument that you declare is mapped to an instance variable in your directive class, with parsing of the attribute value string into the variable value handled automatically by the directive framework facilities of MasterView.
|
320
|
+
</p>
|
321
|
+
|
322
|
+
<p>
|
323
|
+
As with parameters to a Ruby method, directive arguments obtained from the attribute value string in the template souurce document can
|
324
|
+
be expressed as a sequence of positional parameters, optionally with a default value.
|
325
|
+
Keyword values can be specified using Ruby hash literal notation <code>{ key1 => value1, key2 => value2, ...}</code>.
|
326
|
+
Trailing values in a variable-length argument list can be collected in a single array value argument.
|
327
|
+
Finally, an optional block argument can be provided with an argument definition to provide custom processing on the value.
|
328
|
+
</p>
|
329
|
+
|
330
|
+
<p>To define the parameters for your directive and the parsing rules for extracting each value from the directive attribute value string, use the <code>attr_arg</code> declaration in your directive implementation class. The first argument to <code>attr_arg</code> is a symbol with the name of the argument, which is used to create an accessor method for an instance variable that will contain the argument value.
|
331
|
+
Argument values extracted from the attribute value are strings.
|
332
|
+
</p>
|
333
|
+
<p>
|
334
|
+
Additional options can be specified in the form <code><i>:option_name</i> => <i>value</i></code>
|
335
|
+
to indicate how the value should be obtained. By default, an omitted argument value is parsed as an empty string.
|
336
|
+
</p>
|
337
|
+
|
338
|
+
<!--####
|
339
|
+
Keyword args must be wrapped in hash literal brackets *unless* they are the last arg.
|
340
|
+
###test array lits....
|
341
|
+
###-->
|
342
|
+
|
343
|
+
<ul>
|
344
|
+
<li><code>attr_arg <i>:argname</i>, :quote => true</code> - wrap the argument value in (single) quotes
|
345
|
+
</li>
|
346
|
+
<li><code>attr_arg <i>:argname</i>, :default => <i>value</i></code> - specify default value if the argument is omitted
|
347
|
+
</li>
|
348
|
+
<li><code>attr_arg <i>:argname</i>, :varargs => true</code> - collect remaining args (if any) as an array (like *params in ruby)
|
349
|
+
</li>
|
350
|
+
<li><code>attr_arg <i>:argname</i>, :append_element_attrs => [<i>attrName1</i>, <i>attrName1</i>,...]</code> - merge the specified attributes from the element into a hash value
|
351
|
+
<div>Specify <code>:common_html</code> as shorthand for collecting common html attributes (id, class, style, alt, title, width, height, etc)</div>
|
352
|
+
</li>
|
353
|
+
</ul>
|
354
|
+
|
355
|
+
<p>An <code>attr_arg <i>:argname</i></code> directive argument definition can also be specified with an block argument which allows for arbitrary processing to determine the value.
|
356
|
+
</p>
|
357
|
+
|
358
|
+
<ul>
|
359
|
+
<li><code>attr_arg <i>:argname</i> {...}</code> - set the argument value to the the result of evaluating the block with no arguments
|
360
|
+
</li>
|
361
|
+
<li><code>attr_arg <i>:argname</i> {|value| ... }</code> - pass arg value into block to allow additional manipulation of the value
|
362
|
+
</li>
|
363
|
+
<li><code>attr_arg <i>:argname</i> {|value args| ... }</code> - pass value and remaining args array to the block
|
364
|
+
</li>
|
365
|
+
<li><code>attr_arg <i>:argname</i> {|value args directive| ... }</code> - pass value, remaining args array, and the directive instance for which the argument value is being obtained to the block
|
366
|
+
</li>
|
367
|
+
</ul>
|
368
|
+
|
369
|
+
<h4>Directive Argument Definition Examples</h4>
|
370
|
+
|
371
|
+
<pre class="code">
|
372
|
+
module MyAppDirectives
|
373
|
+
class MyDirective < MasterView::DirectiveBase
|
374
|
+
|
375
|
+
# wrap the value parsed from the attribute value in string quotes
|
376
|
+
attr_arg :string_lit_arg, :quote => true
|
377
|
+
|
378
|
+
# a value that we want to normalize
|
379
|
+
attr_arg :some_option { |value| value.downcase }
|
380
|
+
|
381
|
+
# a value with a default if not specified
|
382
|
+
attr_arg :other_option, :default => 'normal'
|
383
|
+
|
384
|
+
# collect attributes from the element
|
385
|
+
attr_arg :html_options, :append_element_attrs => [:common_html, :size]
|
386
|
+
|
387
|
+
# ... template element processing event handlers ...
|
388
|
+
|
389
|
+
end
|
390
|
+
end
|
391
|
+
</pre>
|
392
|
+
|
393
|
+
<h4>Directive Attribute Value Processing</h4>
|
143
394
|
|
144
|
-
<h3>Construction</h3>
|
145
395
|
<p>When a directive attribute is encountered while processing a document element node,
|
146
|
-
an instance of the implementation class registered for that directive is constructed
|
147
|
-
|
148
|
-
|
396
|
+
an instance of the implementation class registered for that directive is constructed for processing the element. The value of the directive attribute from the document element is passed to the directive's initializer as a <code>String</code> value
|
397
|
+
and is available to the directive handler
|
398
|
+
using the <code>attr_value</code> accessor.
|
399
|
+
</p>
|
400
|
+
|
401
|
+
<p>The directive argument definitions from the <code>attr_arg</code> specifications in the directive implementation are applied in declaration order to initialize the instance variable values of the directive handler from the attribute value.</p>
|
402
|
+
|
403
|
+
<h3>Document Element Processing</h3>
|
404
|
+
|
405
|
+
<p>
|
406
|
+
A directive implementation specifies its effect on processing the document element to which it is attached by declaring one or more event handlers using the <code>event</code> declaration.
|
407
|
+
An event handler definition specifies a processing event at which it is to be invoked
|
408
|
+
and the action to be taken.
|
409
|
+
</p>
|
410
|
+
|
411
|
+
<h4>Document Processing Event Registration</h4>
|
412
|
+
|
413
|
+
<p>The general form of an event handler declaration is <code>event <i>:eventname</i> <i>action</i></code>.</p>
|
414
|
+
|
415
|
+
<p>
|
416
|
+
A directive can specify an action to be performed at any of the following events which are notified during the processing of a document element:
|
417
|
+
</p>
|
418
|
+
|
419
|
+
<table class="eventDescription" summary="detailed list of processing events">
|
420
|
+
<thead>
|
421
|
+
<tr><th>Event</th><th>Description</th><th>Default Action</th></tr>
|
422
|
+
</thead>
|
423
|
+
<tbody>
|
424
|
+
|
425
|
+
<tr>
|
426
|
+
<td><code>:before_stag</code></td>
|
427
|
+
<td><i>tbs</i></td>
|
428
|
+
<td> </td>
|
429
|
+
</tr>
|
430
|
+
<tr>
|
431
|
+
<td><code>:stag</code></td>
|
432
|
+
<td>element start tag and attributes are available</td>
|
433
|
+
<td>Append the start tag to the rendering output for this element</td>
|
434
|
+
</tr>
|
435
|
+
<tr>
|
436
|
+
<td><code>:after_stag</code></td>
|
437
|
+
<td><i>tbs</i></td>
|
438
|
+
<td> </td>
|
439
|
+
</tr>
|
440
|
+
|
441
|
+
<tr>
|
442
|
+
<td><code>:content</code></td>
|
443
|
+
<td>the element content (text and/or child elements) is available</td>
|
444
|
+
<td>Append the source element content to the rendering output for this element</td>
|
445
|
+
</tr>
|
446
|
+
|
447
|
+
<tr>
|
448
|
+
<td><code>:before_etag</code></td>
|
449
|
+
<td><i>tbs</i></td>
|
450
|
+
<td> </td>
|
451
|
+
</tr>
|
452
|
+
<tr>
|
453
|
+
<td><code>:etag</code></td>
|
454
|
+
<td>the element end tag has been reached</td>
|
455
|
+
<td>Append the element end tag to the rendering output for this element</td>
|
456
|
+
</tr>
|
457
|
+
<tr>
|
458
|
+
<td><code>:after_etag</code></td>
|
459
|
+
<td><i>tbs</i></td>
|
460
|
+
<td> </td>
|
461
|
+
</tr>
|
462
|
+
|
463
|
+
<tr>
|
464
|
+
<td><code>:element</code></td>
|
465
|
+
<td>the complete document element (start/end tags + content) is available</td>
|
466
|
+
<td>Append the accumulated element rendering to the output document</td>
|
467
|
+
</tr>
|
468
|
+
|
469
|
+
</tbody>
|
470
|
+
</table>
|
471
|
+
|
472
|
+
<p>
|
473
|
+
As noted in the overview, most directive processing is associated with the <code>:stag</code> event, when the directive can manipulate the attributes of the element, or with the <code>:content</code> or <code>:element</code> events when performing transformations which involve the element content or the entire (tags+content) element output.
|
474
|
+
Processing done on the <code>:etag</code> event is used by conditional directives that control the presence or absence of the element in the output document.
|
475
|
+
An <code>:etag</code> handler is also used in combination with <code>:stag</code> when providing directive processing which wraps the element in some fashion (e.g., the <code>mv:block</code> directive which wraps a document element with ruby erb inserts to form a block evaluation context).
|
476
|
+
</p>
|
477
|
+
|
478
|
+
<p>The <code>before_</code> and <code>after_</code> events can be used to insert additional content or elements into the document, as well as being useful for initializing or updating the state of the directive handler itself. However, when used to append additional output these processing events should be used with care to ensure that the resulting output is a properly-defined document structure.
|
149
479
|
</p>
|
150
480
|
|
151
|
-
<p>
|
152
|
-
In particular, methods <code>parse_eval_into_array</code> evaluates the string as if it was the content of an array literal, while <code>parse_eval_into_hash</code> returns a Ruby hash containing the <code>key => value</code> pairs from the attribute value.
|
481
|
+
<p>The action for an event handler can be defined by specifying an option which indicates a standard processing action or by providing a block containing the processing logic.
|
153
482
|
</p>
|
154
483
|
|
155
|
-
<
|
484
|
+
<pre class="code">
|
485
|
+
module MyAppDirectives
|
486
|
+
class MyDirective < MasterView::DirectiveBase
|
487
|
+
# ... directive attribute value argument definitions ...
|
488
|
+
|
489
|
+
event :stag {
|
490
|
+
# ... add/change/transform element attributes...
|
491
|
+
}
|
492
|
+
event :content do
|
493
|
+
#... modify the element content before it is emitted onto the output
|
494
|
+
end
|
495
|
+
|
496
|
+
end
|
497
|
+
end
|
498
|
+
</pre>
|
499
|
+
|
500
|
+
<div class="todo">TODO: add an example of a handler which specifies its action using a standard <code>:render</code> option</div>
|
501
|
+
|
502
|
+
<h4>Document Processing Event Actions</h4>
|
503
|
+
|
504
|
+
<p>
|
505
|
+
An event handler block in a directive implementation can reference any of its attribute arguments using the accessor named in an <code>attr_arg :argname</code> declaration
|
506
|
+
or its complete atribute value string using the <code>attr_value</code> accessor.
|
507
|
+
It can also access information about its document element in the source template
|
508
|
+
using <code>element_attrs</code> to access a hash of the element attributes
|
509
|
+
and <code>element_tag</code> to obtain the name of the element to which it is attached.
|
510
|
+
</p>
|
511
|
+
|
512
|
+
<p>
|
513
|
+
At each event during the course of processing a template source document element,
|
514
|
+
the output content being accumulated for that element can be affected.
|
515
|
+
The principal service used by a directive handler to specify its contribution to the accumulated rendering of the element is the <code>render</code> service.
|
516
|
+
As with Rails controllers and views, a directive event handler can actively specify the <code>render</code> output it wishes to produce. If no rendering operation is performed by an event handler, the default rendering is provided automatically.
|
517
|
+
</p>
|
518
|
+
|
519
|
+
<p>
|
520
|
+
The argument for a <code>render</code> operation is the symbol <code>:nothing</code> to specify that no output should be produced for this event.
|
521
|
+
This option can be used by conditional processing directives to suppress content from the output.
|
522
|
+
</p>
|
523
|
+
|
524
|
+
<p>
|
525
|
+
More commonly, a directive handler will invoke <code>render</code> to cause either text content, possibly including html tag markup as well as element content, or erb markup to be appended to the element output.
|
526
|
+
The default rendering for the element is available from the <code>render_result</code> accessor.
|
527
|
+
This default rendering can be modified or used with erb markup.
|
528
|
+
The helper function <code>erb_eval</code> generates output wrapped in erb evaluation markup
|
529
|
+
<code><% ...ruby expression(s)... %></code> which causes the content to be evaluated as ruby code without affecting the content of the view.
|
530
|
+
The companion helper function <code>erb_content</code> generates output wrapped in erb evaluation markup
|
531
|
+
<code><%= ...ruby expression(s)... %></code> which causes the content to be evaluated as ruby code and the resulting value inserted in the final view content.
|
532
|
+
</p>
|
156
533
|
|
157
534
|
|
158
|
-
<p class="explanation">TODO: fill in here with details on how the directive hooks up its processing (typically either start or end of the element tag to which it is attached), the context available to it when invoked (what can you get from the dcs arg), and how output is emitted</p>
|
159
535
|
|
160
536
|
</div> <!-- bodyContent -->
|
161
537
|
</div>
|
@@ -165,6 +541,8 @@ In particular, methods <code>parse_eval_into_array</code> evaluates the string a
|
|
165
541
|
·
|
166
542
|
<a href="./index.html">Doc Home</a>
|
167
543
|
|
|
544
|
+
<a href="./about.html">About</a>
|
545
|
+
|
|
168
546
|
<a href="./installation.html">Installation</a>
|
169
547
|
|
|
170
548
|
<a href="./configuration.html">Configuration</a>
|
@@ -173,15 +551,19 @@ In particular, methods <code>parse_eval_into_array</code> evaluates the string a
|
|
173
551
|
|
|
174
552
|
<a href="./directives.html">Directives</a>
|
175
553
|
|
|
176
|
-
<a href="./
|
554
|
+
<a href="./developer.html">Developers</a>
|
177
555
|
|
|
556
|
+
<a href="./media_list.html">Screencasts</a>
|
557
|
+
·
|
178
558
|
</div>
|
179
559
|
<table summary="layout area">
|
180
560
|
<tbody>
|
181
561
|
<tr>
|
182
562
|
<td class="copyright">© Copyright MasterView 2006</td>
|
183
563
|
<td class="validators">
|
184
|
-
<a href="http://validator.w3.org/check/referer"
|
564
|
+
<a href="http://validator.w3.org/check/referer"><img
|
565
|
+
src="http://www.w3.org/Icons/valid-xhtml10" class="w3c_validator"
|
566
|
+
title="Valid XHTML 1.0!" alt="Valid XHTML 1.0!" /></a>
|
185
567
|
</td>
|
186
568
|
</tr>
|
187
569
|
</tbody>
|