With Tiles, is there a way to reduce my two JSPs into one JSP? - tiles

I'm using Tiles for the first time. Trying to layout my JSP pages in my Spring MVC project.
Please take a look at what I'm doing and let me know if this is the "correct" way to do it ... my specific question is at the bottom ...
I have the file structured like this ... folder /src/main/webapp/WEB-INF/layouts/ contains ...
standard.jsp
// ...
<html>
<title><tiles:insertAttribute name="title"/></title>
// ... LOTS OF HTML ...
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="body"/>
<tiles:insertAttribute name="footer"/>
// ... LOTS OF HTML
</html>
// ...
tiles.xml
<tiles-definitions>
<definition name="standardLayout" template="/WEB-INF/layouts/standard.jsp">
<put-attribute name="title" value="My Directory" />
<put-attribute name="header" value="/WEB-INF/layouts/header.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="" />
</definition>
</tiles-definitions>
And my viewable JSPs are in folder /src/main/webapp/WEB-INF/views/ which contains ...
tiles.xml
<tiles-definitions>
<definition name="home" extends="standardLayout">
</definition>
</tiles-definitions>
home.jsp
<%# taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<tiles:insertDefinition name="home">
<tiles:putAttribute name = "body" value="/WEB-INF/views/home-body.jsp"/>
</tiles:insertDefinition>
home-body.jsp
<div>
// LOTS OF HTML FOR THE BODY OF THE HOME PAGE
</div>
QUESTIONS: I'd like to just have one home.jsp but it looks like I have to pull the body content (and any other content) from a separate file. Is there an appropriate way to simplify home.jsp and home-body.jsp into one file, or am I actually doing this all correctly?

You need to update your tiles.xml, standard.jsp and home.jsp as below,
tiles.xml
<tiles-definitions>
<definition name="home" extends="standardLayout">
<put-attribute name="body" value="/WEB-INF/views/home.jsp"></put-attribute>
</definition>
</tiles-definitions>
standard.jsp
<html>
<title><tiles:insertAttribute name="title"/></title>
<header>
<tiles:insertAttribute name="header"/>
</header>
<body>
<tiles:insertAttribute name="body"/>
</body>
<footer>
<tiles:insertAttribute name="footer"/>
</footer>
</html>
home.jsp
<!-- Actual body content goes here.. -->
<%# taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<p>The content of the home page.</p>

Related

Spring Tiles Framework : refresh only body content

I have a Tiles layout page having Header, Menu, Body. In this layout whenever user does some action in the Menu lists, the whole Layout is refreshing. I want header,menu to be static, and only body part should get refresh.
Is there any way to prevent the refresh of the Header, menu and update only Body content on the menu click which can be implemented using Spring Tiles?
I got some same question but its related to structs. i don't have idea about structs
If anybody give piece of code it will be helpful.
(1)write this tiles configuration into spring xml file.
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"/>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<value>/WEB-INF/layouts/views.xml</value>
</list>
</property>
</bean>
(2)layouts.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="DefaultTemplate" template="/WEB-INF/views/template/SiteTemplate.jsp">
<put-attribute name="title" value="Home" />
<put-attribute name="header" value="/WEB-INF/views/template/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/views/template/menu.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/views/template/footer.jsp" />
</definition>
</tiles-definitions>
(3)views.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="index" extends="DefaultTemplate">
<put-attribute name="body" value="/WEB-INF/views/index.jsp" />
</definition>
<definition name="personList" extends="DefaultTemplate">
<put-attribute name="body" value="/WEB-INF/views/personList.jsp" />
</definition>
</tiles-definitions>
(4)SiteTemplate.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring MVC - Tiles Integration tutorial</title>
<link rel="stylesheet" href="resources/css/screen.css" type="text/css" media="screen, projection"></link>
<link rel="stylesheet" href="resources/css/print.css" type="text/css" media="print"></link>
<!--[if IE]>
<link rel="stylesheet" href="resources/css/ie.css" type="text/css" media="screen, projection">
<![endif]-->
<style>
body{ margin-top:20px; margin-bottom:20px; background-color:#DFDFDF;}
</style>
</head>
<body>
<div class="container" style="border: #C1C1C1 solid 1px; border-radius:10px;">
<!-- Header -->
<tiles:insertAttribute name="header" />
<!-- Menu Page -->
<div class="span-5 border" style="height:400px;background-color:#FCFCFC;">
<tiles:insertAttribute name="menu" />
</div>
<!-- Body Page -->
<div class="span-19 last">
<tiles:insertAttribute name="body" />
</div>
<!-- Footer Page -->
<tiles:insertAttribute name="footer" />
</div>
</body>
</html>
(5)menu.jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<ul style="list-style:none;line-height:28px;">
<li><spring:url value="/index" var="homeUrl" htmlEscape="true" />
Home
</li>
<li><spring:url value="/viewPeson" var="personListUrl" htmlEscape="true" />
Person List
</li>
</ul>
(6)same as write footer.jsp and header.jsp for your requirement.
(7)code for controlller
#RequestMapping(value="index")
public String index() {
return "index";
}
**NOTE:return type value is same as definition name in views.xml**

Specifying unique content for <head> section using apache tiles

I'm brand new to Tiles so this is probably a very easy question. I've created a web application using Java / Spring 3 / JSPs without the use of tiles and now I'm realizing my life would be much easier with it.
I'm a bit confused on one aspect thus far, and that's defining the layouts. My problem is that in examples I've seen online you define a layout.jsp which contains the information (including tags and tags).
My question is, the "layout.jsp" file is supposed to be the generic "one-size-fits-all" type of file, but what happens when I create another file (say welcome.jsp) which should USE the layout template, but I need to define more and tags... if I define them inside of the welcome.jsp file then the rendered JSP file is not formatted correctly... i.e:
<head>
<!-- This is content from the layout.jsp file -->
<title>Welcome</title>
<link rel="shortcut icon" href="images/favicon.ico"/>
<script type="text/javascript">
// some javascript
</script>
</head>
<body>
<!-- This is content from the welcome.jsp file which is malformed -->
<head>
<script src="js/jquery.mousewheel.min.js"></script>
</head>
</body>
Any help would be greatly appreciated.
Here's my tiles.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/jsp/layout/layout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/jsp/layout/header.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/jsp/layout/footer.jsp" />
</definition>
<definition name="videos" extends="baseLayout">
<put-attribute name="title" value="Videos" />
<put-attribute name="body" value="/WEB-INF/jsp/videos.jsp" />
</definition>
</tiles-definitions>
layout.jsp
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%# include file="../tracking.jsp" %>
<!DOCTYPE HTML>
<html>
<head>
<title><tiles:insertAttribute name="title" ignore="true" /></title>
<link rel="shortcut icon" href="images/favicon.ico"/>
<link href="css/templatemo_style.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="css/jquery-ui-1.10.css" media="screen" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.lightbox-0.5.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
</head>
<body>
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="body" />
<tiles:insertAttribute name="footer" />
</body>
</html>
Create a new definition to change the header content:
<definition name="baseLayout" template="/WEB-INF/jsp/layout/layout.jsp">
<!-- Defined here -->
<put-attribute name="head" value="" />
<put-attribute name="title" value="" />
...
</definition>
<definition name="videos" extends="baseLayout">
<!-- Overridden here -->
<put-attribute name="head" value="/WEB-INF/jsp/videos-additionalHeadDefinitions.jsp" />
...
</definition>
And add this to you layout.jsp:
<head>
<!-- This is content from the layout.jsp file -->
<title>Welcome</title>
...
<tiles:insertAttribute name="head" />
</head>

Spring MVC controller using #RequestParam with Apache tile 2

I am have the following configuration for my Spring MVC + Apache tile 2 project.
The Tile configuration
<definition name="test1" extends="mymain">
<put-attribute name="main">
<definition template="/WEB-INF/views/tiles/template/generictemplate.jsp">
<put-attribute name="headerstyle" value="./resources/css/header.css" type="string" />
<put-attribute name="genericcontent" value="/WEB-INF/views/tiles/test.jsp" />
</definition>
</put-attribute>
</definition>
<definition name="test2" extends="mymain">
<put-attribute name="main">
<definition template="/WEB-INF/views/tiles/template/generictemplate.jsp">
<put-attribute name="headerstyle" value="./resources/css/header.css" type="string" />
<put-attribute name="genericcontent" value="/WEB-INF/views/tiles/test.jsp" />
</definition>
</put-attribute>
</definition>
The controller
#RequestMapping(value="/test1", method=RequestMethod.GET)
public String test1(#RequestParam(value="id", required=true) String id){
return "test1";
}
#RequestMapping(value="/test2", method=RequestMethod.GET)
public String test2(){
return "test2";
}
The view generictemplate.jsp
<%# include file="include.jsp" %>
<tiles:importAttribute name="headerstyle" />
<link href="${headerstyle}" rel="stylesheet" type="text/css" />
<div role="main" class="main clearfix">
<section class="generic">
<div class="post">
<tiles:insertAttribute name="genericcontent"/>
</div>
</section>
<!-- end main -->
</div>
My problem is
When i am calling test2 (without parameter), the header.css can be read. But when test1 is called, I am getting 404 Not Found for header.css. I noticed that view is trying to access the css with path of http://localhost:8080/myproject/test1/resources/css/header.css instead of http://localhost:8080/myproject/resources/css/header.css when test1 is calling.
So why the #RequestParam makes this difference?
Thank.
This is because the css is being loaded relative to the current URL.
For test1 you have a param which adds a slash after test1. Where as test2 doesn't have the param, so its relative to the parent directory.
You could try using absolute paths for the css.

Tiles 2 Access Variable in Template

I am using the Spring MVC framework with Apache Tiles 2. I want to be able to have multiple controllers all use the same view (different logic, some basic presentation). I can do that easily. What I want now is to have different Tiles definitions for each controller, all using the same JSP file, but each passing different template variables (page header, short description, etc). This is my Tiles template definition file:
<tiles-definitions>
<!-- Default Main Template -->
<definition name=".mainTemplate" template="/WEB-INF/templates/main.jsp">
<put-attribute name="shortTitle" value="Company ABC" type="string" />
<put-attribute name="body" value="/WEB-INF/templates/blank.jsp" />
</definition>
<!-- Overriding Templates -->
<definition name="index" extends=".mainTemplate">
<put-attribute name="title" value="Company Alpha Bravo Charlie" type="string" />
<put-attribute name="body" value="/WEB-INF/views/index.jsp" />
</definition>
<definition name="index2" extends=".mainTemplate">
<put-attribute name="title" value="Company Other Page" type="string" />
<put-attribute name="body" value="/WEB-INF/views/index.jsp" />
</definition>
</tiles-definitions>
I then try to have this /WEB-INF/views/index.jsp:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<h1>
Hello world, it's <tiles:getAsString name="title" />!
</h1>
When I load this into Tomcat and bring up the page, I get a long stack trace of exceptions. The top of the pile says org.apache.tiles.impl.CannotRenderException: ServletException including path '/WEB-INF/templates/main.jsp'.} with root cause org.apache.tiles.template.NoSuchAttributeException: Attribute 'title' not found. Anybody know what's going on?
I then try to have this /WEB-INF/views/index.jsp:
How do you try this? In your controller you would specify the name of the Tiles view, not one of the multiple JSP Tiles will use in order to render the page:
#RequestMapping("index2")
public String index2() {
// ...
return "index2";
}

Best way to set HTML head title in a Spring+Tiles2 application?

I have a usability problem in my Spring webapp which uses Tiles as the view technology.
At the moment all of the pages display the same HEAD_TITLE and the PAGE_TITLE is page specific:
<html>
<head><title>HEAD_TITLE</title></head>
<body>
<h1>PAGE_TITLE</h1>
</body>
</html>
This is a major usability problem as the browsers history lists all different pages of the application with the same title. The reason why the HEAD_TITLE is same for all pages is that I haven't found a reasonable way to use the PAGE_TITLE as the HEAD_TITLE.
In most cases the PAGE_TITLE comes from a message bundle with <fmt:message /> tag and
some parameters are passed to it. The Tiles layout is such that the HEAD_TITLE should be already set at that point because all pages of the webapp use the same common layout which defines the <HEAD> elements of the pages amongst other stuff.
Any suggestions how to fix this usability problem? Should I set a "pageTitle" request attribute in my Spring controllers for all pages and use that as the PAGE_TITLE and also as the HEAD_TITLE? Or is it possible to somehow set the HEAD_TITLE in the page specific JSP?
Create a general definition and define headTitle and pageTitle attributes.
<definition name="threeColumnLayout" template="/WEB-INF/ThreeColumnLayout.jsp" >
<put-attribute name="headTitle" value="" />
<put-attribute name="pageTitle" value="" />
<put-attribute name="left" value="/WEB-INF/left.jsp" />
<put-attribute name="middle" value="" />
<put-attribute name="right" value="/WEB-INF/right.jsp" />
</definition>
Set appropriate values in more specific definition.
<definition name="/user/new" extends="threeColumnLayout">
<put-attribute name="headTitle" value="Administration" />
<put-attribute name="pageTitle" value="Create User" />
<put-attribute name="middle" value="WEB-INF/views/UserCreate.jsp" />
</definition>
Use <tiles:getAsString /> tag to retrieve such values in jsp page.
<head>
<title><tiles:getAsString name="headTitle"/></title>
</head>
<body>
<h1>
<title><tiles:getAsString name="pageTitle"/></title>
</h1>
</body>
Reference:- http://tiles.apache.org/framework/tiles-jsp/tagreference.html#tiles:getAsString

Resources