| <!doctype html> |
| <!-- Generated by FreeMarker/Docgen from DocBook --> |
| <html lang="en" class="page-type-section"> |
| <head prefix="og: http://ogp.me/ns#"> |
| <meta charset="utf-8"> |
| <title>Using FreeMarker with servlets - Apache FreeMarker Manual</title> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <meta name="format-detection" content="telephone=no"> |
| <meta property="og:site_name" content="Apache FreeMarker Manual"> |
| <meta property="og:title" content="Using FreeMarker with servlets"> |
| <meta property="og:locale" content="en_US"> |
| <meta property="og:url" content="https://freemarker.apache.org/docs/pgui_misc_servlet.html"> |
| <link rel="canonical" href="https://freemarker.apache.org/docs/pgui_misc_servlet.html"> |
| <link rel="icon" href="favicon.png" type="image/png"> |
| <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono"> |
| <link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1707770044859"> |
| <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script> |
| </head> |
| <body itemscope itemtype="https://schema.org/Code"> |
| <meta itemprop="url" content="https://freemarker.apache.org/docs/"> |
| <meta itemprop="name" content="Apache FreeMarker Manual"> |
| |
| <!--[if lte IE 9]> |
| <div class="oldBrowserWarning" style="display: block"> |
| Unsupported web browser - Use a modern browser to view this website! |
| </div> |
| <![endif]--> <div class="oldBrowserWarning"> |
| Unsupported web browser - Use a modern browser to view this website! |
| </div> |
| <div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo"> |
| <a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div> |
| <ul class="tabs"><li><a href="https://freemarker.apache.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="search-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"> <div class="breadcrumbs"> |
| <ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui.html"><span itemprop="name">Programmer's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_misc.html"><span itemprop="name">Miscellaneous</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="pgui_misc_servlet.html"><span itemprop="name">Using FreeMarker with servlets</span></a></li></ul> </div> |
| <div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width"> |
| <div class="content-wrapper"> |
| <div id="table-of-contents-wrapper" class="col-left"> |
| <script>var breadcrumb = ["Apache FreeMarker Manual","Programmer\'s Guide","Miscellaneous","Using FreeMarker with servlets"];</script> |
| <script src="toc.js?1707770044859"></script> |
| <script src="docgen-resources/main.min.js?1707770044859"></script> |
| </div> |
| <div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="pgui_misc_logging.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_misc_secureenv.html"><span>Next</span></a></div><div class="title-wrapper"> |
| <h1 class="content-header header-section1" id="pgui_misc_servlet" itemprop="headline">Using FreeMarker with servlets</h1> |
| </div></div><div class="page-menu"> |
| <div class="page-menu-title">Page Contents</div> |
| <ul><li><a class="page-menu-link" href="#pgui_misc_servlet_model2" data-menu-target="pgui_misc_servlet_model2">Using FreeMarker for "Model 2"</a></li><li><a class="page-menu-link" href="#pgui_misc_servlet_include" data-menu-target="pgui_misc_servlet_include">Including content from other web application |
| resources</a></li><li><a class="page-menu-link" href="#autoid_63" data-menu-target="autoid_63">Using JSP custom tags in FTL</a></li><li><a class="page-menu-link" href="#autoid_64" data-menu-target="autoid_64">Embed FTL into JSP pages</a></li></ul> </div><a name="topic.servlet"></a><p>In a fundamental sense, using FreeMarker in the web application |
| space is no different from anywhere else; FreeMarker writes its output |
| to a <code class="inline-code">Writer</code> that you pass to the |
| <code class="inline-code">Template.process</code> method, and it does not care if |
| that <code class="inline-code">Writer</code> prints to the console or to a file or |
| to the output stream of <code class="inline-code">HttpServletResponse</code>. |
| FreeMarker knows nothing about servlets and Web; it just merges Java |
| object with template files and generates text output from them. From |
| here, it is up to you how to build a Web application around |
| this.</p><p>But, probably you want to use FreeMarker with some already |
| existing Web application framework. Many frameworks rely on the |
| "Model 2" architecture, where JSP pages handle |
| presentation. If you use such a framework (for example, <a href="http://jakarta.apache.org/struts">Apache Struts</a>), |
| then read on. For other frameworks please refer to the documentation |
| of the framework.</p> |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="pgui_misc_servlet_model2">Using FreeMarker for "Model 2"</h2> |
| |
| |
| <p>Many frameworks follow the strategy that the HTTP request is |
| dispatched to user-defined "action" classes that put |
| data into <code class="inline-code">ServletContext</code>, |
| <code class="inline-code">HttpSession</code> and |
| <code class="inline-code">HttpServletRequest</code> objects as attributes, and |
| then the request is forwarded by the framework to a JSP page (the |
| view) that will generate the HTML page using the data sent with the |
| attributes. This is often referred as Model 2.</p> |
| |
| <p class="center-img"> <img src="figures/model2sketch.png" alt="Figure"> </p> |
| |
| |
| <p>With these frameworks you can simply use FTL files instead of |
| JSP files. But, since your servlet container (Web application |
| server), unlike with JSP files, does not know out-of-the-box what to |
| do with FTL files, a little extra configuring is needed for your Web |
| application:</p> |
| |
| <div class="orderedlist"><ol type="1"> |
| <li> |
| <p>Copy <code class="inline-code">freemarker.jar</code> (from the |
| <code class="inline-code">lib</code> directory of the FreeMarker distribution) |
| into the <code class="inline-code">WEB-INF/lib</code> directory of your Web |
| application.</p> |
| </li> |
| |
| <li> |
| <p>Insert the following section to the |
| <code class="inline-code">WEB-INF/web.xml</code> file of your Web application |
| (and adjust it if required):</p> |
| </li> |
| </ol></div> |
| |
| |
| |
| <div class="code-block role-unspecified"> |
| <pre class="code-block-body"><servlet> |
| <servlet-name>freemarker</servlet-name> |
| <servlet-class><strong>freemarker.ext.servlet.FreemarkerServlet</strong></servlet-class> |
| |
| <!-- |
| Init-param documentation: |
| <a href="https://freemarker.apache.org/docs/api/freemarker/ext/servlet/FreemarkerServlet.html">https://freemarker.apache.org/docs/api/freemarker/ext/servlet/FreemarkerServlet.html</a> |
| --> |
| |
| <!-- FreemarkerServlet settings: --> |
| <init-param> |
| <param-name>TemplatePath</param-name> |
| <param-value>/</param-value> |
| </init-param> |
| <init-param> |
| <param-name>NoCache</param-name> |
| <param-value>true</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ResponseCharacterEncoding</param-name> |
| <!-- Use the output_encoding setting of FreeMarker: --> |
| <param-value>fromTemplate</param-value> |
| </init-param> |
| <init-param> |
| <param-name>ExceptionOnMissingTemplate</param-name> |
| <!-- true => HTTP 500 on missing template, instead of HTTP 404. --> |
| <param-value>true</param-value> |
| </init-param> |
| |
| <!-- FreeMarker engine settings: --> |
| <init-param> |
| <param-name>incompatible_improvements</param-name> |
| <param-value>2.3.27</param-value> |
| <!-- |
| Recommended to set to a high value. |
| See: https://freemarker.apache.org/docs/pgui_config_incompatible_improvements.html |
| --> |
| </init-param> |
| <init-param> |
| <param-name>template_exception_handler</param-name> |
| <!-- Use "html_debug" during development! --> |
| <param-value>rethrow</param-value> |
| </init-param> |
| <init-param> |
| <param-name>template_update_delay</param-name> |
| <!-- Use 0 during development! Consider what value you need otherwise. --> |
| <param-value>30 s</param-value> |
| </init-param> |
| <init-param> |
| <param-name>default_encoding</param-name> |
| <!-- The encoding of the template files: --> |
| <param-value>UTF-8</param-value> |
| </init-param> |
| <init-param> |
| <param-name>output_encoding</param-name> |
| <!-- The encoding of the template output; Note that you must set |
| "ResponseCharacterEncodring" to "fromTemplate" for this to work! --> |
| <param-value>UTF-8</param-value> |
| </init-param> |
| <init-param> |
| <param-name>locale</param-name> |
| <!-- Influences number and date/time formatting, etc. --> |
| <param-value>en_US</param-value> |
| </init-param> |
| <init-param> |
| <param-name>number_format</param-name> |
| <param-value>0.##########</param-value> |
| </init-param> |
| |
| <load-on-startup>1</load-on-startup> |
| </servlet> |
| |
| <servlet-mapping> |
| <servlet-name>freemarker</servlet-name> |
| <url-pattern><strong>*.ftl</strong></url-pattern> |
| <!-- HTML and XML auto-escaped if incompatible_improvements >= 2.3.24: --> |
| <url-pattern><strong>*.ftlh</strong></url-pattern> |
| <url-pattern><strong>*.ftl</strong>x</url-pattern> |
| </servlet-mapping> |
| |
| <em>...</em> |
| |
| <!-- |
| Prevent the visiting of MVC Views from outside the servlet container. |
| RequestDispatcher.forward/include should, and will still work. |
| Removing this may open security holes! |
| --> |
| <security-constraint> |
| <web-resource-collection> |
| <web-resource-name>FreeMarker MVC Views</web-resource-name> |
| <url-pattern>*.ftl</url-pattern> |
| <url-pattern>*.ftlh</url-pattern> |
| <url-pattern>*.ftlx</url-pattern> |
| </web-resource-collection> |
| <auth-constraint> |
| <!-- Nobody is allowed to visit these directly. --> |
| </auth-constraint> |
| </security-constraint></pre> </div> |
| |
| |
| <p>After this, you can use FTL files (<code class="inline-code">*.ftl</code>) |
| in the same manner as JSP (<code class="inline-code">*.jsp</code>) files. (Of |
| course you can choose another extension besides |
| <code class="inline-code">ftl</code>; it is just the convention)</p> |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>How does it work? Let's examine how JSP-s work. Many servlet |
| container handles JSP-s with a servlet that is mapped to the |
| <code class="inline-code">*.jsp</code> request URL pattern. That servlet will |
| receive all requests where the request URL ends with |
| <code class="inline-code">.jsp</code>, find the JSP file based on the request |
| URL, and internally compiles it to a <code class="inline-code">Servlet</code>, |
| and then call the generated servlet to generate the page. The |
| <code class="inline-code">FreemarkerServlet</code> mapped here to the |
| <code class="inline-code">*.ftl</code> URL pattern does the same, except that |
| FTL files are not compiled to <code class="inline-code">Servlet</code>-s, but to |
| <code class="inline-code">Template</code> objects, and then the |
| <code class="inline-code">process</code> method of <code class="inline-code">Template</code> |
| will be called to generate the page.</p> |
| </div> |
| |
| |
| <p><a name="topic.servlet.scopeAttr"></a>For example, instead |
| of this JSP file (note that it heavily uses Struts tag-libs to save |
| designers from embedded Java monsters):</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> |
| <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> |
| |
| <html> |
| <head><title>Acmee Products International</title> |
| <body> |
| <h1>Hello <bean:write name="user"/>!</h1> |
| <p>These are our latest offers: |
| <ul> |
| <logic:iterate name="latestProducts" id="prod"> |
| <li><bean:write name="prod" property="name"/> |
| for <bean:write name="prod" property="price"/> Credits. |
| </logic:iterate> |
| </ul> |
| </body> |
| </html></pre> </div> |
| |
| |
| <p>you can use this FTL file (use <code class="inline-code">ftl</code> file |
| extension instead of <code class="inline-code">jsp</code>):</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><html> |
| <head><title>Acmee Products International</title> |
| <body> |
| <h1>Hello ${user}!</h1> |
| <p>These are our latest offers: |
| <ul> |
| <#list latestProducts as prod> |
| <li>${prod.name} for ${prod.price} Credits. |
| </#list> |
| </ul> |
| </body> |
| </html></pre> </div> |
| |
| |
| <div class="callout warning"> |
| <strong class="callout-label">Warning!</strong> |
| |
| <p>In FreeMarker <code class="inline-code"><html:form |
| action="/query"><em class="code-color">...</em></html:form></code> |
| is just static text, so it is printed to the output as is, like |
| any other XML or HTML markup. JSP tags are just FreeMarker |
| directives, nothing special, so you <em>use FreeMarker |
| syntax</em> for calling them, not JSP syntax: |
| <code class="inline-code"><@html.form |
| action="/query"><em class="code-color">...</em></@html.form></code>. |
| Note that in the FreeMarker syntax you <em>don't use |
| <code class="inline-code">${<em class="code-color">...</em>}</code> in |
| parameters</em> as in JSP, and you <em>don't quote the |
| parameter values</em>. So this is |
| <em>WRONG</em>:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#-- WRONG: --> |
| <@my.jspTag color="${aVariable}" name="aStringLiteral" |
| width="100" height=${a+b} /></pre> </div> |
| |
| |
| <p>and this is good:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#-- Good: --> |
| <@my.jspTag color=aVariable name="aStringLiteral" |
| width=100 height=a+b /></pre> </div> |
| |
| </div> |
| |
| |
| <p>In both templates, when you refer to <code class="inline-code">user</code> |
| and <code class="inline-code">latestProduct</code>, it will first try to find a |
| variable with that name that was created in the template (like |
| <code class="inline-code">prod</code>; if you master JSP: a page scope attribute). |
| If that fails, it will try to look up an attribute with that name in |
| the <code class="inline-code">HttpServletRequest</code>, and if it is not there |
| then in the <code class="inline-code">HttpSession</code>, and if it still doesn't |
| find it then in the <code class="inline-code">ServletContext</code>. In the case |
| of FTL this works because <code class="inline-code">FreemarkerServlet</code> |
| builds the data-model from the attributes of the mentioned 3 |
| objects. That is, in this case the root hash is not a |
| <code class="inline-code">java.util.Map</code> (as it was in some example codes in |
| this manual), but |
| <code class="inline-code">ServletContext</code>+<code class="inline-code">HttpSession</code>+<code class="inline-code">HttpServletRequest</code>; |
| FreeMarker is pretty flexible about what the data-model is. So if |
| you want to put variable <code class="inline-code">"name"</code> into the |
| data-model, then you call |
| <code class="inline-code">servletRequest.setAttribute("name", "Fred")</code>; this |
| is the logic of Model 2, and FreeMarker adapts itself to it.</p> |
| |
| <p><code class="inline-code">FreemarkerServlet</code> also puts 3 hashes into |
| the data-model, by which you can access the attributes of the 3 |
| objects directly. The hash variables are: |
| <code class="inline-code">Request</code>, <code class="inline-code">Session</code>, |
| <code class="inline-code">Application</code> (corresponds to |
| <code class="inline-code">ServletContext</code>). It also exposes another hash |
| named <code class="inline-code">RequestParameters</code> that provides access to |
| the parameters of the HTTP request.</p> |
| |
| <p><code class="inline-code">FreemarkerServlet</code> has various init-params. |
| It can be set up to load templates from an arbitrary directory, from |
| the classpath, or relative to the Web application directory. You can |
| set the charset used for templates, the default locale used by |
| templates, what object wrapper do you want to use, etc.</p> |
| |
| <p><code class="inline-code">FreemarkerServlet</code> is easily tailored to |
| special needs through subclassing. Say, if you need to have |
| additional variables available in your data-model for all templates, |
| subclass the servlet and override the |
| <code class="inline-code">preTemplateProcess()</code> method to shove any |
| additional data you need into the model before the template gets |
| processed. Or subclass the servlet, and set these globally available |
| variables as <a href="pgui_config_sharedvariables.html">shared |
| variables</a> in the <code class="inline-code">Configuration</code>.</p> |
| |
| <p>For more information please read the Java API documentation of |
| the class.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="pgui_misc_servlet_include">Including content from other web application |
| resources</h2> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <p>You can use the <code class="inline-code"><@include_page |
| path="..."/></code> custom directive provided by the |
| <code class="inline-code">FreemarkerServlet</code> (since 2.3.15) to include the |
| contents of another web application resource into the output; this |
| is often useful to integrate output of JSP pages (living alongside |
| the FreeMarker templates in the same web server) into the FreeMarker |
| template output. Using:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><@include_page path="path/to/some.jsp"/></pre> </div> |
| |
| |
| <p>is identical to using this tag in JSP:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><jsp:include page="path/to/some.jsp"></pre> </div> |
| |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p><code class="inline-code"><@include_page ...></code> is not to be |
| confused with <code class="inline-code"><#include ...></code>, as the last |
| is for including FreeMarker templates without involving the |
| Servlet container. An <code class="inline-code"><#include ...></code>-ed |
| template shares the template processing state with the including |
| template, such as the data-model and the template-language |
| variables, while <code class="inline-code"><@include_page ...></code> |
| starts an independent HTTP request processing.</p> |
| </div> |
| |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>Some Web Application Frameworks provide their own solution |
| for this, in which case you possibly should use that instead. Also |
| some Web Application Frameworks don't use |
| <code class="inline-code">FreemarkerServlet</code>, so |
| <code class="inline-code">include_page</code> is not available.</p> |
| </div> |
| |
| |
| <p>The path can be relative or absolute. Relative paths are |
| interpreted relative to the URL of the current HTTP request (one |
| that triggered the template processing), while absolute paths are |
| absolute in the current servlet context (current web application). |
| You can not include pages from outside the current web application. |
| Note that you can include any page, not just a JSP page; we just |
| used page with path ending in <code class="inline-code">.jsp</code> as an |
| illustration.</p> |
| |
| <p>In addition to the <code class="inline-code">path</code> parameter, you can |
| also specify an optional parameter named |
| <code class="inline-code">inherit_params</code> with a boolean value (defaults to |
| true when not specified) that specifies whether the included page |
| will see the HTTP request parameters of the current request or |
| not.</p> |
| |
| <p>Finally, you can specify an optional parameter named |
| <code class="inline-code">params</code> that specifies new request parameters that |
| the included page will see. In case inherited parameters are passed |
| too, the values of specified parameters will get prepended to the |
| values of inherited parameters of the same name. The value of |
| <code class="inline-code">params</code> must be a hash, with each value in it |
| being either a string, or a sequence of strings (if you need |
| multivalued parameters). Here's a full example:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><@include_page path="path/to/some.jsp" inherit_params=true params={"foo": "99", "bar": ["a", "b"]}/></pre> </div> |
| |
| |
| <p>This will include the page |
| <code class="inline-code">path/to/some.jsp</code>, pass it all request parameters |
| of the current request, except for "foo" and "bar", which will be |
| set to "99" and multi-value of "a", "b", respectively. In case the |
| original request already had values for these parameters, the new |
| values will be prepended to the existing values. I.e. if "foo" had |
| values "111" and "123", then it will now have values "99", "111", |
| "123".</p> |
| |
| <p><span class="marked-for-programmers">It is in fact possible to pass |
| non-string values for parameter values within |
| <code class="inline-code">params</code>. Such a value will be converted to a |
| suitable Java object first (i.e. a Number, a Boolean, a Date, etc.), |
| and then its Java <code class="inline-code">toString()</code> method will be used |
| to obtain the string value. It is better to not rely on this |
| mechanism, though, and instead explicitly ensure that parameter |
| values that aren't strings are converted to strings on the template |
| level where you have control over formatting using the |
| <code class="inline-code">?string</code> and <code class="inline-code">?c</code> built-ins. |
| </span></p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_63">Using JSP custom tags in FTL</h2> |
| |
| |
| |
| |
| |
| |
| |
| |
| <p><code class="inline-code">FreemarkerServlet</code> puts the |
| <code class="inline-code">JspTaglibs</code> hash into the data-model, which you |
| can use to access JSP taglibs. The JSP custom tags will be |
| accessible as plain user-defined directives, and the custom EL |
| functions (since FreeMarker 2.3.22) as methods. For example, for |
| this JSP file:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><%@ page contentType="text/html;charset=ISO-8859-2" language="java"%> |
| <%@ taglib prefix="e" uri="/WEB-INF/example.tld" %> |
| <%@ taglib prefix="oe" uri="/WEB-INF/other-example.tld" %> |
| <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> |
| <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> |
| |
| <%-- Custom JSP tags and functions: --%> |
| |
| <e:someTag numParam="123" boolParam="true" strParam="Example" anotherParam="${someVar}"> |
| ... |
| </e:someTag> |
| |
| <oe:otherTag /> |
| |
| ${e:someELFunction(1, 2)} |
| |
| |
| <%-- JSTL: --%> |
| |
| <c:if test="${foo}"> |
| Do this |
| </c:if> |
| |
| <c:choose> |
| <c:when test="${x == 1}"> |
| Do this |
| </c:when> |
| <c:otherwise> |
| Do that |
| </c:otherwise> |
| </c:choose> |
| |
| <c:forEach var="person" items="${persons}"> |
| ${person.name} |
| </c:forEach> |
| |
| ${fn:trim(bar)}</pre> </div> |
| |
| |
| <p>the about equivalent FTL is:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#assign e=JspTaglibs["/WEB-INF/example.tld"]> |
| <#assign oe=JspTaglibs["/WEB-INF/other-example.tld"]> |
| |
| <#-- Custom JSP tags and functions: --#> |
| |
| <@e.someTag numParam=123 boolParam=true strParam="Example" anotherParam=someVar> |
| ... |
| </@e.someTag> |
| |
| <@oe.otherTag /> |
| |
| ${e.someELFunction(1, 2)} |
| |
| |
| <#-- JSTL - Instead, use native FTL constructs: --> |
| |
| <#if foo> |
| Do this |
| </#if> |
| |
| <#if x == 1> |
| Do this |
| <#else> |
| Do that |
| </#if> |
| |
| <#list persons as person> |
| ${person.name} |
| </#list> |
| |
| ${bar?trim}</pre> </div> |
| |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>Parameter values don't use quotation and |
| <code class="inline-code">"${<em class="code-color">...</em>}"</code> like in |
| JSP. See more explanation later.</p> |
| </div> |
| |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p><code class="inline-code">JspTaglibs</code> is not a core FreeMarker |
| feature; it only exists when the template is called through the |
| <code class="inline-code">FreemarkerServlet</code>. That's because JSP |
| tags/functions assume a servlet environment (FreeMarker doesn't), |
| plus some Servlet concepts have to be emulated in the special |
| FreeMarker data-model that <code class="inline-code">FreemarkerServlet</code> |
| builds. Many modern frameworks use FreeMarker on a pure way, not |
| through <code class="inline-code">FreemarkerServlet</code>.</p> |
| </div> |
| |
| |
| <p>Since JSP custom tags are written to operate in JSP |
| environment, they assume that variables (often referred as |
| "beans" in JSP world) are stored in 4 scopes: page |
| scope, request scope, session scope and application scope. FTL has |
| no such notation (the 4 scopes), but |
| <code class="inline-code">FreemarkerServlet</code> provides emulated JSP |
| environment for the custom JSP tags, which maintains correspondence |
| between the "beans" of JSP scopes and FTL variables. |
| For the custom JSP tags, the request, session and application scopes |
| are exactly the same as with real JSP: the attributes of the |
| <code class="inline-code">javax.servlet.ServletContext</code>, |
| <code class="inline-code">HttpSession</code> and <code class="inline-code">ServletRequest</code> |
| objects. From the FTL side you see these 3 scopes together as the |
| data-model, as it was explained earlier. The page scope corresponds |
| to the FTL global variables (see the <a href="ref_directive_global.html#ref.directive.global"><code>global</code> |
| directive</a>). That is, if you create a variable with the |
| <code class="inline-code">global</code> directive, it will be visible for the |
| custom tags as page scope variable through the emulated JSP |
| environment. Also, if a JSP-tag creates a new page scope variable, |
| the result will be the same as if you create a variable with the |
| <code class="inline-code">global</code> directive. Note that the variables in the |
| data-model are not visible as page-scope attributes for the JSP |
| tags, despite that they are globally visible, since the data-model |
| corresponds to the request, session and application scopes, not the |
| page-scope.</p> |
| |
| <p>On JSP pages you quote all attribute values, it does not mater |
| if the type of the parameter is string or boolean or number. But |
| since custom tags are accessible in FTL templates as user-defined |
| FTL directives, you have to use the FTL syntax rules inside the |
| custom tags, not the JSP rules. So when you specify the value of an |
| "attribute", then on the right side of the |
| <code class="inline-code">=</code> there is an <a href="dgui_template_exp.html">FTL expression</a>. Thus, |
| <em>you must not quote boolean and numerical parameter |
| values</em> (e.g. <code class="inline-code"><@tiles.insert |
| page="/layout.ftl" flush=true/></code>), or they are |
| interpreted as string values, and this will cause a type mismatch |
| error when FreeMarker tries to pass the value to the custom tag that |
| expects non-string value. Also note that, naturally, you can use any |
| FTL expression as attribute value, such as variables, calculated |
| values, etc. (e.g. <code class="inline-code"><@tiles.insert page=layoutName |
| flush=foo && bar/></code>).</p> |
| |
| <p>FreeMarker does not rely on the JSP support of the servlet |
| container in which it is run when it uses JSP taglibs since it |
| implements its own lightweight JSP runtime environment. There is |
| only one small detail to pay attention to: to enable the FreeMarker |
| JSP runtime environment to dispatch events to JSP taglibs that |
| register event listeners in their TLD files, you should add this to |
| the <code class="inline-code">WEB-INF/web.xml</code> of your Web |
| application:</p> |
| |
| |
| |
| <div class="code-block role-unspecified"> |
| <pre class="code-block-body"><listener> |
| <listener-class>freemarker.ext.jsp.EventForwarding</listener-class> |
| </listener></pre> </div> |
| |
| |
| <p>Note that you can use JSP taglibs with FreeMarker even if the |
| servlet container has no native JSP support, just make sure that the |
| <code class="inline-code">javax.servlet.jsp.*</code> packages for JSP 2.0 (or |
| later) are available to your Web application.</p> |
| |
| <p>As of this writing, JSP features up to JSP 2.1 are |
| implemented, except the "tag files" feature of JSP 2 (i.e., custom |
| JSP tags <em>implemented</em> in JSP language). The tag |
| files had to be compiled to Java classes to be usable under |
| FreeMarker.</p> |
| |
| <p><code class="inline-code">JspTaglibs[<em class="code-color">uri</em>]</code> |
| will have to find the TLD for the URI specified, just like JSP's |
| <code class="inline-code">@taglib</code> directive has to. For this, it implements |
| the TLD discovery mechanism described in the JSP specification. See |
| more there, but in a nutshell, it searches TLD-s in |
| <code class="inline-code">WEB-INF/web.xml</code> <code class="inline-code">taglib</code> |
| elements, at <code class="inline-code">WEB-INF/**/*.tld</code>, and in |
| <code class="inline-code">WEB-INF/lib/*.{jar,zip}/META-INF/**/*.tld</code>. |
| Additionally, it can discover TLD-s that are visible for the class |
| loader even if they are outside the WAR structure, when you set that |
| up with the <code class="inline-code">MetaInfTldSources</code> and/or |
| <code class="inline-code">ClasspathTlds</code> |
| <code class="inline-code">FreemarkerServlet</code> init-params (since 2.3.22). See |
| the Java API documentation of <code class="inline-code">FreemarkerServlet</code> |
| for the description of these. It's also possible to set these from |
| Java system properties, which can be handy when you want to change |
| these in the Eclipse run configuration without modifying the |
| <code class="inline-code">web.xml</code>; again, see the |
| <code class="inline-code">FreemarkerServlet</code> API docs. |
| <code class="inline-code">FreemarkerServlet</code> also recognizes the |
| <code class="inline-code">org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</code> |
| servlet context attribute, and adds the entries from it to |
| <code class="inline-code">MetaInfTldSources</code>.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_64">Embed FTL into JSP pages</h2> |
| |
| |
| |
| |
| <p>There is a taglib that allows you to put FTL fragments into |
| JSP pages. The embedded FTL fragment can access the attributes |
| (Beans) of the 4 JSP scopes. You can find a working example and the |
| taglib in the FreeMarker distribution.</p> |
| <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="pgui_misc_logging.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui_misc_secureenv.html"><span>Next</span></a></div></div></div></div> </div> |
| </div> |
| <div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated"> |
| Last generated: |
| <time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p> |
| <p class="copyright"> |
| © <span itemprop="copyrightYear">1999</span>–2024 |
| <a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p> |
| </div></div></div></body> |
| </html> |