Pause interpolation of template string in FTL - macros

I want to pass a dynamic string to FTL Macro. But I don't want the template string to be interpolated when I am calling the macro from FTL. I want the template string to be interpolated inside Macro only. So that I can make the Macro reusable by sending dynamic Template strings as parameter. As I am new to Apache FTL so I don't have much idea how to proceed.

Not sure what do you want to achieve, but I guess something like this:
<#macro m s>
<#local parsedS = s?interpret>
<#list ['John Doe', 'Jane Doe'] as name>
<p><#parsedS />
</#list>
</#macro>
<#m r"Hello ${name}!" />
which will print:
<p>Hello John Doe!
<p>Hello Jane Doe!
Some notes:
I haven't just used the parameter as a string with an interpolation,
but as an template fragment (so that auto-escaping, if you use it,
will be applied, also you could use #if and such in the value of
s).
As the template fragment is evaluated for multiple types in my
example, I have assigned the result of ?interpret to a local
variable, otherwise you could just write <#s?interpret />.
As of
the r before the string literal, that tells FreeMarker that ${}
(and \ escapes) must not be interpreted.

Related

AEM6.5 Passing paramater to the resource from HTL/Sightly template

I have a component that uses two different resources in its HTL/Sightly template.
Is there a way to pass a parameter, to the say in my example the eventResource template, so that I can depending on this passed paramter change a css class on it?
<ul data-sly-list.teasers="${model.resourceList}" class="teaser-list-alternating c-list--reset">
<sly data-sly-test="${teasers.eventTeaser}"
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser'}"></sly>
<li data-sly-test="${teasers.contentTeaser}" class="l-stack l-stack--horse"
data-component-hook-content-hub="teaser"
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/contentHubTeaser'}"></li>
</ul>
I tried using data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser', requestAttributes=model.config, selectors='blabla'} to no availability.
#RequestAttribute(name = "contentHub")
private String contentHub;
The requestAttribute contentHub in the eventTeaser model is alway null and I am not sure how to get the selectors value in the eventTeaser template.
I can do it using TypeScript on the front end part but it is not very clean.
I was able to solve it using the selectors indeed and reading the selector value directly from the other sightly template. Here is the documentation I refered to:
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser', requestAttributes=model.config, selectors='inContentHub'}
 In the eventTeaser template I then used the following:
data-sly-set.inContentHub="${'inContentHub' == request.requestPathInfo.selectorString}
and depending on the value of the inContentHub variable I was able to change the css class which was my ultimate goal.

How can I pass a play template scala variable as input to a scala function?

Im not sure if i got the nomenclature right in the title of my question, Im new to play. Basically I wanted to break my html template by calling 2 sub-templates ( passing to them as argument an sub-object from the main template).
So my main template would be
#* patientInfoFrame Template File *#
#(alarm: Alarm)
#import helper._
#* Caller part *#
#calleInfoTemplate(#alarm.callee)
#* Patient part *#
#patientInfoTemplate(#alarm.patient)
where I receive an Alarm object as variable and would build part of the page by calling a second template calleInfoTemplate with a sub-object from the Alarm object and then a third template patientInfoTemplatewith another sub-object.
If I try to compile that it fails saying that #alarm.callee is an illegal start of simple expression.
How can I pass those sub-objects as input to the other templates?
You don't need the # escape character on your variables in this case because you are already inside a dynamic statement (the template call).
#* Caller part *#
#calleInfoTemplate(alarm.callee)
#* Patient part *#
#patientInfoTemplate(alarm.patient)

Why bindings do not work?

<textbox id="nextTitleTextbox" readonly="true" value="#bind(ivm.inventory.successorTitleName)" />
<button id="nextTitleButton" label="..." mold="trendy" onClick="#command('chooseFormerOrSuccessor', isFormer = false)"/>
<a id="nextTitleHrefView" href="/inventory_new.do?method=edit&docUID=${ivm.inventory.successorTitleName}">view</a>
<a id="nextTitleHrefHistory" href="javascript:showRenamingHistory(${ivm.inventory.successorTitleName},${ivm.inventory.successorTitleName})">history</a>
The problem is in 'a' tags. Textbox and buttons works fine, but links in 'a' tags do not catch information from binding, so link there looks like /inventory_new.do?method=edit&docUID=. I really don't understand what's wrong here, because I tried a lot of combination and something similar is working on other pages. Where is mistake in this binding?
I even tried to put string from zscript
<zscript>
String successorTitleHref = "/inventory_new.do?method=edit&docUID=" + ivm.inventory.successorTitleName;
</zscript>
But got exception:
Typed variable declaration : Class or variable not found: ivm.inventory.replacementTitleName.
Also, it's supported controls, that locates in separate file, and every control adding with use derective.
Binding in ZK has nothing to do with variable replacement. #bind() doesn't mean you can use ${...}. The two are completely separate concepts even though both are called "EL Expression" in the manual. But binding EL Expression and ZUML EL Expressions are two different things.
To allow access to ivm in a zscript, you need to define this variable somewhere in the script. One way is to instantiate it:
IVM ivm = new IVM();
or you can use a custom variable resolver.

TYPO3: use fluid's date view helper inline as argument for translate view helper

I am currently developing some extensions to use within TYPO3 6.
In one view I have database records with date fields. I can output the date values with the following:
<f:format.date format="d.m.Y H:i:s">{record.validend}</f:format.date>
However, I need a translated message, so I would like to use the translate view helper and put the formatted date in the arguments attribute. Without succes so far.
I tried:
<f:translate key="{msg_id}" arguments="{0: code, 1: {f:format.date(date: record.validend, format: 'd.m.Y H:i:s')}}" htmlEscape="0" />
…and…
<f:translate key="{msg_id}" arguments="{0: code, 1: {record.validend -> f:format.date(format: 'd.m.Y H:i:s')}}" htmlEscape="0" />
…following this guide: http://forge.typo3.org/projects/typo3v4-mvc/wiki/Fluid_Inline_Notation
However, there seems to be some syntax error in my notation forcing fluid to interpret the whole thing as a string, resulting in an error, cause the arguments attribut is expected to be an array.
Could anyone tell me if what I want is possible, and what syntax I need?
best regards
Christian
You need to escape the quotes of format with backslashes.
The solution is:
<f:translate key="{msg_id}" arguments="{0: code, 1: '{f:format.date(date: record.validend, format: \'d.m.Y H:i:s\')}'}" htmlEscape="false" />
The right way to use format.date as variable is:
{f:format.date(format : 'd-m-Y H:i:s', date : '#1368093280')}
I tested your request and it seems that it isnt possible to call a ViewHelper inside the argument arguments of a ViewHelper.
So you should try something else like a custom ViewHelper or format your date in the controller so you have a variable that contains the formatted date:
{f:translate(key : msg.id, arguments : {0 : msg.date})}

Get the last element in list with helper

I am passing a list to my scala page and I have a form and I would like to set some default values to the last element in the list: Something like the below:
System Name: <input type="text" id="systemSourceName" name="systemSourceName" value="#configs[#configs.size() - 1].systemSourceName" >
But it throws an error at the second #:
identifier expected but '#' found.
Is there a way I can do this?
Use round brackets, square brackets are for type parameters
There is no need for second #, parser knows that he is already inside scala expression.
It is better to use built-in method of List class:
value="#configs.last.systemSourceName"
Scala doesn't access list elements via list[index] but via list(index).
So the following should work:
value="#configs(configs.size - 1).systemSourceName"
An easier solution would be
value="#configs.last.systemSourceName"