I'm using Apache Tiles on a Sprint MVC app and I have this tiles.xml:
<tiles-definitions>
<definition name="defaultLayout" template="/WEB-INF/tiles/template/defaultLayout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/tiles/template/header.jsp" />
<put-attribute name="content" value=""/>
<put-attribute name="footer" value="/WEB-INF/tiles/template/footer.jsp" />
</definition>
<definition name="home" extends="defaultLayout">
<put-attribute name="title" value="Alsa" />
<put-attribute name="content" value="/WEB-INF/pages/home.jsp" />
<put-attribute name="active" value="index" />
</definition>
</tiles-definitions>
What I'm trying to do is use the attribute active to add a class to active menu item. For that I have this in header.jsp:
<%# taglib uri="http://tiles.apache.org/tags-tiles-extras" prefix="tilesx" %>
<tilesx:useAttribute name="active" />
The problem is that everytime I try to render the page I get this error:
org.apache.tiles.template.NoSuchAttributeException: Error importing
attributes. Attribute 'active' is null
What am I doing wrong?
The trick here is to add cascade=true to your attribute so that it will be available to nested definitions and templates.
<definition name="home" extends="defaultLayout">
<put-attribute name="title" value="Alsa" />
<put-attribute name="content" value="/WEB-INF/pages/home.jsp" />
<put-attribute name="active" value="index" cascade="true"/>
</definition>
See:
https://tiles.apache.org/framework/tutorial/advanced/nesting-extending.html
You may need to declare the class. You'll also need id.
<tilesx:useAttribute name="active" id="active" class="java.lang.String"/>
Also if there are other tiles definitions in your app other than "home" and if any of them do not define an "active" attribute, you may want to set "ignore" to true as part of your definition to avoid runtime errors. More here:https://tiles.apache.org/framework/tiles-jsp/tlddoc/index.html
Related
This is my viewstiles xml code.
I don't know meaning of {1}
in my web-init>views>home folder, i have two files - home.jsp , home1.jsp
<definition name="home/*" extends="page.layout">
<put-attribute name="body" value="/WEB-INF/views/home/{1}.jsp" />
</definition>
what is meaning of {1},home/*, page.layout?
It's Apache tiles.
Suppose you have the following definition:
<definition name="bank/user" template="/layout.jsp">
<put-attribute name="header" value="/header.jsp"/>
<put-attribute name="body" value="/user.jsp"/>
</definition>
<definition name="bank/account" template="/layout.jsp">
<put-attribute name="header" value="/header.jsp"/>
<put-attribute name="body" value="/account.jsp"/>
</definition>
don't you think if will be much better if we could do it like this:
<definition name="bank/*" template="/layout.jsp">
<put-attribute name="header" value="/header.jsp"/>
<put-attribute name="body" value="/{1}.jsp"/>
</definition>
{1} refers to the star's value which is "user" in that case
* eliminates the repetition
I hope that's clear.
For more infos: see
I have configured tiles for Spring web project.
The tiles.xml looks as follows
<tiles-definitions>
<definition name="template" template="/WEB-INF/jsp/template.jsp">
<put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
<put-attribute name="body" value="/WEB-INF/jsp/ads.jsp "/>
<put-attribute name="center" value="/WEB-INF/jsp/ads.jsp" />
<put-attribute name="footer" value="/WEB-INF/jsp/footer.jsp" />
</definition>
<definition name="header" extends="template">
<put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
<put-attribute name="body" value="/WEB-INF/jsp/ads.jsp" />
</definition>
<definition name="numberResult" extends="template">
<put-attribute name="body" value="/WEB-INF/jsp/numberResult.jsp" />
</definition>
<definition name="nameResult" extends="template">
<put-attribute name="body" value="/WEB-INF/jsp/nameResult.jsp" />
</definition>
</tiles-definitions>
Now my problem is I have an input field titled studentName in header.jsp.
Lets say user enter "abcd" in that input field. I pass it to controller and I return to nameResult.jsp (where now also the page has header.jsp as part of tiles).
I want to fix the following two issues.
1) I want to retain "abcd" in the input field in header.jsp when I return from controller and display it to user in the input field.
2) I also want to use the value "abcd"(which is in header.jsp) from nameResult.jsp for a AJAX request.
header.jsp code
<div id="mycontainer">
<form method="get" action="number" id="number">
<!-- <div id="regNoErrorMsgNumber">Only numbers are allowed</div> -->
<div style="text-align: center;" >
<!-- //TODO: Only number, no spaces, no special symbol and 12 digit check-->
<input width="20" type="text" data-validation="numbers" id="regNo" name="regNo" size="30" maxLength="50" placeholder="Enter Register Number"> <b>OR</b>
</div>
</form>
<form method="post" action="name" id="name">
<input type="text" id="studentName" name="studentName" size="30" maxLength="50" placeholder="Enter Student Name"></input>
<c:set var="salary" scope="session" value="${2000*2}"/>
</form>
</div>
I am presuming you already have a controller method who return type is ModelAndView. All you need to do is use the addObject(parameterName, parameterValue); method of ModelAndView and you should be able to get the value back on JSP, and also you will be able to use that value to make your AJAX request
<tiles-definitions>
<definition name="home" template="/WEB-INF/views/home.jsp">
<put-attribute name="title" value="My App" />
<put-attribute name="header" value="/WEB-INF/views/common/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/views/common/nav.jsp" />
<put-attribute name="footer" value="/WEB-INF/views/common/footer.jsp" />
</definition>
</tiles-definitions>
How do I propagate the title value (My App) to header.jsp? In header jsp, when I do:
<tiles:insertAttribute name="title" ignore="true" />
nothing is printed. When I do the same in home.jsp, My App is printed. cascaded=true has not helped.
It's not clear where you tried putting that cascade=true (assuming it's a typo in your question: it should be "cascade", not "cascaded") but the following works as expected:
tiles.xml:
<tiles-definitions>
<definition name="home" template="/WEB-INF/views/home.jsp">
<put-attribute name="title" value="My App" cascade="true"/>
<put-attribute name="header" value="/WEB-INF/views/common/header.jsp" />
(...)
</definition>
</tiles-definitions>
home.jsp:
Title: <tiles:insertAttribute name="title" /> <br/>
Header: <tiles:insertAttribute name="header" />
header.jsp:
Title in header: <tiles:insertAttribute name="title" />
The output is:
Title: My App
Header: Title in header: My App
I'm using Spring MVC 3.1 and Tiles 2.
I have this Tile:
<ul class="nav">
<li class="active">Person</li>
<li>Student</li>
<li>Superadmin</li>
</ul>
And the tiles.xml:
<tiles-definitions>
<definition name="base.definition" template="/WEB-INF/pages/tiles/template.jsp">
<put-attribute name="meta" value="/WEB-INF/pages/tiles/meta.jsp" />
<put-attribute name="head" value="/WEB-INF/pages/tiles/head.jsp" />
<put-attribute name="navbar" value="/WEB-INF/pages/tiles/navbar.jsp" />
<put-attribute name="sidebar" value="/WEB-INF/pages/tiles/sidebar.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/pages/tiles/footer.jsp" />
</definition>
<definition name="user.new" extends="base.definition">
<put-attribute name="body" value="/WEB-INF/pages/user.new.jsp" />
</definition>
<definition name="user.show" extends="base.definition">
<put-attribute name="page_title" value="Tiles tutorial homepage" type="string"/>
<put-attribute name="section_title" value="User's list" type="string"/>
<put-attribute name="body" value="/WEB-INF/pages/user.show.jsp" />
</definition>
<definition name="login" template="/WEB-INF/pages/login.jsp">
<put-attribute name="meta" value="/WEB-INF/pages/tiles/meta.jsp" />
<put-attribute name="head" value="/WEB-INF/pages/tiles/head.jsp" />
<put-attribute name="body" value="/WEB-INF/pages/login.jsp" />
</definition>
</tiles-definitions>
Now, I want to set the class "active" for the selected menu.
Can I do that with Tiles? Or I have to look up with Spring?
Approach 1 - JSP/JSTL and Spring/Bean
Change your menu tile to build the menu using a list of some menu-object, which you can set on the session/model. The menu-object could have a boolean flag indicating which one to set the active class on.
Approach 2 - JavaScript/Session
If you don't want to do it this way, you could use a combination of HTML classes, JavaScript, and a session/model attributeto accomplish the task. What you would do is overload the class attribute on your LI elements, something like:
<ul class="nav">
<li class="person">Person</li>
<li class="student">Student</li>
<li class="superadmin">Superadmin</li>
</ul>
You would then have a little JS, using JSTL to get the class, to select the proper LI element and set the class. With jQuery it might look like:
$(document).ready(function() {
$('.${mySelectedClass}').addClass('active');
});
This will use jQuery to select the proper LI and add the 'active' class to it.
Approach 3 - Pure JSTL using URL
If you don't like tying your menu to the presence of an attribute, and you know your URL will, when parsed, will have some information you could use to determine which LI to set as active, you could use that. You can get the current page's URL like
<c:out value="${pageContext.request.requestURL}"/>
Parse ${pageContext.request.requestURL} in some meaningful way, and you could use it to determine which is active.
Approach 4 - Pure JavaScript using URL
Same as above, but using JavaScript to get the current URL, parse it, and manipulate the DOM as we did in approach 2.
Hopefully one of these help you.
I have a Spring application which uses Tiles for the view tier. So all my pages definitions look like this:
<definition name="main.page" template="/tiles/layout.jsp">
<put-attribute name="title" value="Page Title"/>
<put-attribute name="header" value="/tiles/header.jsp"/>
<put-attribute name="body" value=""/>
<put-attribute name="footer" value="/tiles/footer.jsp"/>
</definition>
<definition name="welcome.page" extends="main.page">
<put-attribute name="title" value="Main Page"/>
<put-attribute name="body" value="/pages/welcome.jsp"/>
</definition>
The code which sets page title is:
<title><tiles:getAsString name="title"/></title>
I would like to localize with Spring tag:
<spring:message>
Are there any "best practices" how to do that?
Did you ever tried to put the message key in you tiles variable and use it as key for the spring message tag.
Something like that:
<definition name="welcome.page" extends="main.page">
<put-attribute name="titleKey" value="page.main.title"/>
<put-attribute name="body" value="/pages/welcome.jsp"/>
</definition>
jsp:
<set var"titleKey"><tiles:getAsString name="titleKey"/></set>
<title><spring:message code=${titleKey} /></title>
The previous answer contains several little mistakes
tiles.xml
<definition name="main" template="/WEB-INF/jsp/template.jsp">
<put-attribute name="titleKey" value="main.title" />
<put-attribute name="body" value="/WEB-INF/jsp/main.jsp" />
</definition>
jsp (/WEB-INF/jsp/template.jsp)
<c:set var="titleKey"><tiles:getAsString name="titleKey"/></c:set>
<title><spring:message code="${titleKey}"></spring:message> </title>