Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Issue number: SIM-90

Obtained from: JIRA
Submitted by:  rhallier
Reviewed by:   
CVS: ----------------------------------------------------------------------
CVS: Issue number:
CVS:   If this change addresses one or more issues,
CVS:   then enter the issue number(s) here.
CVS: Obtained from:
CVS:   If this change has been taken from another system,
CVS:   then name the system in this line, otherwise delete it.
CVS: Submitted by:
CVS:   If this code has been contributed to the project by someone else; i.e.,
CVS:   they sent us a patch or a set of diffs, then include their name/email
CVS:   address here. If this is your work then delete this line.
CVS: Reviewed by:
CVS:   If we are doing pre-commit code reviews and someone else has
CVS:   reviewed your changes, include their name(s) here.
CVS:   If you have not had it reviewed then delete this line.
  • Loading branch information...
commit ecf3df658873196d1140bb3b81ba8c0cfb2160f0 1 parent 65838bb
rhallier authored
View
2  .cvsignore
@@ -5,3 +5,5 @@ velocity.log*
maven.log*
clover
*.i*
+.classpath
+.project
View
2  build.xml
@@ -115,6 +115,7 @@
<lib dir="${lib.dir}">
<include name="commons-*.jar"/>
<include name="velocity-*.jar"/>
+ <include name="freemarker.jar"/>
</lib>
</war>
</target>
@@ -127,6 +128,7 @@
<user displayname="Mathias Bogaert" userid="mbogaert"/>
<user displayname="Scott Farquhar" userid="farkas"/>
<user displayname="Mike Cannon-Brookes" userid="rebelutionary"/>
+ <user displayname="Richard Hallier" userid="rhallier"/>
</cvschangelog>
<mkdir dir="${dist.dir}/docs"/>
View
124 docs/freemarker-decorators.html
@@ -0,0 +1,124 @@
+<html>
+ <head>
+ <title>Freemarker Decorators</title>
+ </head>
+
+ <body>
+ As of SiteMesh 2.0.2 <a href="http://freemarker.sourceforge.net/" target="_blank">Freemarker</a> (.ftl)
+ decorators are supported.
+
+ <p>Here is an example of how such a decorator might look like:</p>
+
+<pre style="border: 1px solid #999999; padding: 5px">
+<#include "/includes/decorators/header.dec">
+ &lt;h2&gt;<b>${title}</b>&lt;/h2&gt;
+ <b>${head}</b>
+ &lt;img src="<b>${base}</b>/images/logo.gif" border="0"&gt;
+ &lt;td valign="top" class="body"&gt;
+ &lt;div class="header"&gt;
+ &lt;span class="pagetitle"&gt;<b>${title}</b>&lt;/span&gt;
+ &lt;/div&gt;
+ <b>${body}</b>
+ &lt;/td&gt;
+<#include "/includes/decorators/footer.dec">
+</pre>
+
+ <h3>Installation</h3>
+
+ <ul>
+
+ <li>Download <a
+ href="http://freemarker.sourceforge.net/" target="_blank">Freemarker</a> 2.3 (recommended) and copy it into <b><code>[web-app]/WEB-INF/lib</code></b>.
+ The SiteMesh distribution comes with <b>freemarker.jar</b> v2.3rc3</p></li>
+
+ <li>Add the following to <b><code>[web-app]/WEB-INF/web.xml</code></b>
+ within the <b><code>&lt;web-app&gt;</code></b> tag:</li>
+ </ul>
+
+<pre style="border: 1px solid #999999; padding: 5px">
+&lt;servlet&gt;
+ &lt;servlet-name&gt;sitemesh-freemarker&lt;/servlet-name&gt;
+ &lt;servlet-class&gt;com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet&lt;/servlet-class&gt;
+ &lt;init-param&gt;
+ &lt;param-name&gt;TemplatePath&lt;/param-name&gt;
+ &lt;param-value&gt;/&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ &lt;init-param&gt;
+ &lt;param-name&gt;default_encoding&lt;/param-name&gt;
+ &lt;param-value&gt;ISO-8859-1&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
+&lt;/servlet&gt;
+
+&lt;servlet-mapping&gt;
+ &lt;servlet-name&gt;sitemesh-freemarker&lt;/servlet-name&gt;
+ &lt;url-pattern&gt;*.dec&lt;/url-pattern&gt;
+&lt;/servlet-mapping&gt;
+</pre>
+
+ <ul>
+ <li>Modify <b><code>decorators.xml</code></b> to reference a .dec file.</li>
+ </ul>
+
+<pre style="border: 1px solid #999999; padding: 5px">
+<#include "/includes/decorators/header.dec">
+ &lt;h2&gt;<b>${title}</b>&lt;/h2&gt;
+ <b>${head}</b>
+ &lt;img src="<b>${base}</b>/images/logo.gif" border="0"&gt;
+ &lt;td valign="top" class="body"&gt;
+ &lt;div class="header"&gt;
+ &lt;span class="pagetitle"&gt;<b>${title}</b>&lt;/span&gt;
+ &lt;/div&gt;
+ <b>${body}</b>
+ &lt;/td&gt;
+<#include "/includes/decorators/footer.dec">
+</pre>
+
+ <h3>Context</h3>
+
+ <p>FreemarkerDecoratorServlet puts some things into the context object that you should be aware of: </p>
+
+ <h4>Basic context attributes</h4>
+ <p>
+ <li>It makes all request, request parameters, session, and servlet context attributes available to templates through Request, RequestParameters, Session, and Application variables. For example :
+ <pre style="border: 1px solid #999999; padding: 5px">${Session["user"]}</pre>
+ </li>
+
+ <li>The scope variables are also available via automatic scope discovery. That is, writing Application.attrName, Session.attrName, Request.attrName is not mandatory; it's enough to write attrName, and if no such variable was created in the template, it will search the variable in Request, and then in Session, and finally in Application. </li>
+ <pre style="border: 1px solid #999999; padding: 5px">
+&lt;#assign ww=JspTaglibs["/WEB-INF/webwork.tld"]&gt;</pre>
+ </li>
+
+ <li>It creates a variable with name JspTaglibs, that can be used to load JSP taglibs. For example:
+ <pre style="border: 1px solid #999999; padding: 5px">
+&lt;#assign ww=JspTaglibs["/WEB-INF/webwork.tld"]&gt;
+...
+&lt;@ww.property value="myVar"/&gt; </pre>
+ </li>
+ </p>
+
+ <h4>Sitemesh context attributes</h4>
+ <table border="0" cellspacing="10">
+ <tr>
+ <td valign="top"><strong>base</strong></td>
+ <td>request.getContextPath()</td>
+ </tr>
+ <tr>
+ <td valign="top"><strong>title</strong></td>
+ <td>Parsed page title (&lt;title&gt;...&lt;title&gt;)</td>
+ </tr>
+ <tr>
+ <td valign="top"><strong>head</strong></td>
+ <td>Parsed page head</td>
+ </tr>
+ <tr>
+ <td valign="top"><strong>body</strong></td>
+ <td>Parsed page body</td>
+ </tr>
+ <tr>
+ <td valign="top"><strong>page</strong></td>
+ <td>SiteMesh's internal Page object</td>
+ </tr>
+ </table>
+</body>
+</html>
View
1  docs/navpanel.jsp
@@ -15,6 +15,7 @@
<a href="<%= request.getContextPath() %>/sitemesh/charsets.html">Character Sets</a><br>
<a href="<%= request.getContextPath() %>/sitemesh/decorators.html">Building Decorators</a><br>
<a href="<%= request.getContextPath() %>/sitemesh/velocity-decorators.html">Velocity Decorators</a><br>
+ <a href="<%= request.getContextPath() %>/sitemesh/freemarker-decorators.html">Freemarker Decorators</a><br>
<a href="<%= request.getContextPath() %>/sitemesh/dm.html">Decorator Mappers</a><br>
<a href="<%= request.getContextPath() %>/sitemesh/testsuite.html">Test Suite</a><br>
<a href="<%= request.getContextPath() %>/sitemesh/faq.html">FAQ</a><br>
View
BIN  lib/freemarker.jar
Binary file not shown
View
4 src/example-webapp/WEB-INF/decorators.xml
@@ -15,6 +15,10 @@
<pattern>/velocity.html</pattern>
</decorator>
+ <decorator name="freemarker" page="freemarker.ftl">
+ <pattern>/freemarker.html</pattern>
+ </decorator>
+
<decorator name="test" page="test.jsp">
<pattern>/agent.jsp</pattern>
</decorator>
View
19 src/example-webapp/WEB-INF/web.xml
@@ -19,9 +19,28 @@
<load-on-startup>10</load-on-startup>
</servlet>
+ <servlet>
+ <servlet-name>sitemesh-freemarker</servlet-name>
+ <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class>
+ <init-param>
+ <param-name>TemplatePath</param-name>
+ <param-value>/</param-value>
+ </init-param>
+ <init-param>
+ <param-name>default_encoding</param-name>
+ <param-value>ISO-8859-1</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
<servlet-mapping>
<servlet-name>sitemesh-velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>sitemesh-freemarker</servlet-name>
+ <url-pattern>*.ftl</url-pattern>
+ </servlet-mapping>
+
</web-app>
View
18 src/example-webapp/decorators/freemarker.ftl
@@ -0,0 +1,18 @@
+<html>
+ <head>
+ <title>Velocity Decorator - ${title}</title>
+ <link href="${base}/decorators/main.css" rel="stylesheet" type="text/css">
+ ${head}
+ </head>
+
+ <body>
+ <div id="pageTitle">${title}</div>
+ <hr/>
+
+ ${body}
+
+ <div id="footer">
+ <b>Disclaimer:</b> This site is an example site to demonstrate SiteMesh. It serves no other purpose.
+ </div>
+ </body>
+</html>
View
12 src/example-webapp/freemarker.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <title>Freemarker Test</title>
+ </head>
+ <body>
+
+ <p>This page is decorated by the FreemarkerDecoratorServlet.</p>
+
+ <p>Go <a href="index.html">back</a>.</p>
+
+ </body>
+</html>
View
1  src/example-webapp/index.html
@@ -16,6 +16,7 @@
<li><a href="agent.jsp">Agent Mapped Decorator</a></li>
<li><a href="meta.html">Meta Test</a></li>
<li><a href="velocity.html">Velocity Decorator</a></li>
+ <li><a href="freemarker.html">Freemarker Decorator</a></li>
<li><a href="badpanel.html">Invalid panel source Test (not found)</a></li>
<li><a href="badsource.html">Invalid panel source Test (incorrect JSP)</a></li>
</ul>
View
86 src/java/com/opensymphony/module/sitemesh/freemarker/FreemarkerDecoratorServlet.java
@@ -0,0 +1,86 @@
+/*
+ * Title: FreemarkerDecoratorServlet Description:
+ *
+ * This software is published under the terms of the OpenSymphony Software License version 1.1, of which a copy has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+
+package com.opensymphony.module.sitemesh.freemarker;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.opensymphony.module.sitemesh.HTMLPage;
+import com.opensymphony.module.sitemesh.RequestConstants;
+import com.opensymphony.module.sitemesh.util.OutputConverter;
+
+import freemarker.ext.servlet.FreemarkerServlet;
+import freemarker.template.SimpleHash;
+import freemarker.template.Template;
+import freemarker.template.TemplateModel;
+
+/**
+ * Servlet that allows Freemarker templates to be used as decorators.
+ *
+ * @author <a href="mailto:richard.hallier@freesbee.fr">Richard HALLIER</a>
+ * @version $Revision: 1.1 $
+ */
+public class FreemarkerDecoratorServlet extends FreemarkerServlet
+{
+ /* (non-Javadoc)
+ * @see freemarker.ext.servlet.FreemarkerServlet#preTemplateProcess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, freemarker.template.Template, freemarker.template.TemplateModel)
+ */
+ protected boolean preTemplateProcess(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ Template template,
+ TemplateModel templateModel)
+ throws ServletException, IOException
+ {
+ boolean result=super.preTemplateProcess(request, response, template, templateModel);
+
+ SimpleHash hash = (SimpleHash) templateModel;
+
+ HTMLPage htmlPage = (HTMLPage) request.getAttribute(RequestConstants.PAGE);
+
+ String title, body, head;
+
+ if(htmlPage==null)
+ {
+ title="No Title";
+ body="No Body";
+ head="<!-- No head -->";
+ }
+ else
+ {
+ title=htmlPage.getTitle();
+
+ StringWriter buffer = new StringWriter();
+ htmlPage.writeBody(OutputConverter.getWriter(buffer));
+ body=buffer.toString();
+
+ buffer = new StringWriter();
+ htmlPage.writeHead(OutputConverter.getWriter(buffer));
+ head=buffer.toString();
+
+ hash.put("page",htmlPage);
+ }
+
+ hash.put("title",title);
+ hash.put("body",body);
+ hash.put("head",head);
+ hash.put("base",request.getContextPath());
+
+ /*
+ Factory factory = Factory.getInstance(new Config(getServletConfig()));
+ Decorator decorator = factory.getDecoratorMapper().getDecorator(request, htmlPage);
+ -> decorator.getPage()
+ */
+
+ return result;
+ }
+}
View
3  src/java/com/opensymphony/module/sitemesh/mapper/EnvEntryDecoratorMapper.java
@@ -10,7 +10,6 @@
package com.opensymphony.module.sitemesh.mapper;
import com.opensymphony.module.sitemesh.Decorator;
-import com.opensymphony.module.sitemesh.Page;
import javax.naming.Context;
import javax.naming.InitialContext;
@@ -37,7 +36,7 @@
* </ol>
*
* @author <a href="mailto:joeo@enigmastation.com">Joseph B. Ottinger</a>
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*
* @see com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper
*/
View
3  src/java/com/opensymphony/module/sitemesh/parser/FastPageParser.java
@@ -17,7 +17,6 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
-import java.util.Collection;
import java.io.IOException;
import java.io.Reader;
@@ -27,7 +26,7 @@
* <p>Produces FastPage.</p>
*
* @author <a href="mailto:salaman@qoretech.com">Victor Salaman</a>
- * @version $Revision: 1.9 $
+ * @version $Revision: 1.10 $
*/
public final class FastPageParser implements PageParser
{
View
3  src/java/com/opensymphony/module/sitemesh/taglib/page/ApplyDecoratorTag.java
@@ -20,7 +20,6 @@
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
-import java.io.DataInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
@@ -50,7 +49,7 @@
* {@link com.opensymphony.module.sitemesh.DecoratorMapper} can overide this.</p>
*
* @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*/
public class ApplyDecoratorTag extends BodyTagSupport implements RequestConstants {
private String page = null;
View
1  testsuite/build.xml
@@ -25,6 +25,7 @@
<lib dir="../lib">
<include name="commons-*.jar"/>
<include name="velocity-*.jar"/>
+ <include name="freemarker.jar"/>
</lib>
<classes dir="tmp/webapp/WEB-INF/classes"/>
<webinf dir="src/webapp/WEB-INF/">
View
21 testsuite/src/java/testsuite/sitemesh/FreemarkerDecoratorTest.java
@@ -0,0 +1,21 @@
+package testsuite.sitemesh;
+
+import com.meterware.httpunit.WebResponse;
+import electric.xml.Document;
+import testsuite.tester.WebTest;
+
+/**
+ * @author <a href="mailto:richard.hallier@freesbee.fr">Richard Hallier</a>
+ * @version $Revision: 1.1 $
+ */
+public class FreemarkerDecoratorTest extends WebTest {
+ public void testFreemarkerDecoratedPage() throws Exception {
+ WebResponse rs = wc.getResponse( server.getBaseURL() + "/freemarker/freemarker.jsp" );
+ Document doc = getDocument( rs );
+ assertEquals( "[:: Simple Freemarker Page ::]", rs.getTitle() );
+ assertEquals( "Hello Freemarker World", doc.getElementWithId( "p1" ).getText().toString() );
+ assertEquals( "footer", doc.getElementWithId( "footer" ).getText().toString() );
+ assertEquals( "Simple Freemarker Page", doc.getElementWithId( "header" ).getText().toString() );
+ assertEquals( "\u0126\u0118\u0139\u0139\u0150", doc.getElementWithId( "i18n" ).getText().toString() );
+ }
+}
View
1  testsuite/src/java/testsuite/sitemesh/SiteMeshTestSuite.java
@@ -22,6 +22,7 @@ protected void setupTests() {
addTests( RedirectTest.class );
addTests( BinaryFileTest.class );
addTests( VelocityDecoratorTest.class );
+ addTests( FreemarkerDecoratorTest.class );
}
}
View
4 testsuite/src/webapp/WEB-INF/decorators.xml
@@ -32,4 +32,8 @@
<pattern>/velocity/velocity.jsp</pattern>
</decorator>
+ <decorator name="freemarker" page="/decorators/freemarker.vm">
+ <pattern>/freemarker/freemarker.jsp</pattern>
+ </decorator>
+
</decorators>
View
21 testsuite/src/webapp/WEB-INF/web.xml
@@ -59,11 +59,30 @@
<load-on-startup>10</load-on-startup>
</servlet>
- <servlet-mapping>
+ <servlet>
+ <servlet-name>sitemesh-freemarker</servlet-name>
+ <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class>
+ <init-param>
+ <param-name>TemplatePath</param-name>
+ <param-value>/</param-value>
+ </init-param>
+ <init-param>
+ <param-name>default_encoding</param-name>
+ <param-value>UTF-8</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
<servlet-name>sitemesh-velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>sitemesh-freemarker</servlet-name>
+ <url-pattern>*.ftl</url-pattern>
+ </servlet-mapping>
+
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
View
11 testsuite/src/webapp/freemarker/freemarker.jsp
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <title>Simple Freemarker Page</title>
+ </head>
+ <body>
+
+ <p id="p1">Hello Freemarker World !</p>
+ <p id="i18n"><%= "\u0126\u0118\u0139\u0139\u0150" %></p>
+
+ </body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.