Freemarker - assign expression within quotes - freemarker

How to put ${expression} within double quotes like this?
for example:<User name="" >
I tried with following but it doesn't work:
<User name="${expression}" > get evaluation error
<User name="${r"${expression}"}" > get <User name="${expression}" >, not the assigned value
Thanks.

You can use ?html
<Table name="${expression?html}" >
Or auto-escaping mechanism
<#ftl output_format="HTML">
This built-in is deprecated by the auto-escaping mechanism introduced in 2.3.24
Or escape
<#escape x as x?html>
<Table name="${expression}" >
</#escape>

Related

Stripping of white space seems broken

I am moving some XSLT templates to freemarker due to better Java compatibility but freemarker seems to have issues with handling whitespace. XML ends up with white space all over the place like this:
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row> <fo:table-cell
> <fo:block >
<fo:inline font-weight="bold"
I have tried adding the strip_whitespace=true directive but it has no effect. It is the default so it is probably already meant to be working.
In XSLT all white space between XML blocks is collapsed. This is made easier by placing any free text needs inside an <xsl:text> example text including padding </xsl:text> element.
It seems that freemarker lacks control over the text nodes and there is no way to collapse the whitespace.
UPDATE: here is an example of a portion of the freemarker template where it generates the fo:table-cell
<#macro tableHeaderM tableHeader>
<#list tableHeader.columns as column><#columnM column=column /></#list>
</#macro>
<#macro columnM column>
<fo:table-column column-width="${column.width}cm" />
</#macro>
<#macro rowM row table>
<fo:table-row><#list row.cells as cell><#cellM cell=cell table=table /></#list></fo:table-row>
</#macro>
<#macro cellM cell table>
<fo:table-cell<#cellFormattingM cell=cell table=table />><#blockObjectsM blockObjects=cell.blockObjects /></fo:table-cell>
</#macro>
<#macro cellFormattingM cell table>
<#if cell.border == true> border="0.1mm solid"</#if>
<#if cell.pad == true> padding="3pt"</#if>
<#if cell.shade == true> background-color="#eeeeee"</#if>
<#if table.collapse == true> margin-top="5px"</#if>
</#macro>
The white-space stripping and trimming in FreeMarker is solely for removing white-space that's present in the template itself (i.e., white-space added for source code formatting). The white-space in your case is present in the data-model. Unfortunately, you need to pre-process the DOM to get rid of those (or insert with ?trim and such). The FreeMarker DOM wrapper doesn't know which whitespace is insignificant.
Update (since the white-space doesn't come from the DOM):
strip_whitespace (white-space stripping) is by default true, so adding that won't remove more white-space. So your best bet is using <#t> (and maybe <#rt> and <#lt>) to remove more white-space explicitly.

JSTL <c:if> tag to compare two variables

Why the block never reaches "conditionTrue"? I have printed both the variables
authorEmail and scase.authorEmail and they are same string. If I use literal like 'abc#yahoo.com' to test the condition , it works but not if both the c:if params are variables.
<c:forEach var="scase" items="${section.subSectionList.get(0).SCaseList}">
<c:set var="authorEmail" >
<sec:authentication property="principal.email" />
</c:set>
<c:if test = "${authorEmail == scase.authorEmail}" >
<option>conditionTrue</option>
</c:if>
</c:forEach>
UPDATE - I got it to work by making these changes.
I commented out the entire c:set tag. Instead I added these line -
<sec:authentication var="principal" property="principal" />
My test condition was then :
<c:if test = "${principal.email == scase.authorEmail}" >
<option>conditionTrue</option>
</c:if>
And this worked. However, the reasoning behind it still baffles me. Any insight, much appreciated.

using mule variable value in xpath expression

I have a variable set as
<set-variable variableName="productIdvar" value="#[xpath://productId]" doc:name="Variable" />
On logging its coming right,
I want to use the value of the variable productIdvar in my xpath expression,
<when expression="//*[local-name()='itemid']=?" evaluator="xpath">
or
<when expression="#[xpath://*[local-name()='itemid']=?]">
What should i use in place of ? to get the value of the variable?
Thanks
Rahul.
The following expression should work for you.
<when expression="#[xpath('//*[local-name()=\'itemid\']').text == productIdvar ]">
This way you should be able to compare the result of the xpath with the "productIdVar" variable.
Hope this helps.
<when expression="#[xpath('//*[local-name()=itemid]') == productIdvar ]">
Note that there are no quotation marks surrounding itemid in expression
If your MEL gets a bit messy, try my mule-module-dxpath - an XPath transformer which dynamicaly resolves XPath variables.
You can use XPATH3 and try something like this
#[xpath3('/products/validlity')== flowVars.productIdvar]
Xpath3 reference :- https://developer.mulesoft.com/docs/display/current/XPath

JSTL: I need to access hashtable using a key

I know this works: <c:out value="${model.testhash['A']}"/>
but I need something like:
<c:out value="${model.testhash[${model.testkey}]}"/>
Is this possible?
Have you tried
${model.testhash[model.testkey]}
In general the ${ } only delineates the JSTL expression, you don't need to escape the lookup for the model.testkey lookup as well, so it is also possible to do:
${model.testhash[model.condition ? 'A' : 'B']}
.. just as an example.

(ruby) help matching my regular expression

I am trying to match the value of the following HTML snippet:
<input name="example" type="hidden" value="matchTextHere" />
with the following:
x = response.match(/<input name="example" type="hidden" value="^.+$" \/>/)[0]
why is this not working? it doesn't match 'matchTextHere'
edit:
when i use:
x = response.match(/<input name="example" type="hidden" value="(.+)" \/>/)[0]
it matches the whole html element, and not just the value 'matchTextHere'
^ matches start of a line and $ matches end of the line. Change ^.+$ to \w+ and it will work for values that doesn't contain any symbols. Make it a parenthetical group to capture the value - (\w+)
Update: to match anything between the quotes (assuming that there aren't any quotes in the value), use [^"]+. If there are escaped quotes in the value, it is a different ballgame. .+ will work in this case, but it will be slower due to backtracking. .+ first matches upto the end of the string (because . matches even a "), then looks for a " and fails. Then it comes back one position and looks for a " and fails again - and so on until it finds the " - if there was one more attribute after value, then you will get matchTextHere" nextAttr="something as the match.
x = response.match(/<input name="example" type="hidden" value="([^"]+)" \/>/)[1]
That being said, the regex will fail if there is an extra space between any of the attribute values. Parsing html with regex is not a good idea - and if you must use regex, you can allow extra spaces using \s+
/<input\s+name="example"\s+type="hidden"\s+value="([^"]+)"\s*\/>/
Because you have a start-of-line token (^) and an end-of-line token ($) in your regular expression. I think you meant to capture the value, this might solve your problem: value="(.+?)".
Beware, though, that processing html with regular expressions is not a good idea, it can even drive you crazy. Better use an html parser instead.
You don't need the ^ and $:
x = response.match(/<input name="example" type="hidden" value=".+" \/>/)[0]
you just need to change [0] to [1]
response='<input name="example" type="hidden" value="matchTextHere" />'
puts response.match(/<input name="example" type="hidden" value="(.*?)" \/>/)[1]
matchTextHere

Resources