thymeleaf evaluate string as variable - thymeleaf

suppose I have a thymeleaf fragment named "reference" that takes a parameter referenceNumber="1" and in my model I have "reference1_firstName" = "Bob"
<div ... th:fragment="reference(referenceNumber)">
Reference <div th:text="${referenceNumber}"/> first name is <div th:text="${'reference' + referenceNumber + '_firstName'}".>
</div>
in the obviously incorrect example above I would like to print out "Reference 1 first name is Bob". It seems so simple, I can do it in several other languages, but so far my search has come up empty for thymeleaf

Couple ways to do this.
Preprocessing:
<span th:text="${reference__${referenceNumber}___firstName}" />
#ctx basic object:
<span th:text="${#ctx.getVariable('reference' + referenceNumber + '_firstName')}" />
<span th:text="${#ctx['reference' + referenceNumber + '_firstName']}" />
Or if you intend to access variables this way, use a Map instead of variables.

Related

How to escape right parenthesis in variable?

How can I escape a round bracket (right parenthesis) without closing it in a fragment?
"fragments/questionaire :: questionaire('00001_c-1',
${
{
'...',
'...',
'First 1) ...'
}
},
${
{
'...',
'...',
'...'
}
},'[0,2]')"
Kind of same effect is if keyword new is somewhere in the string.
already tried: 'First 1\) ...' &rpar; ) inside utext
I use it to iterate over an object with questions and hints like:
th:fragment="questionaire(key, questions, hints, rightIndex)"
It's inside a form
<div th:each="aquestion, iterStat : ${questions}" th:with="qid=${key}+'_q-'+${iterStat.index},name='rb-'+${key}">
<div>
<input type="checkbox" th:name="${name}+${'_q-'+iterStat.index}" th:value="0" th:data-s="${iterStat.index}" th:id="${qid}" autocomplete="off" th:checked="${bucket.read('questionaire.'+name+'_q-'+iterStat.index)}==('' + 1)"/>
<label th:for="${qid}" th:text="${aquestion}"></label>
<input type="hidden" th:name="${name}+${'_q-'+iterStat.index}" value="0">
</div>
<div class="hint" th:id="${qid+'--hint'}" th:text="${hints[iterStat.index]}"></div>
</div>
<p class="submitContainer">
<button th:data-qvalidate="|quest${key}|" th:text="#{q.check}">Check</button>
</p>
Following on from my most recent comment in the question...
The least-worst solution I have is to create a Java string variable and add that to your model:
model.put("cp", ")");
where cp means "close parenthesis".
Then you can create a fragment parameter like this:
|foo 1${cp} bar|
And that passes the string foo 1) bar to the fragment without that "selector syntax" error you are currently getting.
<div th:replace="fragments/frag.html :: frag(|foo 1${cp} bar|)"></div>
And my fragment is just this:
<div th:fragment="frag(key)">
<div th:text="${key}"></div>
</div>
I would be happy to learn of a better solution.

Thymeleaf - How to write Html string literals?

How can we write HTML and string literals at a same time in Thymeleaf ?
<div class="details"><span class="Section" th:utext="'Sec' <br> ${wind.sec}"></span><span class="Axiom" th:utext="'Axiom' <br> ${wind.axiom}"></span></div>
This throws error
Cannot execute GREATER THAN from Expression "('Sec' < br) > ${wind.sec}". Left is "true", right is "Great"
You can use the following = which uses + for string concatenation:
<div class="details">
<span class="Section" th:utext="'Sec<br>' + ${wind.sec}"></span>
<span class="Axiom" th:utext="'Axiom<br>' + ${wind.axiom}"></span>
</div>
The <br> is just part of the text literal in this case - because you are using th:utext.
However, using unescaped values such as ${wind.sec} is unsafe and is not recommended. There could be harmful values in that variable - especially if the variable holds data provided by end users.
So, unless the following structure change poses a problem, I would recommend something like this:
<div class="details">
<span class="Section" th:utext="'Sec<br>'"></span>
<span class="Section" th:text="${wind.sec}"></span>
<span class="Axiom" th:utext="'Axiom<br>'"></span>
<span class="Axiom" th:text="${wind.axiom}"></span>
</div>
Here we have separated the true text literals (which can use th:utext) from the variables (which should use th:text). Now, any HTML which may have found its way into your ${...} variables will be escaped, rendering it harmless.

Thymleaf I18N Syntax

I have this code;
<div class="row">
<h5 th:text="#{heading.st}"/>
<h6 th:text="${'Sub Type: ' + results[0].subType + '; Internal Switch Role: ' + results[0].internalSwitch}"></h6>
</div>
where #{heading.st} is the internationalized string for 'Sub Type' stored in a properties file. So I can see than i18n is correctly set up. However, I cannot workout the syntax for replacing the string Sub Type in the h6 element. Both
<h6 th:text="${#heading.st + ': ' + results[0].subType + '; Internal Switch Role: ' + results[0].internalSwitch}"></h6>
and
give syntax errors. Can someone point me in the right direction please.
There are more options as well. Personally, my favorite is either using literal substitutions:
<h6 th:text="|#{heading.st}: ${results[0].subType}|" />
or using additional tags like this:
<h6>
<span th:text="#{heading.st}" />: <span th:text="${results[0].subType}" />
</h6>
I think either option is more readable than string concatenation.
Got it!
<h6 th:text="#{heading.st} + ': ' + ${results[0].subType}"></h6>

How to format currency input in RoR + AngularJS app

Sorry for my English.
I need to change input value format, for example: from "1000000" to "1 000 000 $".
In my views of rails app, I have this line of code:
<%= ng_text_field('total_price', 'selected.data.total_price', 'Full price', ng_readonly: '!selected.permissions.update') %>
In helper:
def ng_text_field(name, ng_model, placeholder, options = {})
result = <<-HTML
<div class="form-group" ng-class='{"has-error":errors.#{name}}' #{options[:ng_if] && "ng-if=\"#{options[:ng_if]}\""}>
<label for="#{name}" class="col-sm-3 control-label">#{placeholder}</label>
<div class="col-sm-9">
<input id="#{name}"
type="text"
class="form-control"
name="#{name}"
placeholder="#{placeholder}"
ng-model="#{ng_model}"
#{options[:ng_readonly] && "ng-readonly=\"#{options[:ng_readonly]}\""}>
<p class="help-block small" ng-if="errors.#{name}">{{errors.#{name} | join:',' }}</p>
</div>
</div>
HTML
result.html_safe
end
I am know Angular very little, I have tried some ways and all this ways was incorrect. :(
Could anyone give advice of some help?
Thank you in advance
You're going to need to create a new directive that requires ngModel and applies the appropriate $parser/$formatter to it.
https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$parsers
A good example of how to do this is (displaying as uppercase but always storing data as lowercase):
ngModel Formatters and Parsers
You should be able to then add the ability to include other directives in your 'options' argument so that they get added correctly to the output.

Thymeleaf allow only ruby tag, escape other tags

I want to show the ruby html tag in a thymeleaf template like this:
<h1 th:text="(${author.displayNameReading} != null) ? '<ruby><rb>' + ${author.displayName} + '</rb><rt>' + ${author.displayNameReading} + '</rt></ruby>' : ${author.displayName}" th:lang="${author.locale}">Some author name</h1>
If I use th:text, it will be escaped. It works if I use utext, but then I'm going to lose all the security for other html tags.
Is it possible to only allow the ruby, rt and rb tags inside th:text?
Why try and stuff everything into a th:text attribute? You can easily split out all that information into new tags -- which is both more readable (formatted like regular html, less string concatenation) and more secure (no need for th:utext). Something like this for example:
<h1 th:lang="${author.locale}">
<ruby th:if="${author.displayNameReading != null}">
<rb th:text="${author.displayName}" />
<rt th:text="${author.displayNameReading}" />
</ruby>
<span th:unless="${author.displayNameReading != null}" th:text="${author.displayName}" />
</h1>

Resources