| <!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>Namespaces - 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="Namespaces"> |
| <meta property="og:locale" content="en_US"> |
| <meta property="og:url" content="https://freemarker.apache.org/docs/dgui_misc_namespace.html"> |
| <link rel="canonical" href="https://freemarker.apache.org/docs/dgui_misc_namespace.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="dgui.html"><span itemprop="name">Template Author's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_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="dgui_misc_namespace.html"><span itemprop="name">Namespaces</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","Template Author\'s Guide","Miscellaneous","Namespaces"];</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="dgui_misc_var.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_autoescaping.html"><span>Next</span></a></div><div class="title-wrapper"> |
| <h1 class="content-header header-section1" id="dgui_misc_namespace" itemprop="headline">Namespaces</h1> |
| </div></div><div class="page-menu"> |
| <div class="page-menu-title">Page Contents</div> |
| <ul><li><a class="page-menu-link" href="#autoid_23" data-menu-target="autoid_23">Creating a library</a></li><li><a class="page-menu-link" href="#autoid_24" data-menu-target="autoid_24">Writing the variables of imported namespaces</a></li><li><a class="page-menu-link" href="#autoid_25" data-menu-target="autoid_25">Namespaces and data-model</a></li><li><a class="page-menu-link" href="#autoid_26" data-menu-target="autoid_26">The life-cycle of namespaces</a></li><li><a class="page-menu-link" href="#autoid_27" data-menu-target="autoid_27">Auto-importing</a></li></ul> </div><p>When you run templates, you have a (possibly empty) set of |
| variables that you have created with <code class="inline-code">assign</code> and |
| <code class="inline-code">macro</code> and <code class="inline-code">function</code> directives |
| (see in the <a href="dgui_misc_var.html">previous chapter</a>). A |
| set of template-made variables like that is called a <strong>namespace</strong>. In simple cases you use only one |
| namespace, the <strong>main namespace</strong>. |
| Whenever you define a variable in the main template (macros and |
| functions are also variables, mind you), or in templates <a href="ref_directive_include.html#ref.directive.include"><code>include</code>-d</a> in |
| it, that's where the variable are created. The key property of a |
| namespace is that the variable name uniquely identifies a value in it |
| (i.e, you can't have multiple variables in it with the same name in |
| the same namespace).</p><p>Sometimes you want to build reusable collection of macros, |
| functions, and other variables, which we call a <strong>library</strong>. It's important that a library can use |
| its own namespace, to avoid accidental name clashes. Consider, you may |
| have many names in that library, and you intend to use the library in |
| many templates, maybe even reuse it in several projects. It becomes |
| impractical to keep track of where the library used in another |
| template accidentally hides variables from the data-model, or what |
| names you shouldn't assign to in the template to avoid overwriting the |
| variables of the library. If you have multiple libraries used in the |
| same template, this becomes even harder to track. So you should use a |
| separate namespace for the variables of each library.</p> |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_23">Creating a library</h2> |
| |
| |
| <p>Here's a simple library, which contains a |
| <code class="inline-code">copyright</code> macro and a <code class="inline-code">mail</code> |
| string:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#macro copyright date> |
| <p>Copyright (C) ${date} Someone. All rights reserved.</p> |
| </#macro> |
| |
| <#assign mail = "user@example.com"></pre> </div> |
| |
| |
| <p>Save this into the <code class="inline-code">lib/example.ftl</code> file |
| (inside the directory where you store the templates). Then create a |
| template, let's say, <code class="inline-code">some_web_page.ftl</code>, and use |
| the library in it:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#<strong>import</strong> "/lib/example.ftl" as <strong>e</strong>> |
| |
| Some Web page... |
| <@<strong>e</strong>.copyright date="1999-2002"/> |
| ${<strong>e</strong>.mail}</pre> </div> |
| |
| |
| |
| |
| <div class="code-block role-output"> |
| <div class="code-block-label">Output</div><pre class="code-block-body">Some Web page... |
| <p>Copyright (C) 1999-2002 Someone. All rights reserved.</p> |
| user@example.com</pre> </div> |
| |
| |
| <p>Note the <a href="ref_directive_import.html#ref.directive.import"><code>import</code> |
| directive</a> above, and the subsequent usage of the |
| "<code class="inline-code">e</code>" variable. |
| <code class="inline-code">import</code> is similar to the perhaps already familiar |
| <a href="ref_directive_include.html#ref.directive.include"><code>include</code> |
| directive</a>, but it will create an empty namespace and will run |
| <code class="inline-code">lib/example.ftl</code> in that namespace. So |
| <code class="inline-code">lib/example.ftl</code> will find itself in a clean |
| world, where only the variables of the data-models are visible (and |
| the globals), and will create its two variables |
| (<code class="inline-code">copyright</code> and <code class="inline-code">mail</code>) in this |
| clean namespace. But you will need to access those two variables |
| from another namespace (the main namespace), thus, the |
| <code class="inline-code">import</code> directive creates a hash variable |
| (<code class="inline-code">e</code> in this case) to access the namespace it has |
| created . That variable is in the namespace that the |
| <code class="inline-code">import</code>-ing template uses, and acts as a window to |
| the namespace of the imported library.</p> |
| |
| <p>To demonstrate that the two namespaces are separate, consider |
| the example below. Replace <code class="inline-code">lib/example.ftl</code> with |
| this:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#macro copyright date> |
| <p>Copyright (C) ${date} Someone. All rights reserved. |
| <br>Email: <strong>${mail}</strong></p> |
| </#macro> |
| |
| <#assign mail = "user@example.com"></pre> </div> |
| |
| |
| <p>and <code class="inline-code">some_web_page.ftl</code> with this:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#import "/lib/example.ftl" as e> |
| <strong><#assign mail="other@example.com"></strong> |
| <@e.copyright date="1999-2002"/> |
| ${e.mail} |
| ${mail}</pre> </div> |
| |
| |
| |
| |
| <div class="code-block role-output"> |
| <div class="code-block-label">Output</div><pre class="code-block-body"> <p>Copyright (C) 1999-2002 Someone. All rights reserved. |
| <br>Email: <strong>user@example.com</strong></p> |
| user@example.com |
| other@example.com</pre> </div> |
| |
| |
| <p>As you can see, the <code class="inline-code">mail</code> variable assigned |
| in <code class="inline-code">some_web_page.ftl</code> is separate from the |
| <code class="inline-code">mail</code> variable assigned in the imported |
| library.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_24">Writing the variables of imported namespaces</h2> |
| |
| |
| <p>Sometimes you want to create or replace a variable in an |
| imported namespace. You can do that with the |
| <code class="inline-code">assign</code> directive and its |
| <code class="inline-code">namespace</code> parameter:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#import "/lib/example.ftl" as e> |
| ${e.mail} |
| <#assign mail="other@example.com" <strong>in e</strong>> |
| ${e.mail}</pre> </div> |
| |
| |
| |
| |
| <div class="code-block role-output"> |
| <div class="code-block-label">Output</div><pre class="code-block-body">user@example.com |
| other@example.com</pre> </div> |
| |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_25">Namespaces and data-model</h2> |
| |
| |
| <p>The variables of the data-model are visible from everywhere. |
| For example, if you have a variable called <code class="inline-code">user</code> |
| in the data-model, <code class="inline-code">lib/example.ftl</code> will access |
| that, exactly like <code class="inline-code">some_web_page.ftl</code> does:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#macro copyright date> |
| <p>Copyright (C) ${date} <strong>${user}</strong>. All rights reserved.</p> |
| </#macro></pre> </div> |
| |
| |
| <p>Assuming <code class="inline-code">user</code> is "John |
| Doe":</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#import "/lib/my_test.ftl" as my> |
| User is: ${user} |
| <@my.copyright date="1999-2002"/></pre> </div> |
| |
| |
| |
| |
| <div class="code-block role-output"> |
| <div class="code-block-label">Output</div><pre class="code-block-body">User is: John Doe |
| <p>Copyright (C) 1999-2002 John Doe. All rights reserved.</p></pre> </div> |
| |
| |
| <p>Don't forget that the variables in the namespace (the |
| variables you create with <code class="inline-code">assign</code>, |
| <code class="inline-code">macro</code>, and <code class="inline-code">function</code> |
| directives) have precedence over the variables of the data-model |
| when you are in that namespace. So generally, if a library is |
| interested in a data-model variable, it doesn't assign to the same |
| name.</p> |
| |
| <div class="callout note"> |
| <strong class="callout-label">Note:</strong> |
| |
| <p>In some unusual applications you want to create variables in |
| the template that are visible from all namespaces, exactly like |
| the variables of the data-model. While templates can't change the |
| data-model, it's possible to achieve similar effect with the |
| <code class="inline-code">global</code> directive; see the <a href="ref_directive_global.html#ref.directive.global">reference</a>.</p> |
| </div> |
| |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_26">The life-cycle of namespaces</h2> |
| |
| |
| <p>A namespace is identified by the path used in the |
| <code class="inline-code">import</code> directive (after it was normalized to an |
| absolute path). If you try to <code class="inline-code">import</code> with |
| equivalent paths for multiple times, it will create the namespace |
| and run the template for only the first invocation of |
| <code class="inline-code">import</code>. The later <code class="inline-code">import</code>-s |
| with equivalent paths will just assign the same namespace to the |
| variable specified after the <code class="inline-code">as</code> keyword. For |
| example:</p> |
| |
| |
| |
| <div class="code-block role-template"> |
| <div class="code-block-label">Template</div><pre class="code-block-body"><#import "/lib/example.ftl" as e> |
| <#import "/lib/example.ftl" as e2> |
| <#import "/lib/example.ftl" as e3> |
| ${e.mail}, ${e2.mail}, ${e3.mail} |
| <#assign mail="other@example.com" in e> |
| ${e.mail}, ${e2.mail}, ${e3.mail}</pre> </div> |
| |
| |
| |
| |
| <div class="code-block role-output"> |
| <div class="code-block-label">Output</div><pre class="code-block-body">user@example.com, user@example.com, user@example.com |
| other@example.com, other@example.com, other@example.com</pre> </div> |
| |
| |
| <p>As you access the same namespace through <code class="inline-code">e</code>, |
| <code class="inline-code">e2</code>, and <code class="inline-code">e3</code>, the |
| <code class="inline-code">email</code> has changed in all of them at once. The |
| practical importance of this is that when you import the same |
| library in multiple templates, only one namespace will be |
| initialized and created for the library, which will be shared by all |
| the importing templates.</p> |
| |
| <p>Note that namespaces are not hierarchical; it doesn't mater |
| what namespace are you in when <code class="inline-code">import</code> creates |
| another namespace. For example, when you <code class="inline-code">import</code> |
| namespace N2 while you are in name space N1, N2 will not be inside |
| N1. N1 just gets the same N2 that you get if you |
| <code class="inline-code">import</code> N2 when you are in the main |
| namespace.</p> |
| |
| <p>Each <a href="gloss.html#gloss.templateProcessingJob">template |
| processing job</a> has its own private set of namespaces. Each |
| template processing job is a separate universe that exists only for |
| the short period while the main template is rendered, and then it |
| vanishes with all its populated namespaces. Thus, whenever we say |
| that "<code class="inline-code">import</code> is called for the first |
| time", we always mean the first time within the lifespan of a |
| single template processing job.</p> |
| |
| |
| |
| |
| |
| <h2 class="content-header header-section2" id="autoid_27">Auto-importing</h2> |
| |
| |
| <p>When you have to import the same libraries again and again in |
| many templates, know that the Java programmers (or whoever is |
| responsible for configuring FreeMarker) can specify auto-imports, |
| which are imports that are automatically done in all templates. Auto |
| imports can also be configured to be "lazy" (since |
| FreeMarker 2.3.25), which means that they are only done when the |
| imported library is actually used in the template. See the Java API |
| documentation for more details: <a href="https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setAutoImports-java.util.Map-">Configuration.setAutoImports</a>, |
| <a href="https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setLazyAutoImports-java.lang.Boolean-">Configuration.setLazyAutoImports</a>.</p> |
| <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_var.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_autoescaping.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> |