does any template engine like Freemarker support customized constraints? - constraints

I want to use template to render my output, just like Freemarker does, but I want to add customized constraints, for example, ${name}[length > 4 && notEmpty], ${name} is a variable, expression in [] is customized expression, "length > 4" means ${name}.legnth is greater than 4, "notEmpty" means ${name} is not null nor "", if these constraints do not return true, template engine can stop rendering with throwing an exception or do something else. Every variable in template may have its own constraints, and I don't want to write too many [#if][/#if] tags(it seems that Freemarker does not support stopping rendering if [#if] returns false). I just search Freemarker, it doesn't support, do you know any other template engine can meet my demand?
thanks.

Related

TYPO3 Symfony Expression: isset() for Query Parameters?

I am using several Symfony expressions in my TypoScript checking for query parameters such as this:
[request.getQueryParams()['tx_news_pi1']['news'] > 0]
do something
[END]
This is working well – as long as the query parameter exists. If it doesn’t, the following error message is written into the log file:
Unable to get an item on a non-array.
In PHP I would use isset() to check whether the query parameter exists – but I could not find a similar way for Symfony expressions in TypoScript. I have tried
[request.getQueryParams()['tx_news_pi1']['news']]
which works the same, meaning: it does what it’s supposed to do, but logs an error message if the query parameter does not exist.
Is there anything like isset() for the Symfony Expression Language in TYPO3?
The is_defined() or isset() I was looking for will be returned by the condition
[request.getQueryParams()['tx_news_pi1']]
instead of
[request.getQueryParams()['tx_news_pi1']['news']]
In my use case this would even be enough. If you need to be more precise (e.g. to differentiate between different query parameters within the same plugin), go for
[request.getQueryParams()['tx_news_pi1'] && request.getQueryParams()['tx_news_pi1']['news'] > 0]
The solution was provided as a reply to a bug report on forge.typo3.org
Try this:
[request.getQueryParams()['tx_news_pi1']['news'] = ]
do something
[END]

Sort form field choices by translated labels

I have an array:
[
0 => 'translate.label1',
1 => 'translate.label2',
2 => 'translate.label1'
]
which I specify as a choices param for field creation.
Now, is it possible to sort these options by translated labels? For example, label1 translated value is zero, label2 - something, label3 - abracadabra. Of course, I expect select options to be:
abracadabra
something
zero
I thought to use this approach: https://stackoverflow.com/a/21586886/2324004
But doesn't it involve second translator digest inside view? Any ideas? I'd rather to use something more flexible because my form is based on non-fixed selects count and it would have executed something recursive...
You have to do it in js after data will be uploaded.
Check this topic:
Javascript to sort contents of select element
Due to fact the translation occurs inside Twig view, the only solution (right now I'm aware) is to prepare translated and sorted list during form build process by injecting manually TranslatorInterface service.
Unfortunately, without overriding widget's template, translation occurs second time, against already translated labels.

How can one detect transclusion depth?

In MediaWiki, is there a standard pattern that you can include in a template body to detect depth of transclusion?
Specifically, let's assume
Template:Myinfobox
contains such a pattern that displays "native myinfobox call" for depth 1 transclusion and "transclusion call" otherwise.
Then, if page
Mypage
calls
{{Myinfobox}}
it should display "native myinfobox call" while any page that calls
{{Mypage}}
should display "transclusion call"
Does anyone know such a pattern that does not require the writer of
Mypage
to insert special markup or <noinclude> or <includeonly> tags?
No, there is no such thing. However, you can learn some evil tricks and internals on expansion depth limits and branching at
https://meta.wikimedia.org/wiki/Help:Advanced_templates
https://meta.wikimedia.org/wiki/Help:Expansion_depth
https://meta.wikimedia.org/wiki/Help:Substitution#Multilevel_substitution
Thanks for the pointers. I was aware of these but it's good to have them here. Right now I'm resorting to the following trick (using the terminology of my question): I have a home article parameter in the Myinfobox that the user of the template must set to the name of the page hosting the Myinfobox direct call. Thus Mypage will contain something like:
{{ Myinfobox | … | home article = Mypage | … }}
The Myinfobox template tests whether {{PAGENAME}} equals {{{ home article }}} to determine the message it outputs: "transclusion" in case the 2 values are different, "native" otherwise.
But this is clumsy and places burden on the template user.

How do I escape ${} in my Tridion Component Template that is consumed by multiple templates?

I am running into a situation where I have a fied with the value ${test}, in my component template that renders this the value comes out ok the problem comes in when another template calls this component and templates using ##RenderComponentPresentation(Component.ID, MyFirstTemplate)## at this point the ${test} is evaluated and because there is no such item on the component or in the package it evaluates to nothing.
I have Component Template One that reads the value of a Component field (which contains: ${test})
This template renders fine, I get back "${test}"
Now I have Component Template Two that calls ##RenderComponentPresentation(Component.ID, ComponentTemplateOne.ID)##
This is where the ${test} now gets evaluated instead of retained so it goes from ${test} to "" because it doesn't find a variable or component field name with that name.
Component Template Two then gets called by Component Template Three in the same way ##RenderComponentPresentation(Component2.ID, ComponentTemplateTwo.ID)##
Since the ${test} has already been evaluated and lost in Component Template Two I no longer end up with ${test} I am still left with "".
I have tried:
##RenderComponentField('myField', 0, False, False)##
##RenderComponentField('myField', 0, True, False)##
##RenderComponentField('myField', 0, False, True)##
no luck.
The following was my work around and it seems to work:
Placing the "\" in front of both the open and close curly brace $\{test\}
I need to make sure I remove the "\" after the last Template (Page or Component) executes.
I have in place now a C# TBB that takes the "${test}" and does the following to it:
Converts the ${test} to $\{test\} in the initial template and a C# TBB on the Page Template that then returns it to the initial value of ${test}.
Is there a way to prevent this from happening or a way to avoid doing what i am doing to make this work?
Have you tried this link , you should be able to this with this link
##"$" + "{" + "test" + "}"##

XQuery Update: insert or replace depending if node exists not possible?

I am trying to build simple XML database (inside BaseX or eXist-db), but I have trouble figuring how to modify values in document :
content is simple as this for test :
<p>
<pl>
<id>6></id>
</pl>
</p>
I am trying to build something like function which would insert element into <pl> if that element is not present or replace it if it is present. But XQuery is giving me troubles yet :
When I try it head-on with if-then-else logic :
if (exists(/p/pl[id=6]/name)=false)
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'
I get error Error: [XUDY0027] Replace target must not be empty. Clearly I am confused, why the else part is evaluated in both cases, thus the error.
When I empty out the else part :
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
Then I get Error: [XUST0001] If expression: no updating expression allowed.
When I try through declaring updating function, even then it reports error :
declare namespace testa='test';
declare updating function testa:bid($a, $b)
{
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
};
testa:bid(0,0)
Error: [XUST0001] If expression: no updating expression allowed.
I've got these errors from BaseX 6.5.1 package.
So how can I modify values in a simple fashion if possible ?
If I call insert straight, the there could be multiple elements of same value.
If I call replace it will fail when the node does not exist.
If I delete the node before insert/replace then I could destroy sub-nodes which I don't want.
In most SQL databases, these are quite simple task (like MYSQL 'replace' command).
#Qiqi: #Alejandro is right. Your if expression is incorrect XQuery syntax:
if (exists(/p/pl[id=6]/name))
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'
Note that eXist-db's XQuery Update functionality is currently an eXist-specific implementation, so in eXist (currently) 1.4.x and 1.5dev, you'll want:
if (exists(/p/pl[id=6]/name))
then update insert <name>thenname</name> into /p/pl[id=6]
else update value /p/pl[id=6]/name with 'elsename'
This eXist-specific XQuery Update syntax is documented on http://exist-db.org/update_ext.html. This syntax was developed before the W3C XQuery Update spec had reached its current state. The eXist team plans to make eXist fully compliant with the W3C spec soon, but in the meantime the docs above should help you achieve what you need to if you use eXist.
Note too that your example code contains a typo inside the pl and id elements. The valid XML version would be:
<p>
<pl>
<id>6</id>
</pl>
</p>

Resources