1ecpp(7) Tntnet users guide ecpp(7)
2
3
4
6 ecpp - template-language for tntnet(8)
7
9 ecpp is the template-language used by the tntnet-system to generate
10 dynamic content.
11
12 A template consists of normal content (normally html-data) enriched
13 with special tags, which trigger some special handling.
14
15 One ecpp-file is compiled into a C++-class. The C++-class is placed
16 into the namespace component. A ecpp-file compiled into a C++-class is
17 called component. The name of the class is the basename of the file.
18
19 request, reply, qparam
20 Each component has 3 parameters: request, reply and qparam. request
21 holds information about the client-request like http headers and the
22 url, but also additional parameters specified in the config-file tnt‐
23 net.xml(7). The type of request is tnt::HttpRequest.
24
25 reply receives the answer from the component. The component can set
26 additional http-headers here, set cookies and - most important - gener‐
27 ate output. The most important methods here are reply.out() and
28 reply.sout(). Both return a std::ostream, which receives the output of
29 the component. reply.sout() has a filter installed, which translates
30 some characters, whith special meanings in html to the corresponding
31 html-entities. The characters are <, >, &, " and '. This is useful for
32 printing values from variables to the html-code.
33
34 qparam holds the query-parameters parsed from GET- or POST-parameters
35 or received from other components. The type of qparam is
36 tnt::query_params. Normally you use a <%args>-block to specify the
37 parameters, but there are special cases, where it is useful to access
38 these directly.
39
40 component adressing
41 Each component has a unique name. The name is composed from the
42 class-name, the character '@' and the name of the shared library, it is
43 located. Components can have internal subcomponents. The name of the
44 internal subcomponent is appended to the classname separated by a dot
45 (.).
46
47 special rule for line feeds after a </%something>-tag
48 A line feed immediately after a closing tag for all <%something>-blocks
49 are ignored. Hence blocks followed immediately one after another does
50 not generate white space in output, which is often undesirable.
51
52 error-handling
53 Error-handling is done by exception. Tntnet catches all exceptions
54 thrown by components and handles them properly. Exceptions must be
55 derived from std::exception. Exceptions derived from tnt::HttpError,
56 are handled separately. They carry a http-return-code, which is sent to
57 the client. Other exceptions derived from std::exception, result in a
58 http error code 500 (Internal Server Error).
59
61 <$ expr $>
62 Print expressions expr to the outputstream. The characters <, >,
63 &, " and ', which have special meanings in html, are translated
64 to the corresponding html-entities.
65
66 <$$ expr $>
67 Print expressions expr without translating characters with spe‐
68 cial meaning in html to html entities to the output stream.
69
70 <? cond ? expr ?>
71 Conditional output. Print expression expr to the outputstream,
72 if cond evaluates to true. Characters with special meaning in
73 html are translated to the corresponding html-entities.
74
75 <?? cond ? expr ?>
76 Conditional output. Print expression expr to the outputstream,
77 if cond evaluates to true. Characters with special meaning in
78 html are not translated to the corresponding html-entities.
79
80 <& component [ arguments ] >
81 Call the specified component. The output of the component is
82 printed into the outputstream. If the component-name does not
83 start with a letter, the ecpp-compiler treats it as a expres‐
84 sion, which returns the name of the component. You must surround
85 the expression in brackets, if it contains spaces.
86
87 The arguments-part specify the parameters, the component will
88 receive. Arguments are name-value-pairs separated by '='. They
89 are put in the qparam-parameter of the component and are nor‐
90 mally declared in the <%args>-block. Values can be specified in
91 3 forms:
92
93 As a plain word without spaces
94
95 As a string enclosed in quotation marks
96
97 As a expression enclosed in brackets
98
99 A single plain word in the argumentlist is treated as a variable
100 of type cxxtools::query_params and a copy is passed to the com‐
101 ponent. Other parameters are added to this copy. If you want to
102 pass all parameters of the current component put the variable
103 qparam as a plain word in the argument list.
104
105 </&component>
106 Closing-tag for a component-call. When components are called,
107 this closing-tag might occur later. The code in <%close>-block
108 is placed here.
109
110 <{...}>
111 C++-inline-processing-block. The code in this block is copied
112 into the C++-class unchanged.
113
114 A linefeed after the closing tag is not ignored.
115
116 <#...#>
117 Comment-block. Everything in this block is ignored.
118
119 <%application [ scope="component|page|global" ] >...</%application>
120 Variables defined here, have the lifetime of the application.
121
122 Application-scope is automatically locked.
123
124 <%args>...</%args>
125 Defines GET- or POST-parameters recieved by the component.
126
127 Each argument has a name and optionally a defaul-value. The
128 default-value is delimited by '=' from the name. A single argu‐
129 ment-definition followed by a semicolon (;). In the component a
130 variable with the same name of type std::string is defined,
131 which receives the value.
132
133 A argument-name can be prefixed by a type-definition. The
134 ecpp-compiler generates code, which tries to convert the value
135 with the input-stream-operator. This means, that each type,
136 which can be read from a input-stream (std::istream) can be
137 used. If the argument can't be converted, a exception is thrown.
138
139 Argumentnames can be postfixed by empty square-brackets. This
140 defines a std::vector with the specified type or std::string, if
141 no type is specified. This way multiple values with the same
142 name can be received. If a type is specified, each value is con‐
143 verted to the target-type.
144
145 <%close>...</%close>
146 Code in these tags is placed into the calling component, when a
147 closing tag </&component> is found.
148
149 The <%close> receives the same parameters like the corresponding
150 normal component call.
151
152 <%config>...</%config>
153 Often webapplications need some configuration like data‐
154 base-names or login-information to the database. These configu‐
155 ratioin-variables can be read from the tntnet.xml. Variablenames
156 ended with a semicolon are defined as static std::string-vari‐
157 ables and filled from tntnet.xml. A variable can be prepended by
158 a type. The value from tntnet.xml is then converted with a
159 std::istream.
160
161 You can also specify a default value by appending a '=' and the
162 value to the variable.
163
164 Example:
165
166 <%config>
167 dburl = "sqlite:db=mydbfile.sqlite";
168 int maxvalue = 10;
169 </%config>
170
171 tntnet.xml:
172 <dburl>postgresql:dbname=mydb</dburl>
173
174 <%cpp>...</%cpp>
175 C++-processing-block. The code between these tags are copied
176 into the C++-class unchanged.
177
178 A linefeed after the closing tag is ignored.
179
180 <%def name>...</%def>
181 Defines a internal subcomponent with the name name, which can be
182 called like other components.
183
184 <%doc>...</%doc>
185 Comment-block. Everything in this block is ignored.
186
187 A linefeed after the closing tag is ignored.
188
189 <%get>...</%get>
190 Works like a <%args> block but receives only GET parameters.
191
192 <%i18n>...</%i18n>
193 Encloses a block of text-data, which is to be translated. See
194 ecppl(1) and ecppll(1) for details.
195
196 <%include>filename</%include>
197 The specified file is read and compiled.
198
199 <%param>...</%param>
200 Defines parameter received from calling components. In contrast
201 to query-parameters these variables can be of any type. The syn‐
202 tax (and the underlying technology) is the same like in scoped
203 variables. See the description about scoped variables to see how
204 to define parameters. The main difference is, that a parameter
205 variable has no scope, since the parameter is always local to
206 the component.
207
208 <%out> expr </%out>
209 Same as <$$ ... $>. Prints the contained C++ expression expr.
210
211 <%post>...</%post>
212 Works like a <%args> block but receives only POST parameters.
213
214 <%pre>...</%pre>
215 Defines C++-code, which is placed outside the C++-class and out‐
216 side the namespace-definition. This is a good place to define
217 #include-directives.
218
219 <%request [ scope="component|page|global" ] >...</%request>
220 Define request-scope variables. Variables defined here, has the
221 lifetime of the request.
222
223 <%session [ scope="component|page|global" ] >...</%session>
224 Variables defined here, has the lifetime of the session.
225
226 Sessions are identified with cookies. If a <%session>-block is
227 defined somewhere in a component, a session-cookie is sent to
228 the client.
229
230 Sessions are automatically locked.
231
232 <%securesession [ scope="component|page|global" ] >...</%securesession>
233 Secure session is just like session but a secure cookie is used
234 to identify the session. Secure cookies are transfered only over
235 a ssl connection from the browser and hence the variables are
236 only kept in a ssl secured application.
237
238 If a variable defined here is used in a non ssl page, the vari‐
239 able values are lost after the current request.
240
241 <%sout> expr </%sout>
242 Same as <$ ... $>. Prints the contained C++ expression expr. The
243 characters <, >, &, " and ', which have special meanings in
244 html, are translated to the corresponding html-entities.
245
246 <%thread [ scope="component|page|global" ] >...</%thread>
247 Variables defined here, has the lifetime of the thread. Each
248 thread has his own instance of these variables.
249
250 Thread-scope-variables do not need to be locked at all, because
251 they are only valid in the current thread.
252
254 Scoped variables are c++-variables, whose lifetime is handled by tnt‐
255 net. These variables has a lifetime and a scope. The lifetime is
256 defined by the tag, used to declare the variable and the scope is
257 passed as a parameter to the tag.
258
259 There are 5 different lifetimes for scoped variables:
260
261 request
262 The variable is valid in the current request. The tag is
263 <%request>.
264
265 application
266 The variable is valid in the application. The tag is <%applica‐
267 tion>. The application is specified by the shared-library of the
268 top-level component.
269
270 session
271 The variable is valid for the current session. The tag is <%ses‐
272 sion>. If at least session-variable is declared in the current
273 request, a session-cookie is sent to the client.
274
275 thread The variable is valid in the current thread. The tag is
276 <%thread>.
277
278 param The variable receives parameters. The tag is <%param>.
279
280 And 3 scopes:
281
282 component
283 The variable is only valid in the same component. This is the
284 default scope.
285
286 page The variable is shared between the components in a single
287 ecpp-file. You can specify multiple internal subcomponents in a
288 %def-block. Variables, defined in page-scope are shared between
289 these subcomponents.
290
291 global Variables are shared between all components. If you define the
292 same variable with global-scope in different components, they
293 must have the same type. This is achieved most easily defining
294 them in a separate file and include them with a
295 <%include>-block.
296
297 Variables are automatically locked as needed. If you use ses‐
298 sion-variables, tntnet ensures, that all requests of the same
299 session are serialized. If you use application-variables, tntnet
300 serializes all requests to the same application-scope. Request-
301 and thread-scope variables do not need to be locked at all,
302 because they are not shared between threads.
303
304 Syntax of scoped variables
305 Scoped variables are declared with exactly the same syntax as normal
306 variables in c++-code. They can be of any type and are instantiated,
307 when needed. Objects, which do not have default constructors, need to
308 be specified with proper constructor-parameters in brackets or sepa‐
309 rated by '='. The parameters are only used, if the variable need to be
310 instantiated. This means, that parameters to e.g. application-scope
311 variables are only used once. When the same component is called later
312 in the same or another request, the parameters are not used any more.
313
314 Examples
315 Specify a application-specific global variable, which is initialized
316 with 0:
317
318 <%application>
319 unsigned count = 0;
320 </%application>
321
322 Specify a variable with a user-defined type, which holds the state of
323 the session:
324
325 <%session>
326 MyClass sessionState;
327 </%session>
328
329 Specify a persistent databaseconnection, which is initialized, when
330 first needed and hold for the lifetime of the current thread. This
331 variable may be used in other components:
332
333 <%thread scope="global">
334 tntdb::Connection conn(dburl);
335 </%thread>
336
338 This manual page was written by Tommi Mäkitalo ⟨tommi@tntnet.org⟩.
339
341 tntnet(1), ecppc(1)
342
343
344
345Tntnet 2006-07-23 ecpp(7)