I am using handlebar as a templating framework.
When the template get compiled, in case it is not well-formed html, there should be exception thrown.
Does handlebar have such a feature?
For example the following template is not well-formed as the img tag is not properly closed.
<head>
<meta charset="utf-8"/>
<title>Template</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<img src="logo.jpg">
</div>
</div>
</div>
</body>
</html>
Related
I have a Spring Boot Web MVC application where I'm using a Bootstrap 4 template and Thymeleaf as view.
I'm facing a problem where a drop-down navigation item is rendering without styles and scripts when the containing page is mapped in the controller under more than one path segment. If the path consists only of one segment the component works as intended.
Page containing the component "menu.html"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Menu</title>
<!-- Custom fonts for this template -->
<link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Custom styles for this template -->
<link href="/css/sb-admin-2.min.css" rel="stylesheet">
<!-- Custom styles for this page -->
<link href="/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
</head>
<body id="page-top">
<div id="wrapper">
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
<ul class="navbar-nav ml-auto">
<!-- Drop-Down Component -->
<li class="nav-item dropdown no-arrow">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="mr-2 d-none d-lg-inline text-gray-600 small" th:text="${user.getName()}"></span>
<img class="img-profile rounded-circle" src="img/undraw_profile.svg" width="50" height="50">
</a>
<!-- Dropdown - User Information -->
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
Logout
</a>
</div>
</li>
</ul>
</nav>
<!-- Logout Modal-->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="logoutModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="logoutModalLabel">Ready to Leave?</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="/login?logout=true">Logout</a>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript-->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="js/sb-admin-2.min.js"></script>
<!-- Page level plugins -->
<script src="vendor/datatables/jquery.dataTables.min.js"></script>
<script src="vendor/datatables/dataTables.bootstrap4.min.js"></script>
<!-- Page level custom scripts -->
<script src="js/demo/datatables-demo.js"></script>
</body>
</html>
Using the following mapping in my controller the component works fine:
#GetMapping(value = "/first-segment")
public String showModal(Model model) {
model.addAttribute("user", userService.getAuthenticatedUser());
return "menu";
}
But if I add a second segment no styling is displayed and the component can't be clicked on:
#GetMapping(value = "/first-segment/second-segment")
public String showModal(Model model) {
model.addAttribute("user", userService.getAuthenticatedUser());
return "menu";
}
Note
I'd also like to add that not all Bootstrap components don't render correctly under two path segments. As far as I've noticed only drop-down and modal components share this issue.
Replace:
<script src="vendor/jquery/jquery.min.js"></script>
with:
<script src="/vendor/jquery/jquery.min.js"></script>
Note the extra slash at the start. Otherwise, the Javascript file is supposed to be relative to the current file. That is why it worked for the first segment, but not the second segment.
By starting with a slash, it is always relative to the root of the path.
I'm having trouble putting a button into the element of the list based on Thymeleaf. I would like to have a button next to element of the list.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout.html}">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<section layout:fragment="" content="">
<div class="row">
<div class="col-2">
<a th:href="#{/archives}">archiwum zadań</a>
</div>
<div class="col-2">
<a th:href="#{/add}">dodawanie zadania</a>
</div>
</div>
<ul>
<li th:each="task: ${tasks}"
th:text="|${task.getId()} ${task.getName()} ${task.getCategory().getDescription()} ${task.isFinished()}|">
<input type="submit" value="Done">
</li>
</ul>
</section>
</body>
</html>
Thymeleaf will replace any pre-existing tag content with whatever is generated by the th:text expression.
In your case that pre-existing content is your <input> element - which is why the buttons are not displayed.
One way to avoid this is to place your th:text into a span inside the <li>:
<ul>
<li th:each="task: ${tasks}">
<span th:text="|${task.id} ${task.name} ... |"></span>
<input type="submit" value="Done">
</li>
</ul>
(I removed a couple of your fields from my example, for brevity).
Note also in my case, I have changed ${task.getId} to ${task.id}. As long as you have appropriately named getters (as per the JavaBeans naming convention) you can use the field name - and Thymeleaf will find the correct getter to call.
i have a problem with Spring Boot Thymeleaf. I want to include a simple html-file in another html file with Thymeleaf.
Here my main.html file:
In the middle of the codesnippet you can see the root-div, here i want to include the dashboard.html file.
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Admin-Area</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="/backend/webjars/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="/backend/webjars/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 fixed-top mainnav navbar-expand-xl">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="../dashboard/dashboard.html">B2C-Shop</a>
<button type="button" class="navbar-toggler navbar-toggler-right">
<span class="navbar-toggler-icon"></span>
</button>
</nav>
<div class="container-fluid">
<div class="row">
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<div th:each="script: ${scripts}">
<div th:if="${script.endsWith('dashboard.html')}">
<div id="root" th:include="dashboard :: dashboard></div>
</div>
</div>
</main>
</div>
</div>
<script src="/backend/webjars/es5-shim/4.5.9/es5-shim.min.js"></script>
<script src="/backend/webjars/es6-shim/0.20.2/es6-shim.min.js"></script>
<script src="/backend/webjars/jquery/3.3.1/jquery.min.js"></script>
<script src="/backend/webjars/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="/backend/webjars/modernizr/2.8.3/modernizr.min.js"></script>
<div th:each="script: ${scripts}">
<div th:if="${script.endsWith('.js')}">
<script type="text/javascript" th:src="'/backend/js' + ${script}"></script>
</div>
</div>
</body>
</html>
And this is the dashboard.html file which i want to include in the main.html file.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:fragment="dashboard">
<h1>Welcome to B2C-Admin-Area</h1>
</div>
</html>
This is my DashboardController.java which i declare the dashboarb/dashboard.html file
The return methode "getTemplate()" references to backend folder in resources folder.
/**
*
* Render dash board
*
* #param model the attribute model
* #return the template file name
*/
#RequestMapping(value = "/backend/dashboard/dashboard.html", method = RequestMethod.GET)
public String dashboard(final Model model)
{
String[] script = {"/dashboard/dashboard.html"};
model.addAttribute(SCRIPT, script);
return getTemplate();
}
/**
* Gets the template file name.
*
* #return the template file name
*/
protected String getTemplate()
{
return "backend";
}
My folder stucture looks like this:
Do you have any idea to include this file?
Thank you.
Regards MWC.
First arrange your html files as shown in the below structure:
Then create fragment for import as :
suppose you saved below code in breadcrumb file in template/common folder:
<section class="content-header" th:fragment="breadcrumbfragment">
<ol class="breadcrumb">
<li><i class="fa fa-dashboard"></i> Home</li>
<li class="active">Next </li>
<li class="active">Next to Next</li>
</ol>
</section>
Now to import above fragment use following line:
<section class="content-header" th:replace="common/breadcrumb::breadcrumbfragment"></section>
I have the following problem when trying to use the login.jsp
I have the following code in the login
<%# include file="/jsp/include.jsp"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
function sendForm() {
document.formLogin.submit();
}
</script>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Example :: Spring Application</title>
</head>
<body>
<div class="container">
<form class="bs-docs-example form-horizontal"
action="ServletValidation" name="formLogin" id="formLogin"
method="post">
<legend>Login</legend>
<div class="control-group">
<label for="inputUsername" class="control-label">Email</label>
<div class="controls">
<input type="text" id="inputUsername">
</div>
</div>
<div class="control-group">
<label for="inputPassword" class="control-label">Password</label>
<div class="controls">
<input type="password" id="inputPassword">
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox"> <input type="checkbox">
Remember me
</label>
<button class="btn" type="submit" action="sendForm();">Sign
in</button>
</div>
</div>
</form>
</div>
</body>
</html>
And the following text in the web.xml
<servlet>
<description></description>
<display-name>ValidationServlet</display-name>
<servlet-name>ValidationServlet</servlet-name>
<servlet-class>bt.servlet.ValidationServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValidationServlet</servlet-name>
<url-pattern>/ValidationServlet</url-pattern>
</servlet-mapping>
But once I click the button for submit it returns:
State HTTP 404 - /bt/jsp/ServletValidation
Description The resource required (/bt/jsp/ServletValidation) is not
available.
The folder structure is the following:
+bt
-src
-WebContent
-jsp
-resources
-WEB-INF
-classes
*web.xml
*index.jsp
The problem I'm finding is why is it sending to that URL
There are two problems:
Your servlet maps to the URL /ValidationServlet and your form has the action set to ServletValidation.
Maybe your login.jsp isn't at the same level of your servlet mapping.
The best solution would be setting the action of your form to map the full URL that maps to your servlet. This can be achieved using Request#getContextPath():
<form action="${request.contextPath}/ValidationServlet" ...>
<!-- content... -->
</form>
If you don't use JSTL in your project, then do it. You should avoid scriptlets in your jsp (those <% ... %> tags that hold nasty Java code inside the JSP). But if you don't, then you should try the following:
<form action="<%=request.getContextPath()%>/ValidationServlet" ...>
<!-- content... -->
</form>
Still, the first way is the best to go.
More info:
How to avoid Java Code in JSP-Files?
Our JSTL wiki page
Just change the web.xml file
<url-pattern>/ServletValidation</url-pattern>
ServletValidation is different from ValidationServlet.
I am trying to extract the specific content in html using Jsoup. Below is the sample html content.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body class="">
<div class="shop-section line bmargin10 tmargin10">
<div class="price-section fksk-price-section unit">
<div class="price-table">
<div class="line" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer">
<div class="price-save">
<span class="label-td"><span class="label fksk-label">Price :</span></span>
</div>
<span class="price final-price our fksk-our" id="fk-mprod-our-id">Rs.<span class="small-font"> </span>11990</span>
</div>
<meta itemprop="price" content="Rs. 11990" />
<meta itemprop="priceCurrency" content="INR" />
<div class="our-price-desc fksk-our-price-desc">
<small>(Prices are inclusive of all taxes)</small>
</div>
</div>
</div>
</div>
</body>
</html>
I got the required output using below command:
document.select(".price-table").select(".line").select("span").get(2).text()
Looks like its lengthy.
Can't i able to directly get using span class ("price final-price our fksk-our")?
Any help regarding the same?
Does this not work for you? Not sure why you're arbitrarily starting at price-table.
doc.select("span[class=price final-price our fksk-our]").text();
If not, it should be pretty close. Look at JSoup's selector syntax; it is very powerful.