I've inherited an old application that is using Struts 1.2 Tiles 1. For various annoying reasons I can't upgrade.
I'm not very familiar with Struts, or specifically Tiles in general and I'm trying to do something that makes sense in my head but I can't seem to make work in practice. Here's an example of what I'm trying to accomplish:
<tiles-definition>
<definition name="content-with-sidebar" path="/content_with_sidebar.jsp">
<put name="top" value="" type="string" />
<put name="sidebar" value="/tiles/sidebar.jsp" />
<put name="main" value="" type="string" />
<put name="bottom" value="" type="string" />
</definition
</tiles-definition>
content_with_sidebar.jsp
...
<tiles:insert attribute="top" flush="false" />
<div id="content">
<aside>
<tiles:insert attribute="sidebar" flush="false" />
</aside>
<div id="main">
<tiles:insert attribute="main" flush="false" />
</diV>
</div>
<tiles:insert attribute="top" flush="false" />
...
actual_page.jsp
<tiles:insert definition="content-with-sidebar" flush="false">
<tiles:put name="top" type="string">
<div>Maybe this page has something on the top that isn't the page header</div>
</tiles:put>
<!-- use the default sidebar -->
<tiles:put name="main">
<strong>Current Location:</strong>
<address><h:outputText value="#{locationDesc} #{zipCode}" /></address>
<!-- Some more dynamic jsp markup -->
</tiles:put>
<!-- This one doesn't have anything extra on the bottom -->
</tiles:insert>
This almost works but the dynamic bits get rendered above and outside the <tiles:insert> and the plain strings go where they should. I understand now, after much searching, that <tiles:put> in this, er, context, is expecting a plain ole string.
Is there a pattern to accomplish what I want with dynamic context?
As it stands I'm having to create another jsp file to be referenced by the <tiles:put> tag. i.e.
<tiles:put name="main" value="/actual_page_body.jsp" />
I'd rather not have to create an additional file when one would do. Any advice would be helpful.
With tiles, when the definition is rendered (content-with-sidebar in your code), the jsp corresponding to the 'path' attribute (/content_with_sidebar.jsp) will be invoked. All other jsps have to be manually invoked using a <tiles:insert>. What tiles provides you is a way to configurationally invoke them as definition attributes.
Related
I am facing a crazy issue. On form submit if any word contains 'script' (Eg: De'script'ion) then that will b truncated, hence remaining with 'Deion' ('script' removed from 'Description'). Could not find the reason for it.. I am using Velocity Templates for UI and Struts 1.x
Form Bean
<form-bean name="newUserForm" dynamic="true" type="com.test.fe.webapp.form.NewUserForm">
<form-property name="userId" type="java.lang.String" />
<form-property name="role" type="java.lang.String" />
<form-property name="selectedPartnersMultiSelect" type="java.lang.String[]" />
<form-property name="isExistingUser" type="java.lang.String" />
</form-bean>
Found the root cause for this..
Our application has applied a Filter to prevent Cross Site Scripting(XSS) attacks, hence this issue was occuring..
Thanks
I'm developing a simple tag library in order to centralize the creation of form components.
In my custom tag I need to get the value of the backing object mapped field.
Here is how I pass the field name value to my library:
<jsp:directive.attribute name="field" type="java.lang.String" required="true" rtexprvalue="true" description="The field exposed from the form backing object" />
Inside my tag library, using <form:hidden path="${field}.id" /> from spring tag library works, but how can I get same value not using that library? I do not want to have an input type hidden mapped in my form, but only retrieve the value of that field name.
Thanks for any hints.
You can try the spring:eval tag
<jsp:directive.attribute name="object" type="java.lang.Object" required="true" description="The form backing object" />
<jsp:directive.attribute name="field" type="java.lang.String" required="true" description="The field name" />
<spring:eval expression="object[field]" />
I am a user of JSF and Richfaces. I will simplify the code about my question to make things easier.
I have a composition named 'mytab.xhtml' defined like following:
<cc:interface>
<cc:attribute name="header" required="true"/>
</cc:interface>
<cc:implementation>
<rich:tab id="my-tab" header="#{cc.attrs.header}" >
<cc:insertChildren />
</rich:tab>
</cc:implementation>
This composition is used in another xhtml file like following:
<rich:tabPanel id="tp" switchType="ajax" headerPosition="top" >
<ic:mytab id="tab1" header="header1">
<h:outputText>content1</h:outputText>
</ic:mytab>
<ic:mytab id="tab2" header="header2">
<h:outputText>content1</h:outputText>
</ic:mytab>
</rich:tabPanel>
But it is very strange that the tab is not rendered at all.
To find the reason, if I add an outputText in the composition definition file like this:
<cc:interface>
<cc:attribute name="header" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputText>#{cc.attrs.header}</h:outputText>
<rich:tab id="my-tab" header="#{cc.attrs.header}" >
<cc:insertChildren />
</rich:tab>
</cc:implementation>
The outputText will be rendered, but tab is not rendered.
Or, if I change one of the tab to richfaces tab directly:
<rich:tabPanel id="tp" switchType="ajax" headerPosition="top" >
<ic:mytab id="tab1" header="header1">
<h:outputText>content1</h:outputText>
</ic:mytab>
<rich:tab id="tab2" header="header2">
<h:outputText>content1</h:outputText>
</rich:tab>
</rich:tabPanel>
The first tab will not be rendered, but the second tab will be rendered.
Thank you if you could give me any help.
Composite components are rendered as own UINamingContainer. So between the UITabPanel and the UITab-component now is a UINamingContainer, UITab might not know what to do with it (same problem with datatable, by the way). What you can do is to use a classic facelet tag instead.
Hello I have a form input button as follows :
<form:input path="creationUsr.lastName" type="text" name="creationUsr.lastName" id="creationUsr.lastName" class="login-text" placeholder="<spring:message code='tile.form.lastName'/>" value=""/>
Here is my spring context locale setting :
<mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
If I put this out of form tag :
<spring:message code='tile.form.lastName'/>
The value is as I should be.
I have a way around this but it's kind of ugly. I could revert to normal forms without using spring and regular <input type="text" name="lastname"> instead of <form:input .. and then serialize form to json and do a post with javascript.
I'm sure there must be a way to do this with spring mvc.
You can't use a JSP tag inside an attribute of another JSP tag. To do what you want, save the message in a page-scope attribute, and use the EL to pass the message to the input tag:
<spring:message code='tile.form.lastName' var="lastNameMessage"/>
<form:input path="creationUsr.lastName"
type="text"
name="creationUsr.lastName"
id="creationUsr.lastName"
class="login-text"
placeholder="${lastNameMessage}"
value=""/>
Problem: I have two identical pages home.jsp and contact.jsp with same structure. They differs only in body content and title. I want to create a Layout page using tiles framework and reuse the code for the two JSPs. The controller framework is yet not decided, it may be Spring MVC 3 or Struts 2.
Solution A: Calling JSP files/views directly from controller/action classes.
I write a single definition in tiles.xml like:
<definition name="baseLayout" template="/WEB-INF/jsp/layout/baseLayout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/jsp/includes/header.jsp"/>
<put-attribute name="body" value="" />
</definition>
Now in baseLayout.jsp:
<html>
<head><title><tiles:insertAttribute name="title"/></title></head>
<body>
<div class="wrapper">
<div class="header"><tiles:insertAttribute name="header"/></div>
<div class="body"><tiles:insertAttribute name="body"/></div>
</div>
</body>
</html>
Now in home.jsp
<tiles:insertDefinition name="baseLayout">
<tiles:putAttribute name="title">
Title for home page
</tiles:putAttribute>
<tiles:putAttribute name="body">
Content for home page
</tiles:putAttribute>
</tiles:insertDefinition>
Similarly for contact.jsp :
<tiles:insertDefinition name="baseLayout">
<tiles:putAttribute name="title">
Title for contact page
</tiles:putAttribute>
<tiles:putAttribute name="body">
Content for contact page
</tiles:putAttribute>
</tiles:insertDefinition>
Solution B: Calling the tiles definition of different JSP files from cotrollers/action classes. This approach requires one tiles definition for each of the JSP file I would be writing. So altogether 3 tiles definitions (one is for baseLayout and other two are for home and contact).
tiles.xml :
<definition name="baseLayout" template="/WEB-INF/jsp/layout/baseLayout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/jsp/includes/header.jsp"/>
<put-attribute name="body" value="" />
</definition>
<definition name="home" extends="baseLayout">
<put-attribute name="title" value="Title for home page" />
<put-attribute name="header" value="/WEB-INF/jsp/home.jsp"/>
</definition>
<definition name="contact" extends="baseLayout">
<put-attribute name="title" value="Title for contact page" />
<put-attribute name="header" value="/WEB-INF/jsp/contact.jsp"/>
</definition>
baseLayout.jsp : Same as **Solution A**
home.jsp : Content for home page
contact.jsp : Content for contact page
I want advice on which one of the above approaches I should stick to.
The second solution is the best way:
You can have independent section in your tiles properties for each
jsp layout.
You can change anytime without effecting other layouts later on
The most traditional way using in struts
First solution:
May cause problems later on with having to edit them with any change
specially when you are deep in the project in advanced levels
More generic approach not suitable for struts/tiles architectural
designs
Solution B is the best approach to implement,
you will have individual style template what you can reuse later if required for other jsp's without messing the code in jsp like Solution A.
As of understanding the second approach is more clear and a common standard to follow.
Solution A helps maintenance in large applications by distributing configuration and also promoting name convention over explicit configuration. Moreover it is conceptually compatible with other templating solutions such as JSF or plain tags. For example see this: JSP tricks to make templating easier?
Think an application with hundreds of controllers and views written by different people over a large period of time. With solution B you will have to face a huge tiles.xml file. Add a slight lack of discipline and view names end up an inconsistent mess and content present inside the configuration (like your example).