I'm new to Thymeleaf (and webdev) and I'm trying to combine Thymeleaf iteration (th:each) with URL re-writing (th:href).
<a th:each="lid : ${lists}" th:text="${lid}" th:href="#{/list?l=${lid}}">
hello
</a>
This produces the following (where lid=45):
45
So, it did the substitution on the th:text, but not on the th:href.
I'm not trying to do any sort of URL re-writing, I'm just using the '#' syntax because I want Thymeleaf to substitute the 'lid' attribute.
I'm using the current version of Thymeleaf (2.1.2) with Google App Engine.
If you don't want to do any url rewriting, you shouldn't use the # syntax.
You can use the pipeline (|) syntax to do some literal substitions:
th:href="|/list?l=${lid}|"
Source: Thymeleaf documentation
You can also try this way:
<a th:href="#{'/list?l=' + ${lid}}" th:text="${lid}">element</a>
I don't have enough reputation to add a comment on a previous post but the Thymeleaf Source documentation link from a previous post is broken. Documentation can now be found at the following link:
Thymeleaf Standard URL Syntax
Section 9 Using Expressions in URLs in this documentation explains how you can use expressions within other expressions when generating URLs with the # syntax. The following is an example:
<a th:href="#{/order/details(id=${modelattribute})}"/>
Will produce a link similar to:
http://domain.org/context/order/details?id=1
if modelattribute had a value of 1 in the current context.
Related
I am using Thymeleaf as the front end.
I have some menu categories in natural language that I display on a web page and pass to the server.
For example, I have a category of "My favourite cats"
The category is in a variable ${category.key}
This category has a link;
<a th:href="|http://myserver?selectedCategory=${category.key}|><span th:text=${category.key}></span></a>
If I do not URLEncode ${category.key} on the server, then when a
user clicks the link, the selectedCategory parameter is null if there
is a whitespace in the category string.
If I encode the category string, the selectedCategory parameter
passes to the server fine BUT the link text appears as
My+favourite+cats
I don't want two variables, one encoded, one not encoded.
How do I either encode or unencode ${category.key} as part of the Thymeleaf HTML compilation process?
#symbol is Server Context path in Thymeleaf. you use #symbol.
<a href="#" th:href="#{/your server context path?selectedCategory=__${category.key}__}">
<span th:text="${category.key}"> </span></a>
Thymeleaf will url encode strings if you build them with url syntax (which was supplied in a comment above). For your example url, it should look like this -- using the # symbol instead of the $:
<a th:href="#{http://myserver(selectedCategory=${category.key})}" th:text="${category.key}" />
(Also, you don't need that extra span.)
Using the #symbol is definitely the primary alternative. But just to note another option that may be of use on occasions:
The answer is to use the lesser know #strings functions to replace the '+' with ' '
In the link text, use
th:text="${#strings.replace(category.key,'+',' ')}"
Seeking help in spring secuity with thyemeleaf. I want to pass specific role as a paramter in spring security hasRole() function.
<li sec:authorize="hasRole(__${someVariable}__)" th:if="${#authentication}">
i just want to pass my role as a variable "somevariable" would have value of like 'admin', 'systemadmin' etc
FYI.. I am using Thymeleaf + Spring
I solved the same basic problem in a way that avoids trying to hack the double-underscore (e.g. __${someVariable}__) syntax.
<th:block th:with="secAuth=${yourNormalModelAccessHere}">
<li class="nav-item" sec:authorize="${#authorization.expression(#vars.secAuth)}">
</th:block>
Hope this helps someone. :)
I can get it solved by using:
${#authorization.expression('hasRole(__${someVariable}__)')}
What do you mean by pass some variable? If you have implemented spring security correctly, hasRole can be evaluated using sec:authorize="hasRole('ROLE_ADMIN') .. etc. Also, you do not need to include th:if since sec:authorize attribute renders its content when the attribute expression is evaluated to true
See reference here
I would ditch sec:authorize and instead write it like this:
<li th:if="${#request.isUserInRole(someVariable)}">
(Assuming somewhat recent version of Servlet API and use of Spring Expression Language in Thymeleaf template.)
the angularjs feature called directive cause to problems in spring mvc. If I use thymeleaf to render a html with elements such
<div ui-view autoscroll="false"></div>
i got a error like
org.xml.sax.SAXParseException: Attribute name "ui-view" associated with an element type "div" must be followed by the ' = ' character.
is there an elegant workaround or should I use something else than thymeleaf?
Edit:
Many thanks for your answers, they helped me a lot.
Either you code xml or you use some workaround. open your application.properties and add following
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
Just put the below code. basically what it is saying is that every attribute in HTML should have a value. When the browser renders it, it will anyway look like below.
<div ui-view="" autoscroll="false"></div>
Update: You can also use directive in a class or as an element.
I am using Play Framework 1.2.5. What is the difference between:
#{Application.render()}
and
#Application.render()
The first one is preferably used in the form action whereas the second one may be used for an anchor template. Both of them will be generating a URL, hence not able to understand which for the first one I need a {} surrounding braces.
Please let me know about this.
Thanks,
#{} is a short cut to generate a relative url based on a reverse route (Controller.method -> URL)
##{} gives you the absolute URL
#{} refer to tags. There just so happens to be an #a tag and you can do
#{a #Application.logout()}Disconnect#{/a}
because within the tag, you're actually passing the ActionDefinition when doing #Application.logout(), not the URL.
See http://www.playframework.org/documentation/1.2.5/tags
As far as I know, you need the curly braces when you use this in a template, for instance:
<form action="#{Application.post}">.
I just tried without the curly braces and that resulted in the exact string (#Application.render) and not an URL.
My code in the template:
#Application.index()<br />
#{Application.index()}<br />
Results in the following HTML in my browser:
#Application.index()<br />
/<br />
How do I configure a jsoup Whitelist to allow internal anchor references, without allowing any arbitrary value?
Example html:
Jump To Section 1
<!-- ... -->
<a name="section1">Section 1</a>
If I attempt to clean the code with the relaxed Whitelist the href is removed.
Jsoup.clean(html, Whitelist.relaxed().addAttributes("a", "name", "target");
returns the following:
<a target="_self">Jump To Section 1</a>
<!-- ... -->
<a name="section1">Section 1</a>
If I manually build a Whitelist and add the tags and attributes that I want, but don't call addProtocols(....) I can get jsoup to leave the href in place, but that doesn't seem like a good solution as it doesn't filter out href's that contain JavaScript. For example, I want the a tag (or at least the href) removed from the following:
Jump To Section 1
<a name="section1">Section 1</a>
Is this possible with jsoup?
I did see the following patch submission to jsoup, but it doesn't look like it made it into the jsoup code base: https://github.com/jhy/jsoup/pull/77
Whitelist whitelist=new Whitelist();
Cleaner cleaner = new Cleaner(whitelist);
whitelist.addAttributes("a","accesskey","dir","lang","style","tabindex","title","href");
cleaner.clean(doc);
If no protocols are provided/whitelisted, then all of them are implicitly allowed (see isSafeAttribute). If you want to allow internal anchors, then you need to never call addProtocol on your whitelist's anchor tags, unfortunately (well, on the href at least). It looks like there was a pull request to add support, but it was never merged.
Be aware that if you are allowing all protocols, that a malicious user can run Javascript on link click:
Some text
so be cautious of that if you do not trust your HTML.
If you want to only allow say, http, https, and anchor tags, then I believe you are out of luck.
The reply get 3 upvotes doesn't answer the question at all.
The github link mentioned in the OP is currently merged, and for others who are looking for the answer
Whitelist.relaxed().addProtocols("a", "href", "#")
Reference: Jsoup API Document