|
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