|
5 | 5 | xmlns:xlink="http://www.w3.org/1999/xlink"> |
6 | 6 | <info> |
7 | 7 | <title>HTML Templating Module</title> |
8 | | - <date>2Q21</date> |
| 8 | + <date>3Q25</date> |
9 | 9 | <keywordset> |
10 | 10 | <keyword>application-development</keyword> |
11 | 11 | </keywordset> |
|
23 | 23 |
|
24 | 24 | <para>The main goal of the HTML templating framework is a clean separation of concerns. |
25 | 25 | Generating entire pages in XQuery is quick and dirty, but makes maintenance and code |
26 | | - sharing difficult. Ideally people should be able to look at the HTML view of an |
| 26 | + sharing difficult. Ideally, people should be able to look at the HTML view of an |
27 | 27 | application and modify its look and feel without knowing XQuery. The application logic, |
28 | 28 | written in XQuery, should be kept separate. Likewise, the XQuery developer should only |
29 | 29 | have to deal with the minimal amount of HTML (generated dynamically).</para> |
30 | | - <para>The templating module also handles most of the HTTP processing an application |
| 30 | + <para> |
| 31 | + The templating module also handles most of the HTTP processing an application |
31 | 32 | requires. It does so using sophisticated features like automatic parameter injection and |
32 | 33 | type conversion. The goal was to remove repeating code like:</para> |
33 | 34 | <programlisting language="xquery" xlink:href="listings/listing-1.txt"/> |
|
45 | 46 | <sect1 xml:id="write-html"> |
46 | 47 | <title>Writing the HTML</title> |
47 | 48 |
|
48 | | - <para>The templating module is based mainly on conventions. Wherever possible it tries to |
| 49 | + <para> |
| 50 | + The templating module is based mainly on conventions. Wherever possible it tries to |
49 | 51 | make a best guess instead of requiring additional code or annotations. This works as |
50 | | - long as the conventions used are sufficiently clear.</para> |
51 | | - <para>The input for the templating framework is always a plain HTML file. The module scans |
| 52 | + long as the conventions used are sufficiently clear. |
| 53 | + </para> |
| 54 | + <para> |
| 55 | + The input for the templating framework is always a plain HTML file. The module scans |
52 | 56 | the HTML view for elements with <code>data-template</code> attributes |
53 | 57 | following a simple convention and tries to translate them into XQuery |
54 | 58 | function calls. By using <code>data-*</code> attributes, the HTML remains sufficiently clean and does |
55 | 59 | not get messed up with application code. A web designer could take the HTML files and |
56 | | - work on it without being bothered by the extra class names.</para> |
57 | | - <para>To start with the usual "Hello world" example:</para> |
| 60 | + work on it without being bothered by the extra class names. |
| 61 | + </para> |
| 62 | + <para> |
| 63 | + To start with the usual "Hello world" example: |
| 64 | + </para> |
58 | 65 | <programlisting language="xml" xlink:href="listings/listing-2.xml"/> |
59 | 66 |
|
60 | | - <para>When the module encounters <code>data-template="demo:hello"</code>, it will try to find a function named |
| 67 | + <para> |
| 68 | + When the module encounters <code>data-template="demo:hello"</code>, it will try to find a function named |
61 | 69 | <literal>demo:hello</literal> in all the modules known within the current XQuery context. If a function is found and its signature |
62 | 70 | follows a certain convention, it will be called and the <tag>div</tag> will |
63 | 71 | either be replaced or enhanced by whatever the function returns.</para> |
64 | 72 |
|
65 | | - <para>The <literal>data-template</literal> attribute must follow the function naming pattern. |
| 73 | + <para> |
| 74 | + The <literal>data-template</literal> attribute must follow the function naming pattern. |
66 | 75 | It is also possible to pass static parameters to a template call. |
67 | 76 | Additional parameters go into one or more attributes |
68 | 77 | <literal>data-template-*</literal>, where the * should be replace by the name of the parameter, |
69 | | - e.g. <literal>data-template-path="menu.html"</literal>.</para> |
| 78 | + e.g. <literal>data-template-path="menu.html"</literal>. |
| 79 | + </para> |
| 80 | + <sect2 xml:id="legacy-template-syntax"> |
| 81 | + <title>Legacy Template Syntax</title> |
| 82 | + <para> |
| 83 | + You might encounter older templates that use the class attribute to call template functions. |
| 84 | + Like <code><title class="app:title" /></code> |
| 85 | + </para> |
| 86 | + <para> |
| 87 | + This is considered <emphasis>legacy</emphasis> syntax and should be re-written to use <code>data-template</code> |
| 88 | + attributes instead. |
| 89 | + </para> |
| 90 | + <para> |
| 91 | + In fact, version 1.1.0 introduced a configuration option <literal>$templates:CONFIG_USE_CLASS_SYNTAX</literal>. |
| 92 | + Setting it to <literal>false()</literal> will cause all class attributes to be ignored when reading |
| 93 | + template files. This is necessary in order to use colons in class names, which some CSS frameworks tend to do. |
| 94 | + This option will likely be <emphasis>turned on by default</emphasis> with the next major release of this library. |
| 95 | + </para> |
| 96 | + </sect2> |
70 | 97 | </sect1> |
71 | 98 |
|
72 | 99 | <!-- ================================================================== --> |
73 | 100 |
|
74 | 101 | <sect1 xml:id="templating"> |
75 | 102 | <title>Templating Functions</title> |
76 | 103 |
|
77 | | - <para>A templating function is an ordinary XQuery function in a module which takes at least |
78 | | - two parameters of a specific type. Additional parameters are allowed. If a function does |
79 | | - not follow this convention it will be ignored by the framework.</para> |
80 | | - <para> For example, our "Hello world!" function could be defined as follows:</para> |
| 104 | + <para> |
| 105 | + A templating function is an ordinary XQuery function in a module. It <emphasis>must</emphasis> accept at least |
| 106 | + two parameters, <code>$node</code> and <code>$model</code>. |
| 107 | + Additional parameters are allowed. If a function does not follow this convention it will be |
| 108 | + ignored by the framework. |
| 109 | + </para> |
| 110 | + <para> |
| 111 | + For example, our "Hello world!" function could be defined as follows: |
| 112 | + </para> |
81 | 113 | <programlisting language="xquery" xlink:href="listings/listing-5.txt"/> |
82 | 114 | <para>The two required parameters are <code>$node</code> and <code>$model</code>: </para> |
83 | 115 | <itemizedlist> |
|
228 | 260 | <title>Important Note</title> |
229 | 261 | <para>The old version of the templating module used to be part of the <emphasis>deprecated</emphasis> |
230 | 262 | shared-resources package, while a <link xlink:href="https://github.com/eXist-db/templating/">new and improved version</link> |
231 | | - is now available in its own |
232 | | - expath package. We recommend to update to the new package with the short name |
| 263 | + is now available as its own expath library package. We recommend to update to the new package with the short name |
233 | 264 | <emphasis>templating</emphasis>, available on the eXist-db dashboard. To update, follow the 3 steps below:</para> |
234 | 265 | <orderedlist> |
235 | 266 | <listitem> |
|
241 | 272 | <programlisting language="xquery" xlink:href="listings/listing-15.txt"/> |
242 | 273 | </listitem> |
243 | 274 | <listitem> |
244 | | - <para>New standard templating functions will go into a separate module, so you may want to add the following import in addition to the one above, which will give you access to the lib:parse-params template function (and others in the future):</para> |
| 275 | + <para> |
| 276 | + New standard templating functions will go into a separate module, so you may want to add the following import |
| 277 | + in addition to the one above, which will give you access to the lib:parse-params template function (and others in the future): |
| 278 | + </para> |
245 | 279 | <programlisting language="xquery" xlink:href="listings/listing-16.txt"/> |
246 | 280 | </listitem> |
247 | 281 | </orderedlist> |
248 | 282 | </sect2> |
249 | 283 | <sect2 xml:id="main-xquery"> |
250 | 284 | <title>Calling the Templating from a Main XQuery</title> |
251 | | - <para>A complete main module which calls the |
252 | | - templating framework to process an HTML file passed in the HTTP request body could look |
253 | | - as follows:</para> |
| 285 | + <para> |
| 286 | + A complete main module which calls the templating framework to process an HTML file passed |
| 287 | + in the HTTP request body could look as follows: |
| 288 | + </para> |
254 | 289 | <programlisting language="xquery" xlink:href="listings/listing-12.txt"/> |
255 | | - <para>This module would be called from the URL rewriting controller. For example, we could |
| 290 | + <para>This module can now be called from the URL rewriting controller. For example, we can |
256 | 291 | add a rule to <literal>controller.xq</literal> to pass any .html resource to the above |
257 | 292 | main query (saved to <literal>modules/view.xq</literal>):</para> |
258 | 293 | <programlisting language="xquery" xlink:href="listings/listing-13.txt"/> |
259 | | - <para>The only part of the main module code which might look a bit unusual is the inline |
| 294 | + <para> |
| 295 | + The only part of the main module code which might look a bit unusual is the inline |
260 | 296 | lookup function: the templating module uses dynamic function calls to execute template |
261 | 297 | functions in application modules. But unfortunately, XQuery modules can only "see" |
262 | 298 | functions in their own context. There is therefore no way for the templating module to |
263 | 299 | determine what functions are defined in application modules which are outside its |
264 | 300 | context. So it needs to be "helped" by providing a callback function to resolve function |
265 | 301 | references. The lookup function is defined in the main context and can access all the |
266 | | - modules imported into the main module.</para> |
267 | | - <para>Normally you can just copy and paste the main module code as given above. To adapt it |
268 | | - to your own application, just import your application modules and you're done.</para> |
| 302 | + modules imported into the main module. |
| 303 | + </para> |
| 304 | + <para> |
| 305 | + Normally you can just copy and paste the main module code as given above. To adapt it |
| 306 | + to your own application, just import your application modules and you're done. |
| 307 | + </para> |
269 | 308 | </sect2> |
270 | 309 | </sect1> |
271 | 310 |
|
|
0 commit comments