Structuring a BIG view with Thymeleaf and Spring MVC - spring-mvc

I'm about to generate a pdf report (roughly 20 slides long) in java using Spring MVC, Thymeleaf and Flying-saucer. I would like to be able to structure the code according to the different slides so that I can easily add and remove slides and not have all code for all slides in one chunk. In the end, after Spring MVC and Thymeleaf are done, I guess I will have a lot of XHTML and CSS ready to be sent to Flying-saucer for PDF generation.
I haven't worked that much with Spring MVC but my feeling is that you first do the controller stuff, e.g. get data, work with the data and then put necessary data on the Model so Thymeleaf can continue and render the view based on a template and the data on the Model.
How can I divide the code parts in java and Thymeleaf in a good modular way? Anyone have a good design to be inspired by or can point me somewhere on the web where I can find good information about this?

In your case I suggest to fragment Thymeleaf templates into three parts - master, slide and content templates. You can fill report content dynamically from Spring MVC controller or build it in static way just in Thymeleaf.
I providing skeleton templates structure as I think it's the best (all templates supposed to be on root template path). If you want to add slide you just create new template with content and insert new line to master template. If you want to remove slide you just delete appropriate line.
Master template - index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<th:block th:include="slide :: slide" th:with="content=${'content1'}"></th:block>
<th:block th:include="slide :: slide" th:with="content=${'content2'}"></th:block>
<th:block th:remove="tag" th:include="slide :: slide" th:with="content=${'content3'}"></th:block>
</body>
</html>
Slide template - slide.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body th:fragment="slide">
<div class="slide">
<div th:replace="${content} :: content"></div>
</div>
</body>
</html>
Content template 1 - content1.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<ul th:fragment="content">
<li>Content 1</li>
</ul>
</body>
</html>
Content template 2 - content2.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<span th:fragment="content">Content 2</span>
</body>
</html>
Content template 3 - content3.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<p th:fragment="content">
Content 3
</p>
</body>
</html>

Related

cannot link bootstrap.min.css with Dynamic web app

dears,
i've followed these steps :
1) Download Bootstrap from http://getbootstrap.com/
2)Create a dynamic web project in eclipse.
3)Make sure that this dynamic web project could be run on the server.
4)Under WebContent folder, create a bootstrap folder.
5)Import files such as following from downloaded Bootstrap
resources into the newly created folder, “bootstrap” in step 3. css
folder consisting of bootstrap.min.css js consisting of
bootstrap.min.js img consisting of images Create an index.jsp and put
following within tag
But my html doesn't seem to see the css, i even wrote this line as a test but nothing appears
<div class="alert alert-info">
<strong>Info!</strong> Indicates a neutral informative change or action.
</div>
this is the whole index.html page:
<!DOCTYPE html>
<html>
<head>
<link href=”bootstrap/bootstrap.min.css” rel=”stylesheet” type=”text/css” />
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div class="alert alert-info">
<strong>Info!</strong> Indicates a neutral informative change or action.
</div>
</body>
</html>
Try to change your css link declaration to
<link href="bootstrap/bootstrap.min.css" rel="stylesheet" type="text/css" />
It has symbols with unsupported encoding.

Html anchor in another html

Suppose I have two html files footer.html and main.html. The footer contains a reference to the top of a page as follows:
<!-- footer.html -->
<!doctype html>
<html lang="en">
<head></head>
<body>
<footer>
<small>To top</small>
</footer>
</body>
</html>
The main.html file embeds the footer by using the <object> tag (see note 1) as shown below. There can be several files similar to main.html. Because of this <a href="page#header"> may not be used.
<!-- main.html -->
<!doctype html>
<html lang="en">
<head></head>
<body>
<div id="header">...</div>
<div id="content"> Long content ... </div>
<object id="footer" type="text/html" data="footer.html"></object>
</body>
</html>
Question: Is it possible to refer to the anchor from the footer to main without using javascript, php etc?
Note 1: The <object> tag can be used to embed another html, although without a relation:
You can also use the <object> tag to embed another webpage into your HTML document.
from http://www.w3schools.com/tags/tag_object.asp
The same can be done using <iframe> or <embed> instead of <object>, but the issue remains.
Is it possible to refer to the anchor from the footer to main without using javascript, php etc?
No, it isn't.
If you use a relative URL, then it will be relative to the document that the link appears in (i.e. the footer).
If you use an absolute URL, then you have to specify which document you want to link to the top of (and since multiple documents will embed the footer, you can't do that).
You've ruled out generating the URL programatically with JavaScript.
Thanks to all for the comments and answers. Indeed, this approach seems not to work due to a missing relation between html files. In other words, footer.html cannot refer to the inside of main.html. Instead, I modified the structure, so that the main includes the footer directly and the content is embedded by using an <iframe> as follows:
<!-- main.html -->
<!doctype html>
<html lang="en">
<head></head>
<body>
<div id="header">...</div>
<iframe id="content" name="contentframe" src="content.html"></iframe>
<footer id="footer">
<small>To top</small>
</footer>
</body>
</html>
This solves the issue and works without JS, PHP or the like independently of the page loaded into the <iframe>. That is, it simply jumps to top keeping the contents of the loaded page. Eventually, there is one main and multiple long content pages which are loaded into this main. Tested with FF and IE.

How do I include partials?

I got this:
main.vm
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> test </title>
</head>
<body>
$content
</body>
</html>
This should serve as the default template for all other views which are going to be included.
For example this one:
example.vm
#define($content)
<div>
<p> Hello World ! </p>
</div>
#end
How do I include that partial as content into the main.vm file?
Am I defining my templates right?
I couldn't figure out that from the official docs.
I'm using Spring Boot, everything is set up correctly.
All the templates are in the same folder:
/resources/templates
edit:
The main idea is to have one boilerplate html file with all the script tags and link tages, head and body.
This should be the main template with a $content variable, this is a placeholder for every other page.
Now every other page should be included into that main page.
How do I achieve that?
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> test </title>
</head>
<body>
$content
##the templates you want to 'execute' and render
#parse("example.vm")
#parse("example1.vm")
##...
#parse("example-n.vm")
##The templates you want to 'render' but not 'execute' as velocity templates.
#include("include.vm")
#include("include1.vm")
#include("include2.vm")
##...
#include("include-n.vm")
</body>
</html>
This would help...
Please note this:-
Using the #parse() macro would execute the template and then include it.
Using the #include() macro would include the template as plaintext.

Grails not finding my resources

My Grails project structure:
my-app/
grails-app/
<mostly typical grails-app structure>
views/
web/
index.gsp
app/
admin/
layouts/
main.gsp
<rest of project structure is like any other Grails app>
So you can see whereas, normally, the index page is located at grails-app/views/index.gsp, I have it at grails-app/views/web/index.gsp.
My application.properties:
app.grails.version=2.4.2
app.name=my-app
app.context=/
app.version=0.1
One section of my UrlMappings.groovy:
"/"(view:"/web/index")
My main.gsp layout:
<!DOCTYPE html>
<html lang="en">
<head>
<title><g:layoutTitle default="MyApp"/></title>
<g:resource dir="css" file="myapp.css" />
<g:layoutHead/>
</head>
<body>
<g:layoutBody/>
<g:resource dir="js" file="myapp.js" />
</body>
</html>
My index.gsp:
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
When the app starts up and I view it in a browser, it is obvious that myapp.css is not being found because the page styling is all wrong. When I view page source I see:
<!DOCTYPE html>
<html lang="en">
<head>
<title>MyApp</title>
/css/myapp.css
<meta name="layout" content="main"/>
</head>
<body>
<h1>Hello!</h1>
/js/myapp.js
</body>
</html>
So it sounds like Grails takes your app.context and uses that as the prefix for all resources. And because I haven't wired something correctly, Grails is just translating my <g:resource> tags into plaintext and printing them out in the HTML.
I guess my question is: What do I need to do so that Grails can find my CSS/JS resources?
I don't sure that tag into tag will be work correctly, so write like this:
<link rel="stylesheet" href="${resource(dir:'css', file:'myapp.css')}" charset="utf-8"/>
According to the Documentation, The resources tag generates a link (URI) string. Can be used in an href, JavaScript, Ajax call, etc.
Use the resources tag inside script or link tags to get your css/js loaded in your page like,
<link rel="stylesheet" href="<g:resource dir="css" file="myapp.css" />" charset="utf-8"/>
You can also use resources plugin, which I would recommend as it solves the purpose and has good documentation

Render Partial in WebPages without using MVC

I'm using Razor with WebPages but without MVC. I like the simplicity with this so I'm not interested in using MVC at this point. However I would like to be able to render a partial into my page. Like a menu, a footer, etc.
With MVC you can to this:
#{ Html.RenderPartial("Footer", Model);}
I would like to do something similar:
#{ Html.RenderPartial("footer.cshtml"); }
How can I achieve what I want?
take a look at this link http://www.mikesdotnetting.com/Article/151/Extending-ASP.NET-Web-Pages-Create-Your-Own-Helpers
Hope this will help you
also try this:
<!DOCTYPE html>
<html>
<head>
<title>Main Page</title>
</head>
<body>
#RenderPage("/Shared/_Header.cshtml")
<h1>Index Page Content</h1>
<p>This is the content of the main page.</p>
#RenderPage("/Shared/_Footer.cshtml")
</body>
</html>

Resources