I use Thymeleaf as a templating engine and I usually output variable value like this:
in Java I set:
ctx.setVariable("tester", "hello");
and in html template I output:
<span th:text="${tester}"></span>
This works great, but I would like to output a variable without the need of a tag. Something following would be great:
${tester}
Unfortunately it does not work. My goal is to avoid unnecessary tag to output the variable value. Is this possible to do with Thymeleaf?
My goal is to avoid unnecessary tag to output the variable value. Is this possible to do with Thymeleaf?
Yes this is possible. You can use the Thymeleaf synthetic th:block tag (see here).
Example template excerpt:
<body>
<th:block th:text="${tester}"></th:block>
</body>
This renders the following HTML:
<body>
hello
</body>
Only the variable is displayed.
Use Thymeleaf expression inlining (docs) using either [[...]] or [(...)]. With expression inlining, you do not need to use synthetic tags.
Example:
<body>
The value of tester is [[${tester}]].
</body>
Thymeleaf triggers on the "th:" tag and as far as I know thats the only way.
The behaviour you describe works with JSF.
Best regards
Ben
I also managed to figure out some workaround:
<span th:text="${tester}" th:remove="tag"></span>
th:remove removes span tag, but preserves content.
Related
I am in a situation where the "class" attribute of a div tag should be dependent on the value of a java binding. This can be easily done by moving the associated logic to the java class, but at this moment we are not allowed to change anything at the Java component.
I am trying out the following to resolve the problem (using WOOGNL):
<div class="<wo:WOConditional condition = \"[cssClassDecider]\">classToUse</wo:WOConditiona>" >
HTML Static Content
</div>
As it can be seen, i am trying to use value of "cssClassDecider" to set the class.
Can anybody tell if any has solved a similar problem or one is available at WO.
It's not clear to me whether cssClassDecider is providing the string content for the class attribute, or a boolean to drive a conditional. In any case, the usual pattern would be:
<wo:WOGenericContainer elementName="div" class="$methodReturningClassNames">
...
</wo:WOGenericContainer>
If cssClassDecider returns a conditional, you could do something like this:
<wo:WOConditional condition="$cssClassDecider">
<div class="classWhenTrue">
...
</div>
</wo:WOConditional>
<wo:WOConditional condition="$cssClassDecider" negate="$true">
<div class="classWhenFalse">
...
</div>
</wo:WOConditional>
If neither of those solve your problem, provide some more information.
In PHP we can do the following with the help of Variable variables in PHP:
$privateVar = 'Hello!';
$publicVar = 'privateVar';
echo $$publicVar; // Hello!
Suppose we have the following chunk of Java code:
request.setAttribute("privateVar", "Hello!");
request.setAttribute("publicVar", "privateVar");
I've tried the following but an error occurs.
${${publicVar}}
Does anyone know how we can get value of privateVar via using only publicVar in JSP (JSTL)?
UPDATE 1:
I have a custom tag which allows to print a message if an object foo doesn't have a field bar.
I know I must catch exceptions in the case but I don't want to handle ones in JSP. I want to do it only in CustomTag file.
<%-- JSP file --%>
<ctf:tagName varName="foo.bar" />
<%-- CustomTag file --%>
<%# attribute name="varName" required="true" rtexprvalue="true"%>
<c:catch var="exception">
<c:set var="valX" value="${${varName}}" scope="page"/>
</c:catch>
<c:if test="${exception != null}">Can't find getter for the VAR in the OBJ.</c:if>
UPDATE 2:
JB Nizet gave me the answer and the following works well! :)
<c:set var="privateVar" value="Hello!" />
<c:set var="publicVar" value="privateVar" />
${pageScope[pageScope.publicVar]}
I don't think you can directly do this in the same way that you can in PHP. Instead you could change the attribute to use the value of the privateVar instead of the name, like this:
String privateVar = "Hello!";
request.setAttribute("privateVar", privateVar);
request.setAttribute("publicVar", privateVar);
This gives you access to the value under both names, which I think is the closest you'd get. No need to even put the attribute privateVar in the request if you are ultimately going to use publicVar on the JSP.
Ultimately you may want to rethink the design here as it doesn't really work in Java.
The basics:
That's not JSTL but Expression Language. And you should only use a single ${} evaluator. The code would be:
${publicVar}
More info:
StackOverflow Expression Language wiki
To your problem:
Expression Language doesn't allow that. You cannot have private attributes in any scope (page, request, session, application), so you can at most set the attribute twice with different names but the same value. But as you may note, this is useless.
I am currently using Struts2 tags for my form, and to show its error messages. My question is that the default markup for showing error messages in Struts2 tags is the usage of <ul> tag. is there anyway I can change this? I want the error messages to be displayed as <span> not a list.
How would I achieve this?
Another option is to change the CSS for UL elements.
This approach works only if you specifically care about appearance, not the DOM itself.
You can override template files which are used for rendering errors. Copy actionerror.ftl and fielderror.ftl files from the simple theme from struts2-core jar to your application and modify them not to use ul/li tags.
The tags render according to their theme. The question then changes to: How do you change the theme? You can change it for the tag
(set theme attribute on the tag to simple), page, request, or generally.
http://struts.apache.org/2.2.1/docs/struts-2-themes.html
Personally I like writing html, that is I don't like any "help" from the struts2 default theme. So in my struts.xml I simply use:
<constant name="struts.ui.theme" value="simple" />
Web developers should know html.
Update:
Generally use YUI reset.css so I probably missed this...
If you extend ActionSupport on the action there is a getFieldErrors() method so you could use <s:property value='fieldError["field_name"]'/> that will return the associated error message string of course without any formatting.
It isn't much less readable than the <s:fielderror/> tag... after all we need to use property tags all the time anyways.
I had same issue I used following code to resolve my issue
<s:if test="fieldErrors.get('email').size() > 0">
<s:property value="fieldErrors.get('email').get(0)"/>
</s:if>
Where email is name of my field. This way we don't have to modify CSS.
Here is a tutorial to show the use of the Struts 2âēs ActionError and ActionMessage class.
http://www.mkyong.com/struts2/struts-2-actionerror-actionmessage-example/
ActionError â is used to send error feedback message to user â display via < s:actionerror/ >
<s:if test="hasActionErrors()">
<div class="errors">
<s:actionerror/>
</div>
</s:if>
ActionMessage â is used to send information feedback message to user,display via < s:actionmessage/ >
<s:if test="hasActionMessages()">
<div class="welcome">
<s:actionmessage/>
</div>
</s:if>
For example, a user will be rendered throughout my application as
<div class="user">
<p class="username">${user.name}</p>
<p class="karma">${user.karma}</p>
<img src="/users/${user.id}"/>
</div>
How can I reuse this code block?
Note - my code is running within a tag, so I can't use tags for this (or any JSP) otherwise I get a Scripting elements are disallowed here error.
Edit
I'm trying to use a tag file, but getting PropertyNotFoundException.
This is my tag file called 'user.tag':
<%#tag description="User" pageEncoding="UTF-8" %>
<a href="../user/showUser.do?userId=${user.id}">
<p>${user.name}</p>
<img class='avatar' src='${user.avatarUrl}' alt=""/>
</a>
And usage inside a jsp:
Where job.poster is a java bean with id, name, and avatarUrl properties.
If I add
<%#attribute name="user" %>
to the tag file, then I get an exception
Property 'id' not found on type java.lang.String
Since JSP 2.0, there is yet another kind of tags: Tag files. Tag files are JSP custom tags written as a JSP template itself, which seems to be what you want.
http://fforw.de/post/creating-jsp-layouts-with-page-tags/ shows how to use such a tag file as general layout solution. Using them as component should be even easier.
You should be able to use tag files within tag files; this works for me in a JSP 2.2 container:
<%-- mytag.tag --%>
<%#tag description="demo code" pageEncoding="UTF-8"%>
<%#taglib prefix="cust" tagdir="/WEB-INF/tags" %>
<%#attribute name="message"%>
<cust:mytag2 message="${message}" /><%-- uses mytag2.tag --%>
If that fails, you can use the include directive: <%#include file="/WEB-INF/jspf/fragment.jspf" %>
Note that the spec says about tags:
Directive Available? Interpretation/Restrictions
======================================================================
page no A tag file is not a page. The tag directive must
be used instead. If this directive is used in a
tag file, a translation error must result.
So, fragment.jspf must not have a any elements that are not supported in tags, including a page directive.
For the example you have given it sounds like some templating framework is needed, to display the user badge on each screen. At its simplest level this may just be a jsp:include which always includes your "UserBadge.jsp".
If you are running on a web framework e.g. JSF you may use Facelet templates or write a custom component for this. So the answer depends on what framework you have. Breaking it down to just JSP and JSTL - the included JSP or a javax.servlet.jsp.tagext.Tag would certainly reduce the duplication.
Always be careful to follow the DRY Principle... Don't Repeat Yourself!
I feel sometimes creating a .tag file is overkill (especially if it's only for one page), and I've wanted what you describe for years, so I wrote my own, simple solution. See here:
https://stackoverflow.com/a/25575120/1607642
Why don't you use a custom tag or jsp functions.
Thanks,
I want to output the value of the xzy variable into the value of the abc variable.
<c:set var="abc" value="<c:out value="${xyz}"/>"/>
I'm getting an error (unterminated <c:set> tag) when I do this.
How do you do this?
No, you must have well-formed markup. <c:set/> can have body content instead of a value attribute though:
<c:set var="abc"><c:out value="${xyz}" /></c:set>
I would only use this to take advantage of the XML-escaping provided by <c:out/>. Otherwise it's simpler just to set the value="${xyz}".
What about
<c:set var="abc" value="${xyz}"/>
Remember, c:out is basically when you want to write text to the HTML page. In this case you just want to pass the value around, so keep it in variable land. Think of your java code doing this
String myString = System.out.println("12");
That is about what you are doing... :)