In my Spring Controller I set following to my model attribute:
model.addAttribute("abc-def", "Hello World");
In my thymeleaf html I want to read the value of abc-def.
<th:block th:text="${abc-def}"></th:block>
But I get the error:
The operator 'SUBTRACT' is not supported between objects of type 'null' and 'null'
Its clear because - is an arithmetic operator. Is there a way to escape - for reading out the model value?
My advice would be: don't use variables names with dashes in them. (Would you try to define a variable int abc-def = 5; in java?)
In any case, this seems to work if you have to use it:
<th:block th:text="${#request.getAttribute('abc-def')}" />
Thymeleaf 2
Per the Expression Basic Objects section of the documentation (with more details in Appendix A), the context variables are in a #vars object. So, you can access variables with something like this:
<th:block th:text="${#vars.get('abc-def')}" />
Thymeleaf 3
As Metroids commented this all changes in Thymeleaf 3. It combines the #ctx and #vars objects, so you need to use the Context's getVariable method:
<th:block th:text="${#ctx.getVariable('abc-def')}" />
But this isn't the best plan
While certainly these will "work", having variables with punctuation in them is a bit unusual, and may confuse the next programmer to see your code. I wouldn't do it unless I had a really good reason to use that name.
Related
I am trying to condtionally create a component using #ConditionalOnExpression("not ${service.synchronous} && not ${service.disabled}").
I based this on Spring Boot SpEL ConditionalOnExpression check multiple properties, which provides a multi-property conditional as follows: #ConditionalOnExpression("${properties.first.property.enable:true} && ${properties.second.property.startServer:false}")
However, I keep getting:
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
Those properties are always set in my .properties file so I did not provide a default value with the colon notation. What am I doing wrong?
You will need to provide the default values for your properties like in the example you followed, so update the expression to be:
#ConditionalOnExpression("not ${service.synchronous:false} && not ${service.disabled:true}")
In most such cases the properties your app is reading are not what you expect them to be.
Set a breakpoint on all constructors of SpelParseException. In the debugger you will see the expression that is parsed, that will give show you exactly which properties you are really using.
Maybe you have to go search a little in the stack until you find the right location where you can see the expression.
My mistake was that I had not imported the test properties file in a Spring test.
After I added #TestPropertySource("classpath:/application.properties") to the test class, the properties from the properties file were used.
I am implementing a freemarker code in an environment that stores the templates in an database.
for example
${bundle.key}
will display the value of the row with row_id = 'key'
However when I use include directive something doesn't work.
I have a template with a key GenF as follows
<#function PriceFormat Number>
<#return Number?string['0.0000']>
</#function>
if i run
${GenF.PriceFormat(1.568)}
I get the output
1.5680
as expected.
but when i run
<#include bundle.GenF>
${PriceFormat(1.568)}
I receive an error message:
Can't find resource for bundle ...structures.shared.localization.bl.MultiResourceBundle, key
do I use the include directive wrong, or is something was not defined correctly in the Data model by our programmers?
#include expects the name
(path, "file" name) of a template, not the template content itself. See: https://freemarker.apache.org/docs/ref_directive_include.html
What you seem to want is <#bundle.GenF?interpret />. Though note that the parsed template won't be cached that way, unlike when you invoke a template with #include. For #include to be able to resolve "bundle.GenF" as template name (or rather something like "bundle:/GenF", but it's up to you), you have to use a custom TemplateLoader (see Configuration.setTemplateLoader).
As far as you only need this for defining custom number formats, you may also want to consider using custom number formats (https://freemarker.apache.org/docs/pgui_config_custom_formats.html), like ${1.538?string.#bundle_GenF}.
I have camel routes that make rest calls based on header values.
I had been using xpath to read values from xml and set them as the header and used xpath in a block as so:
<camel:setHeader headerName="clear">
<xpath>/TicketInfo/TicketData/Clear/text()</xpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but now I am forced to use json so xpath will not work. I now have:
<camel:setHeader headerName="clear">
<camel:jsonpath>$.ticket.Type</camel:jsonpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but obviously the <camel:xpath>$clear='CLEARED'</camel:xpath> part won't work anymore. Is there another way I can check the value of $clear header to restrict when the <camel:doTry> and following execute?
Try the simple language :
<camel:when>
<camel:simple>${in.header.clear} == 'CLEARED'</camel:simple>
<camel:doTry>
See this documentation
Just curious if this is possible.
Given some template:
<body>
<title>{{title}}</title>
<h1>{{description}}</h1>
</body>
How could you evaluate a Ruby expression in place of {{description}}?
The second sentence in Mustache page:
"It emphasizes separating logic from presentation: it is impossible to embed application logic in this template language."
If you want a more "dynamic" field, you need to define it on the object being rendered, not in the template.
Look for the taxed_value example a bit down the page to illustrate how to embed custom expressions:
class Simple < Mustache
# ...
def taxed_value
value * 0.6
end
# ...
end
I have recently found out that Smarty, differently from Django template engine, does not escape variables automatically and I need to put |escape next to most of the variables in my templates.
Following the docs, http://www.smarty.net/docsv2/en/variable.default.modifiers.tpl I need to set default modifiers, needn't I?
So, here's my code:
$smarty = new Smarty();
$smarty->default_modifiers = array('escape:"htmlall"');
... and still variables ARE NOT escaped until I add |escape next to them.
What am I doing wrong?
If you are on Smarty 3, try this:
$smarty = new Smarty();
$smarty->loadFilter(Smarty::FILTER_VARIABLE, "htmlentities");
Tadà !
Update: Smarty::FILTER_VARIABLE is undocumented as of 28/11/2014. Use $smarty->escape_html = true if you want to stick to offical docs.
It appears that this feature was removed from Smarty v3, and docs are outdated. See:
http://www.smarty.net/forums/viewtopic.php?p=62207
I'd recommend a workaround - which is template level. Either create a new style v3 function to take care of filtration, or, do a simple include.
Include method
Put this in a clean.tpl file:
{$text|escape:htmlall}
Then invoke as {include file=clean.tpl text=$myvariabletofilter}
Function method
The new functions in Smarty could also take care of that:
{function clean}
{$text|escape:htmlall}
{/function}
And invoke as {clean text=$myvariabletofilter}
As always, make sure that these things get trimmed right and don't insert unncessary spaces.