1Basic syntax
2============
3
4A Diazo theme consists of a static HTML page (referred to as the "theme") and
5a rules file, conventionally called ``rules.xml``.
6
7The rules file contains an XML document that is is rooted in a tag called
8``<rules />``::
9
10    <rules
11        xmlns="http://namespaces.plone.org/diazo"
12        xmlns:css="http://namespaces.plone.org/diazo/css"
13        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
14
15           ...
16
17    </rules>
18
19Here we have defined three namespaces: the default namespace is used for rules
20and XPath selectors. The ``css`` namespace is used for CSS3 selectors. These
21are functionally equivalent to the XPath selectors. In fact, CSS selectors are
22replaced by the equivalent XPath selector during the pre-processing step of
23the compiler. Thus, they have no performance impact. The ``xsl`` namespace is
24used if you want to add inline XSLT directives for fine-grained control. We
25will come to that later in this guide.
26
27    Diazo supports complex CSS3 and XPath selectors, including things like the
28    ``nth-child`` pseudo-selector. You are advised to consult a good reference
29    if you are new to XPath and/or CSS3.
30
31Rule directives
32---------------
33
34The following directives are allowed inside the ``<rules />`` element in the
35rules file:
36
37``<theme />``
38~~~~~~~~~~~~~
39
40Used to specify the theme file. For example::
41
42    <theme href="theme.html" />
43
44Relative paths are resolved relative to the rules.xml file. For http/https
45urls, the ``--network`` switch must be supplied to the ``diazocompiler`` or
46``diazorun`` program.
47
48The following attributes are allowed:
49
50``href`` (required)
51    A reference to the theme HTML file, as either a relative or absolute
52    URL.
53``if``
54    Used to specify an arbitrary condition that must be true for this theme
55    reference to be used. More on this in the section on using multiple themes
56    later in this guide.
57``if-path``
58    Used to specify a URL path segment that must be matched by the current
59    request for this theme reference to be used. More on this in the section
60    on using multiple themes later in this guide.
61``if-content`` or ``css:if-content``
62    Used to specify an element that must be present in the content for this
63    theme reference to be used. More on this in the section on using multiple
64    themes later in this guide.
65
66``<notheme />``
67~~~~~~~~~~~~~~~
68
69Used to turn off all theming in certain conditions. For example::
70
71    <theme href="theme.html" />
72    <notheme css:if-content="body.rawpage" />
73
74Multiple ``<notheme />`` elements may be used. If the condition on any of
75them is true, the theme will be omitted. That is, they are logically or'd
76together.
77
78One or more of the following attributes are required:
79
80``if``
81    Used to specify an arbitrary condition for when to omit the theme.
82``if-path``
83    Used to specify a URL path segment that must be matched by the current
84    request for the theme to be omitted.
85``if-content`` or ``css:if-content``
86    Used to specify an element that must be present in the content for the
87    theme to be omitted.
88
89If more than one attribute is used, the condition of all must be true for the
90directive to take effect. That is, they are logically and'ed together.
91
92``<replace />``
93~~~~~~~~~~~~~~~
94
95Used to replace an element in the theme entirely with an element in the
96content. For example::
97
98    <replace theme="/html/head/title" content="/html/head/title"/>
99
100The (near-)equivalent using CSS selectors would be::
101
102    <replace css:theme="title" css:content="title"/>
103
104The result of either is that the ``<title />`` element in the theme is
105replaced with the ``<title />`` element in the (dynamic) content.
106
107The following attributes are allowed:
108
109``theme`` or ``theme-children`` or ``css:theme`` or ``css:theme-children`` (required)
110    Used to specify the node(s) in the theme that is to be replaced. When using
111    ``theme-children``, all elements inside the tag that matches the XPath
112    or CSS expression will be replaced, but the matched tag itself will remain
113    intact.
114``content`` or ``content-children`` or ``css:content`` or ``css:content-children`` (required)
115    Used to specify the node in the content that is to replace the matched
116    node(s) in the theme. When using ``content-children``, all elements inside
117    the tag that matches the XPath or CSS expression will be used, but the
118    matched tag itself will be left out.
119``attributes``
120    If you want to replace attributes instead of tags, you can use the
121    ``attributes`` attribute to provide a space-separated list of attributes
122    that should be replaced on the matched theme node(s). For example, with
123    ``attributes="class"`` the ``class`` attribute on the matched theme
124    node(s) will be replaced by the ``class`` attribute of the matched content
125    node(s).
126
127    **Note:** As with ``<replace />`` rules working on tags, if the named
128    attribute(s) do not exist on the both the theme and content nodes, nothing
129    will happen. If you want to copy attributes regardless of whether they
130    exist on the theme node(s) or not, you can use ``<copy />`` instead.
131
132    Using ``attributes="class id"``, the ``class`` and ``id`` attributes will
133    be replaced.
134
135    As a special case, you can write ``attributes="*"`` to drop all attributes
136    on the matched theme node and copy over all attributes from the matched
137    content node.
138
139    **Note:** You should not use ``theme-children`` or ``content-children``
140    or their CSS equivalents when using ``attributes``.
141
142    See also ``<merge />``, ``<copy />`` and ``<drop />``
143``method``
144    If you have any ``<drop />`` or other rules that manipulate the *content*,
145    and you do not want that manipulation to be taken into account when
146    performing this replacement, you can add ``method="raw"`` to the
147    ``<replace />`` rule.
148``if``
149    Used to specify an arbitrary condition for when to perform the
150    replacement.
151``if-path``
152    Used to specify a URL path segment that must be matched by the current
153    request for the replacement to be performed
154``if-content`` or ``css:if-content``
155    Used to specify an element that must be present in the content for the
156    replacement to be performed.
157
158For more advanced usage of ``<replace>``,
159see :ref:`modifying-the-theme-on-the-fly`
160and :ref:`modifying-the-content-on-the-fly`.
161
162``<before />`` and ``<after />``
163~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164
165These are equivalent to ``<replace />`` except that the node(s) matched in
166the content are inserted before or after the node(s) matched in the theme,
167respectively. For example::
168
169    <before css:theme="#content" css:content="#info-box" />
170
171This would place the element with id ``info-box`` from the content
172immediately before the element with id ``content`` in the theme. If we
173wanted the box below the content instead, we could do::
174
175    <after css:theme="#content" css:content="#info-box" />
176
177To insert the box immediately inside the ``#content`` node, before any of its
178existing children, we could do::
179
180    <before css:theme-children="#content" css:content="#info-box" />
181
182``<before />`` and ``<after />`` have the same required and optional
183attributes as ``<replace />``, except for ``attributes``, which is not
184supported.
185
186``<drop />``
187~~~~~~~~~~~~
188
189Used to drop elements from the theme or the content. This is the only
190element that accepts either ``theme`` or ``content`` attributes (or their
191``css:`` and ``-children`` equivalents), but not both::
192
193    <drop css:content="#portal-content .about-box" />
194    <replace css:theme-children="#content" css:content="#portal-content" />
195
196This would copy all children of the element with id ``portal-content`` in
197the theme  into the element with id ``content`` in the theme, but only
198after removing any element with class ``about-box`` inside the content
199element first.
200
201Similarly::
202
203    <drop theme="/html/head/base" />
204
205Would drop the ``<base />`` tag from the head of the theme.
206
207The following attributes are allowed:
208
209``theme`` or ``theme-children`` or ``css:theme`` or ``css:theme-children``
210    Used to specify the node(s) in the theme that is to be dropped. When using
211    ``theme-children``, all elements inside the tag that matches the XPath
212    or CSS expression will be dropped, but the matched tag itself will remain
213    intact.
214``content`` or ``content-children`` or ``css:content`` or ``css:content-children``
215     Used to specify the node(s) in the content that is to be dropped. When
216     using ``content-children``, all elements inside the tag that matches the
217     XPath or CSS expression will be dropped, but the matched tag itself will
218     remain intact.
219``attributes``
220    If you want to drop attributes instead of whole tags, you can use the
221    ``attributes`` attribute to provide a space-separated list of attributes
222    that should be dropped on the matched theme node(s). For example, with
223    ``attributes="class"`` the ``class`` attribute will be dropped from the
224    matched node(s). Using ``attributes="class id"``, the ``class`` and ``id``
225    attributes will both be dropped.
226
227    As a special case, you can write ``attributes="*"`` to drop all attributes
228    on the matched theme node.
229
230    **Note:** You should not use ``theme-children`` or ``content-children``
231    or their CSS equivalents when using ``attributes``.
232
233    See also ``<merge />`` and ``<replace />``
234``if``
235    Used to specify an arbitrary condition for when to perform the
236    drop.
237``if-path``
238    Used to specify a URL path segment that must be matched by the current
239    request for the drop to be performed
240``if-content`` or ``css:if-content``
241    Used to specify an element that must be present in the content for the
242    drop to be performed.
243
244``<strip />``
245~~~~~~~~~~~~~
246
247Used to strip a tag from the theme or content, leaving its children intact.
248You can think of this as the inverse of ``<drop />`` with ``theme-children``
249or ``content-children``. For example::
250
251    <strip css:theme="#content" />
252
253This will remove the element with id ``content``, leaving in place all its
254children.
255
256Similarly::
257
258    <strip css:content="#main-area .wrapper" />
259    <replace css:theme="#content-area" css:content="#main-area" />
260
261This will replace the theme's element with the id ``content-area`` with the
262element in the content that has the id ``main-area``, but will strip out any
263nested tags with the CSS class ``wrapper`` found inside ``#main-area``.
264
265``<strip />`` uses the same attributes and semantics as ``<drop />``.
266
267``<merge />``
268~~~~~~~~~~~~~
269
270Used to merge the values of attributes in the content with attributes with the
271same name in the theme. This is mainly useful for merging CSS classes::
272
273    <merge attributes="class" css:theme="body" css:content="body" />
274
275If the theme has the following body tag::
276
277    <body class="alpha beta">
278
279and the content has::
280
281    <body class="delta gamma">
282
283then the result will be::
284
285    <body class="alpha beta delta gamma">
286
287The following attributes are allowed:
288
289``attributes`` (required)
290    A space-separated list of attributes to merge. A given attribute must
291    exist on both the theme and the content nodes for the rule to have any
292    effect.
293``theme`` or ``css:theme`` (required)
294    The theme node(s) to merge the attribute value(s) with.
295``content`` (required)
296    The content node(s) to merge the attribute value(s) from.
297``separator``
298    The separator to use when merging attributes. The default is to use
299    a space. Use ``separator=""`` to merge with no separator.
300``if``
301    Used to specify an arbitrary condition for when to perform the
302    merge.
303``if-path``
304    Used to specify a URL path segment that must be matched by the current
305    request for the merge to be performed
306``if-content`` or ``css:if-content``
307    Used to specify an element that must be present in the content for the
308    merge to be performed.
309
310``<copy />``
311~~~~~~~~~~~~
312
313Used to copy an attribute from a node in the content to a node in the theme.
314Unlike ``<replace />``, ``<copy />`` will work even if the attribute does
315not exist on the target theme node. If it *does* exist, it will be replaced.
316For example::
317
318    <copy attributes="class" css:theme="body" css:content="body"/>
319
320The following attributes are allowed:
321
322``theme`` or ``css:theme`` (required)
323    Used to specify the node(s) in the theme where the attribute should be
324    copied.
325``content`` or ``css:content`` (required)
326    Used to specify the node(s) in the content from which the attribute should
327    be copied.
328``attributes`` (required)
329    A space-separated list of attributes that should be copied to the theme.
330
331    As a special case, you can write ``attributes="*"`` to drop all attributes
332    on the matched theme node and copy over all attributes from the matched
333    content node.
334``if``
335    Used to specify an arbitrary condition for when to perform the
336    copy.
337``if-path``
338    Used to specify a URL path segment that must be matched by the current
339    request for the copy to be performed
340``if-content`` or ``css:if-content``
341    Used to specify an element that must be present in the content for the
342    copy to be performed.
343
344Order of rule execution
345-----------------------
346
347In most cases, you should not care too much about the inner workings of the
348Diazo compiler. However, it can sometimes be useful to understand the order
349in which rules are applied.
350
3511. ``<before />`` rules using ``theme`` (but not ``theme-children``) are
352   always executed first.
3532. ``<drop />`` rules are executed next.
3543. ``<replace />`` rules using ``theme`` (but not ``theme-children``) are
355   executed next, provided no ``<drop />`` rule was applied to the same theme
356   node or ``method="raw"`` was used.
3574. ``<strip />`` rules are executed next. Note that ``<strip />`` rules do
358   not prevent other rules from firing, even if the content or theme node
359   is going to be stripped.
3605. Rules that operate on attributes.
3616. ``<before />`` and ``<replace />`` and ``<after />`` rules using
362   ``theme-children`` execute next, provided no ``<replace />`` rule using
363   ``theme`` was applied to the same theme node previously.
3647. ``<after />`` rules using ``theme`` (but not ``theme-children``) are
365   executed last.
366
367Behaviour if theme or content is not matched
368--------------------------------------------
369
370If a rule does not match the theme (whether or not it matches the content),
371it is silently ignored.
372
373If a ``<replace />`` rule matches the theme, but not the content, the matched
374element will be dropped in the theme::
375
376    <replace css:theme="#header" content="#header-element" />
377
378Here, if the element with id ``header-element`` is not found in the content,
379the placeholder with id ``header`` in the theme is removed.
380
381Similarly, the contents of a theme node matched with a ``<copy />`` rule will
382be dropped if there is no matching content. Another way to think of this is
383that if no content node is matched, Diazo uses an empty nodeset when copying
384or replacing.
385
386If you want the placeholder to stay put in the case of a missing content node,
387you can make this a conditional rule::
388
389    <replace css:theme="#header" content="#header-element" if-content="" />
390
391See the next section for more details on conditional rules.