-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal for conditional processing improvements to eXist's HTML Templating Library #20
Comments
Hey @yamahito 👋, Thank you for opening an issue. We will get back to you as soon as we can. Have you seen our Open Collective page? Please consider contributing financially to our project. This will help us involve more contributors and get to issues like yours faster. https://opencollective.com/existdb
|
This is a valuable addition to the core templating library and will be included in the next major version. |
The one thing we need to look at closely: let $key := substring-after(
local-name($attr), $templates:ATTR_DATA_TEMPLATE || "-") |
One alternative approach given that placeholders are expanded from model entries in attributes before the <a data-template="my:tpl-func" data-template-use-when="${link}" href="${link}">${text}</a> |
Agreed, or else decide to use a different |
@yamahito Yes, do you have a proposal for an alternative? What I would want to achieve is that filtering out all templating specific attributes is easy and reliable. All the while it is pleasant and understandable to edit those templates. |
Maybe it is safer to use non-HTML5-compliant attributes. If those are filtered out by default we achieve two goals:
Example: Change the parameter attribute prefix to <a tpl-func="my:tpl-func" tpl-use-when="${link}" href="${link}">${text}</a>
<span tpl-use-unless="${link}">${nolink-text}</span> |
If we leave the convention that all data attributes that become a function parameter e.g. My gut feeling is that if we are using non-HTML5-compliant attributes at all, it should be offered as an addition to the |
With the approach to directly use model-properties we need to agree how to handle items that do not have an effective boolean value such as maps, functions and sequences. |
I am not in favour of the use of model properties directly: I think the strength of the templating system is that it refers to xquery functions, and this proposal attempts to build on that. |
It is definitely more versatile and allows to specify arbitrary conditions. |
I would still propose to add one or maybe two simple tests that are generally useful <a tpl-func="my:tpl-func" tpl-if-exists="${link}" href="${link}">${text}</a>
<span tpl-if-empty="${link}">${nolink-text}</span> |
I have updated this paragraph above to clarify that I am reluctant to move away from data attributes - the wording as quoted was unclear! The best alternative to data attributes, IMO, is to use namespaced elements in the templates XML format, and ensure that these are completely removed by the templating engine when it renders them as HTML... |
If we had two tests, |
The placeholder ( |
Yes! I had originally included I take your point about being unable to differentiate between string values and function references. It brings me back to feeling that we should stick to functions that return boolean values, particularly when considering effective boolean values of functions etc. If we allowed specification of arguments by function position as well as by argument name, could we do something like: <a data-template="my:tpl-func" data-template-use-when="exists" data-arg1-template="${link}" href="${link}">${text}</a> |
I like the general idea. Being able to use built-in functions can have great potential. In order to be able to differentiate both the template function parameters from the test function parameters those attributes should clearly communicate what they are for, best be grouped by prefixes. With a template function/handler/renderer declare function my:translated-label ($node, $model, $lang) {
map:put($model, "text", "translated link text")
}; <a data-template-handler="my:translated-label"
data-template-handler-argument-lang="en"
data-template-use-when="exists"
data-template-use-when-argument-arg="${link}">${text}</a>
We are also deviating from your original proposal quite a lot, that was compelling because of its simplicity. <a data-template-handler="my:translated-label"
data-template-handler-argument-lang="en"
data-template-use-when-exists="${link}">${text}</a> Since those tests are already part of the templating library, but only as template handling functions communicating this concept would be easier as we can refer to those and explain why it is List of current conditional template handlers:
I oppose opening up |
closes eXist-db#20 `<a data-template-when="my:test"></a>` will only be rendered when the call to `my:test($node, $model)` evaluates to `true()`. Can be used in combination with data-template, the template function will only run if the template is actually rendered.
This is a very good point, I think I agree on the other points as well. Thanks for all of your consideration on this. |
This proposal sets out the case for adding convenience features to eXist's HTML Templating Library which will both simplify conditionally including content in the templates themselves, as well as testing using frameworks such as XQsuite.
Current methods for conditionally including content:
Currently, it is possible to conditionally include content in templates by writing an XQuery function, and including it as a
@data-template
:The conditional logic is then held in an XQuery function, alongside the function that actually generates the content:
Note that it is necessary to recurse the templates processing using
templates:process
in the event that recursion is required. This makes writing tests cumbersome (particularly the first, below):As well as the test for
eg:when-link
, I include the test foreg:link-href
for reasons which will hopefully become obvious later on.templates:if-parameter-set
andtemplates:if-parameter-unset
The Templating library does include these tools for conditional processing already; the reader why ask, why these aren't sufficient?
There are two reasons:
$model
map, calculated using XQuery, or retrieved directly from the eXist database....parameter-set
features are set using the@data-templates
attribute; this means that an additional, redundant wrapping element is needed in addition to any content in the template that is populated using XQuery.Proposed changes
We propose the addition of templating attributes
@data-template-use-when
and@data-template-use-unless
to conditionally include or exclude content.The attributes cause a function to be called using the same methods as
@data-template
; however, rather than use the results of the function to update the$model
map or HTML page, the effective boolean value is used to control whether or not further processing takes place.The use-when/use-unless attribute is used independantly of
@data-template
, so that either or both attributes may be specified on a template element.@data-template
is only called where the condition is satisfied.The example from the last session becomes:
The
eg:when-link
function is removed, and the testing burden is almost entirely eliminated: the existing testing foreg:link-href
is sufficient.Even if a different condition were needed instead of the function that we are using to populate, the tests for that conditional function would simply need to test the effective boolean value, and not the cumbersome resolver config.
Implementation suggestion
Implementation should be fairly straightforward; we can check for conditional attributes before during templates processing:
Further considerations
If desirable, it should be possible to allow multiple conditions as a space separated list of QNames for each of the proposed attributes. This could allow for some sophisticated mechanisms for choosing layouts based on more than simple binary choices.
The text was updated successfully, but these errors were encountered: