Displaying text in Thymeleaf - spring-mvc

I'm totally new in Thymeleaf. Just read about it earlier, now, I'm trying to display some text using Thymeleaf in the front end, getting the values from Spring MVC in back-end.
File successPwd.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8"/>
<title>Password Change</title>
</head>
<body>
<h2>Password Changed</h2>
Your password has been changed. Your account information is below.
Username: [[${account.username}]] <br/>
First Name: [[${account.firstName}]] <br/>
Last Name: [[${account.surname}]] <br/>
</body>
</html>
File PasswordResetController.java
#RequestMapping(value= "/user/new_password", method = RequestMethod.POST)
public String saveNewPassword(#RequestParam(value="new_password",required=false) String password, #RequestParam(value="hash") String hash, Model model)
{
//some codes to check hash
AccountInfo account = accountInfoService.getAccount(hash);
model.addAttribute("account", account);
return "/successPwd";
}
What I'm getting is like this:
Password Changed
Your password has been changed. Your account information is below.
Username: [[${account.username}]]
First Name: [[${account.firstName}]]
Last Name: [[${account.surname}]]
Thymeleaf is not converting to the proper values, most likely I missed something very very basic here.

In this case, you should use th:text. For example, Username: <p th:text=${account.username}>Username will be rendered here</p>. Note that, the text inside p tag won't be shown.
See here for more details: Standard thymeleaf syntax

If you want to get rid of the "awkward" Html tag you can do as follows.
<span th:text="${account.username}" th:remove="tag">userName</span>

Related

cardIdentifier returned in URL QueryString rather than hidden-field

I have integrated SagePay's 'Drop In Checkout' into a test solution. The issue is, when I am submitting the form for the 'cardIdentifier', it is returned in the URL as a QueryString, rather than a hidden field, as per the documentation.
http://integrations.sagepay.co.uk/content/getting-started-integrate-using-drop-checkout
"Once the customer initiates the form submission, the payment details are validated, tokenised and passed as a hidden field called cardIdentifier which is then posted with the rest of the form contents"
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="CustomPayment.aspx.cs" Async="true" Inherits="SagePayDropInTest.CustomPayment" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://pi-test.sagepay.com/api/v1/js/sagepay-dropin.js"></script>
</head>
<body>
<div id="main">
<h1>My Test Shop</h1>
<form id ="checkout-form">
<h2>Payment Details</h2>
<div id="payment-details"></div>
<div id="submit-container">
<input type="submit"/>
</div>
</form>
</div>
<script>
sagepayCheckout({
merchantSessionKey: '<%=MerchID%>',
containerSelector: '#payment-details'
}).form({
formSelector: '#checkout-form'
});
</script>
</body>
</html>
C# CodeBehind
namespace SagePayDropInTest
{
public partial class CustomPayment : System.Web.UI.Page
{
public string MerchID = "";
protected void Page_Load(object sender, EventArgs e)
{
MerchID = GetMerchSessionID();
}}}
It does return the cardIdentifier, but just as a QueryString, but I would rather I was getting it as a hidden-field, as documented. The rest of the integration works as documented, it is just this step which is throwing me.
I am no doubt missing something obvious, and any guidance would be much appreciated.
Try changing the <form> tag to include a method="post" attribute. This should mean that the cardIdentifier is sent as a posted field rather than in the query string. The default method for a form is normally a GET request, the SagePay JS probably doesn't change this.
Also, there looks like an extra space in the <form id ="checkout-form"> tag as it is. I would recommend taking this out as some less forgiving browsers may not parse this correctly, breaking the CSS selector in your JS.

Passing data to a nested template not working as expected

I was trying to get a struct passed to a nested template in Go, using html/template and tried to achieve it using both template.ParseFiles and template.ParseGlob, but it is not working as per my expectation because my understanding is not clear.
My template code for the file header.html is
{{define "header"}}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> SiteAdmin - {{.User}}</title>
</head>
{{end}}
and for the file admin.html is
{{template "header"}}
<body>
"User is {{.User}}"
</body>
</html>
I am using the Execute method on the type *Template as
type Admin struct {
User string
}
data := new(Admin)
data.User = "Guest"
tpl, err := template.ParseGlob("views/templates/admin/*.html")
CheckForErr(err)
err = tpl.Execute(w, data)
CheckForErr(err)
With the above code, I can pass around the struct data to admin.html, and it shows User is Guest in the browser. But if I try to pass it to any of the nested templates, it wouldn't. The title of the page still shows as SiteAdmin - and not SiteAdmin - Guest. The User data from the struct is visible only if I call it as {{.User}} inside the admin.html file, and any reference to it in the nested templates turns out to be not passed. Is this something achievable?
Thank you all.
You need to use {{ template "header" . }}. As the document in text/template say:
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
In this case, the pipeline you passed into is ., which reffers to the whole data.
It is somehow unconvenient that documents of html/template is mostly in text/template.

Error while moving HTML form from jsp to ThymeLeaf

I am trying to follow this as reference Serving Static content in SpringBoot
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.ui.Model;
/**
* Created by Eric on 11/25/2015.
*/
#org.springframework.stereotype.Controller
public class Controller {
#RequestMapping("/appPage")
public String greeting(#RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
model.addAttribute("title", "Best Of the App");
model.addAttribute("basecontext", "Best Of the App");
return "appPage";
}
}
My HTML form being below
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${title}" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
<input type="hidden" type="text" id="basecontext" value='${basecontext}'/>
</body>
</html>
I am trying to set value in hidden input field. But that gives me error
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Exception parsing document: template="appPage", line 9 - column 33
I am trying to move this html page which was getting loaded in a JSP application to Spring Boot + ThymeLeaf.
If I simply place this content in index.html without a Context handler in Controller. the page is loaded just fine. Thymeleaf does not throw any error.
ThymeLeaf uses xml and not html and you are not allowed to have attributes of the same name in xml type="hidden" type="text"
You actually should get SAXParseException: Attribute "type" was already specified for element in your spring log

How to pass a map in thymeleaf (spring 4)

I want to pass a map from a properties file using the thymeleaf template engine.
Exception:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'title' cannot be found on object of type 'java.lang.String' - maybe not public?
provider.html:
<!DOCTYPE>
<html th:include="receiver :: receiver(#{site})"></html>
receiver.html:
<!DOCTYPE HTML>
<html th:fragment="receiver(map)">
<head>
<title th:text="${map.title}">title</title>
</head>
<body th:text="${map.body}">
body
</body>
</html>
messages.properties:
site.title = Any title
site.body = Any body
Controller:
#Controller
public class StartController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String start(Model model) {
return "provider";
}
}
It simply like in Java. Key and value of the Map
<div th:each="userEnrty: ${userMap}">
<p th:text="${userEntry.key}">No Id!</p>
<p th:text="${userEntry.value}">No Name!</p>
</div>
So I figured out that property-files are processed as Map. So 'site' wasn't a map at all.
My solution now is to pass the name of the variable-prefi and get the keys by thymeleaf preprocessing.
provider.html:
<!DOCTYPE>
<html th:include="receiver :: receiver('site')"></html>
receiver.html:
<!DOCTYPE HTML>
<html th:fragment="receiver(mapname)">
<head>
<title th:text="#{__${mapname}__.title}">title</title>
</head>
<body th:text="#{__${mapname}__.body}">
body
</body>
</html>
messages.properties
site.title = Any title
site.body = Any body

Get value input text jstl - Spring MVC

My friends,
I have problem.
I'm working with spring MVC and I put value in:
<input type="hidden" name="projetoid" id="projId"/>
I'd like to get valeu of "projetoid" and pass as argument:
<p><s:message code="modal.projeto.confirma_desativacao" arguments="???" htmlEscape="false"/></p>
Any idea? How can I get this value with JSTL?
There's a little difficulty understanding your question, but I perceived it as you want the value in projId to be passed into the s:message arguments attribute. Here is what I have tested and found working.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<input type="hidden" name="projetoid" id="projId" value="testing123"/>
<p><s:message id="target" code="modal.projeto.confirma_desativacao" arguments="???" htmlEscape="false"/></p>
<script type='text/javascript'>
$(document).ready(function(){
var hiddenVal = $('#projId').val();
$('#target').attr("arguments", hiddenVal);
console.log('Logged: '+$('#target').attr("arguments"));
});
</script>
</body>
I could see the console.log successfully printed the value of projId.
I used jQuery to do the job. When the document is ready, I passed the value from projId to id:target. If you are trying to pass the value upon form submit, then you have to create a function to transfer the value over upon submitting the form. Hope this helps =)

Resources