1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
page!content: = Ruwiki %RV#% Templating
Ruwiki uses a heavily modified version of the \RDoc
“cheap-n-cheerful” HTML page template system. This a
line-oriented, text-based templating system.
== Templates
Templates in the templating system are essentially plain strings with
particular references to templating keys or an include directive.
The template interacts with value and message hashes provided by
Ruwiki. The keys known to the templates expected by Ruwiki are
detailed in Extending_Ruwiki. Nested key references are found from the
inside-out. That is, the closest resolving key to the current level is
found, not the furthest resolving key.
=== Including Other Templates
Templates may include other templates to any arbitrary level by using
the <tt>!INCLUDE!</tt> directive. When the \TemplatePage is created,
an array of template strings are provided; these will be used to
satisfy <tt>!INCLUDE!</tt> directives. If there are not enough
template strings provided, <tt>!INCLUDE!</tt> won’t be
translated.
: This may change before Ruwiki reaches 1.0, so that templates are
: named instead of iterated.
=== Simple Template Keys
Strings of the format <tt>%<em>key</em>%</tt> or
<tt>%?<em>key</em>%</tt> are simple template keys. <em>key</em> is
looked up in the provided value hash and is presented as the string
value of the result. <tt>%key%</tt> template keys are mandatory; if
the key is not found in the value hash, an exception will be raised.
<tt>%?key%</tt> template keys are optional; if they key is not found
in the value hash, an empty string (“”) will be used.
=== Labels
Strings of the format <tt>#<em>key</em>#</tt> or
<tt>#?<em>key</em>#</tt> are labels. <em>key</em> is looked up in the
provided message hash as a Symbol (e.g.,
<tt><em>key</em>.intern</tt>). As with simple template keys,
<tt>#key#</tt> labels are mandatory and <tt>#?key#</tt> labels are
optional.
=== Links
Strings of the format <tt>HREF:\ref:name</tt> will become HTML links.
Both <em>ref</em> and <em>name</em> are keys to be looked up.
<em>name</em> is mandatory; an exception will be raised if it is not
found.
=== Control Structures
The templating library supports both looping and conditional control
structures in both single-line and multi-line forms. Single-line
control structures <strong>may not</strong> be nested; multi-line
control structures <strong>may</strong> be nested arbitrarily deeply.
==== Looping Control Structures
There are two forms of looping control structures.
[:key|stuff:]
START:key
... stuff ...
END:key
===== Single-Line Looping
[:key|stuff:]
The value of <em>key</em> may be <tt>nil</tt>, an integer value, a
range, or an array. When <em>key</em> represents:
# <tt>nil</tt>, the looping structure will be replaced with an empty string.
# An integer, <em>stuff</em> will be repeated <em>key</em> times. Values from 1 to <em>key</em> will be provided to the text of <em>stuff</em> to be substituted as a simple template key of the form <tt>%key%</tt>.
# A range, <em>stuff</em> will be repeated once for each successive value in the range of <em>key</em>. Each value will be provided to the text of <em>stuff</em> to be substituted as a simple template key of the form <tt>%key%</tt>.
# An array, the behaviour will differ depending on the contents of the array.
## If the array contains hashes, the behaviour is the same as a multi-line looping construct. See below for details.
## Otherwise, the template iterates through the array, providing each value to the text of <em>stuff</em> to be substituted as a simple template key of the form <tt>%key%</tt>.
As an example, if we have:
"[:b|%b% ]"
# <tt>val["b"] = 3 -> "1 2 3 "</tt>
# <tt>val["b"] = (0..2) -> "0 2 3 "</tt>
# <tt>val["b"] = ["a", "B"] -> "a B "</tt>
==== Multi-Line Looping
START:key
... stuff ....
END:key
The value of <tt>key</tt> must be an array of hashes. <tt>... stuff
...</tt> will be repeated once for each entry in the array. The hashes
will be passed as nested value hashes.
%a% [:b|%a% ]%a%
When the above template string is run with the following hash:
val["a"] = 1
val["b"] = [ { "a" => 2 }, { "a" => 3 } ]
The result is:
1 2 3 1
The behaviour is the same for multi-line blocks.
==== Conditional Block Keys
IF:key
... stuff ...
ENDIF:key
The block between <tt>\IF:key</tt> and <tt>\ENDIF:key</tt> will be included in
the output only if the corresponding key is set in the value hash.
== Example
Given the set of templates T1, T2, and T3 (shown below), here’s how we would
use the templating system.
values = { "name" => "Dave", "state" => "TX" }
t = TemplatePage.new(T1, T2, T3)
File.open(name, w) { |f| t.process(f, values) }
or:
<!-- Source -->
val1 = { "name" => "Dave", "state" => "TX" }
val2 = { "name" => "Dave" }
msgs = { }
res = ""
t.process(res, values, msgs)
<!-- T1 -->
Templates can subsitute a wide variety of values.
!INCLUDE!
<!-- T2 -->
Name: %name% !INCLUDE!
<!-- T3 -->
IF:state
State: %state%
ENDIF:state
The result will be:
Name: Dave
State: TX
Name: Dave
properties!project: Ruwiki
properties!title: RuwikiTemplatingLibrary
properties!topic: RuwikiTemplatingLibrary
properties!version: 1
ruwiki!content-version: 2
ruwiki!version: %RV#%
|