# apostrophe-templates
# Inherits from: apostrophe-module
# apos.templates
Implements template rendering via Nunjucks. You should use the
self.render and self.partial methods of your own module,
which exist courtesy of apostrophe-module
and invoke methods of this module more conveniently for you.
You may have occasion to call self.apos.templates.safe when
implementing a helper that returns a value that should not be
escaped by Nunjucks. You also might call self.apos.templates.filter to
add a new filter to Nunjucks.
# Options
# filters: an object in which
each key is the name of a Nunjucks filter and
its corresponding value is a function that implements it.
You may find it easier and more maintainable to call apos.templates.addFilter(name, fn).
# language: your own alternative to the object
returned by require('nunjucks'). Replacing Nunjucks entirely in Apostrophe would be a vast undertaking, but perhaps you have a custom version of Nunjucks that is compatible.
# viewsFolderFallback: specifies a folder or an array of folders to be checked for templates
if they are not found in the module that called self.render or self.partial
or those it extends. This is a handy place for project-wide macro files.
Often set to __dirname + '/views' in app.js.
# Methods
# addHelpersForModule(module, *object *, or module, name, value)
Add helpers in the namespace for a particular module. They will be visible in nunjucks at apos.modules[module-name].helperName. If the alias option for the module is set to "shortname", then they are also visible as apos.shortname.helperName. Note that the alias option must be set only by the project-level developer (except for core modules).
# addHelperShortcutForModule(module, name)
# addShortcutHelper(name, value)
The use of this method is restricted to core modules
and should only be used for apos.area, apos.singleton,
and anything we later decide is at least that important.
Everything else should be namespaced at all times,
at least under its module alias.
# modulesReady()
When all modules have finished adding helpers, wrap all helper functions so that the true line numbers responsible for any errors can be seen in the error logs. Also apply module aliases, make the options passed to the module available in nunjucks, and apply any helper shortcuts
# addFilter(*object *, or name, fn)
Add new filters to the Nunjucks environment. You can add many by passing an object with named properties, or add just one by passing a name and a function. You can also do this through the filters option of this module.
# safe(s)
return a string which will not be escaped by Nunjucks. Call this in your helper function when your return value contains markup and you are absolutely sure that any user input has been correctly escaped already.
# escapeIfNeeded(s)
Escape any HTML markup in the given string and return a new Nunjucks safe string,
unless it is already marked as safe by Nunjucks. If it is nullish treat it as an
empty string. If it is not a string convert it with its toString method before
escaping.
# renderForModule(req, name, data, module)
Load and render a Nunjucks template, internationalized
by the given req object. The template with the name
specified is loaded from the views folder of the
specified module or its superclasses; the deepest
version of the template wins. You normally won't call
this directly; you'll call self.render on your module.
Apostrophe Nunjucks helpers such as apos.area are
attached to the apos object in your template.
Data passed in your data object is provided as the
data object in your template, which also contains
properties of req.data and module.templateData,
if those objects exist.
If there is a conflict, your data argument wins,
followed by req.data.
If not overridden, data.user and data.permissions
are provided for convenience.
The .html extension is assumed.
# renderStringForModule(req, s, data, module)
Works just like self.render, except that the entire template is passed as a string rather than a filename.
# partialForModule(name, data, module)
# partialStringForModule(name, data, module)
# jsonForHtml(data)
Stringify the data as JSON, then escape any sequences
that would cause a script tag to end prematurely if
the JSON were embedded in it. Also make sure the JSON is
JS-friendly by escaping unicode line and paragraph
separators.
If the argument is undefined, "null" is returned. This is
better than the behavior of JSON.stringify (which returns
undefined, not "undefined") while still being JSONic
(undefined is not valid in JSON).
# renderBody(req, type, s, data, module)
Implements render and renderString. See their
documentation.
# i18n(req, *operation *, , additional arguments)
Takes req, operation which will be '__', '__mf' or another
standard helper name provided by the i18n module, and the
arguments intended for that helper, beginning always with key.
Invokes the specified operation of the i18n module. This
method exists as an override and extension point for
Apostrophe's static text internationalization features.
# getEnv(module)
Fetch a nunjucks environment in which include,
extends, etc. search the views directories of the
specified module and its ancestors. Typically you
will call self.render, self.renderPage or
self.partial on your module object rather than calling
this directly.
# getViewFolders(module)
# newEnv(moduleName, dirs)
Create a new nunjucks environment in which the specified directories are searched for includes, etc. Don't call this directly, use:
apos.templates.getEnv(module)
# newLoader(moduleName, dirs)
Creates a Nunjucks loader object for the specified list of directories, which can also call back to this module to resolve cross-module includes. You will not need to call this directly.
# addStandardFilters(env)
# renderPageForModule(req, template, data, module)
Typically you will call the sendPage method of
your own module, provided by the apostrophe-module
base class, which is a wrapper for this method.
Send a complete HTML page for to the browser.
If template is a function it is passed a data object,
otherwise it is rendered as a nunjucks template relative
to this module via self.render.
data is provided to the template, with additional
default properties as described below.
module is the module from which the template should
be rendered, if an explicit module name is not part
of the template name.
Additional properties merged with the `data object:
"outerLayout" is set to...
apostrophe-templates:outerLayout.html
Or:
apostrophe-templates:refreshLayout.html
This allows the template to handle either a content area refresh or a full page render just by doing this:
{% extend outerLayout %}
Note the lack of quotes.
Under any of the following conditions, "refreshLayout.html" is used in place of "outerLayout.html":
req.xhris true (always set on AJAX requests by jQuery)req.query.xhris set to simulate an AJAX requestreq.decorateis falsereq.query.apos_refreshis true
These default properties are also provided on the data object
visible in Nunjucks:
url(req.url)user(req.user)query(req.query)permissions(req.user._permissions)refreshing(true if we are refreshing the content area of the page without reloading)js.globalCalls(javascript markup to insert all global pushed javascript calls)js.reqCalls(javascript markup to insert all req-specific pushed javascript calls)
# addBodyClass(req, bodyClass)
Add a body class or classes to be emitted when the page is rendered. This information
is attached to req.data, where the string req.data.aposBodyClasses is built up.
The default outerLayoutBase.html template outputs that string.
The string passed may contain space-separated class names.
# addBodyDataAttribute(req, name, value = '')
Add a body attribute to be emitted when the page is rendered. This information
is attached to req.data, where req.data.aposBodyDataAttributes is built up
using name as the attribute name which is automatically prepended with "data-"
and the optional value argument
Also receives an object with key/pair values which becomes attribute name(s) and value(s)
The default outerLayoutBase.html template outputs that string.
# prepend(location, helperFn)
Use this method to provide a function that will be invoked at the point
in the page layout identified by the string location. Standard locations
are head, body, main and contextMenu.
The page layout, template or outerLayout must contain a corresponding
apos.templates.prepended('location') call, with the same location, to
actually insert the content.
Your function is called once per request, and will receive req as an argument
as a convenience. Since page rendering is in progress, req will be equal to
apos.templates.contextReq.
The output of functions added with prepend is prepended just after the
opening tag of an element, such as <head>. Use append to insert material
before the closing tag.
This method is most often used when writing a module that adds new UI to Apostrophe and allows you to add that markup without forcing developers to customize their layout for your module to work.
# append(location, helperFn)
Use this method to provide a function that will be invoked at the point
in the page layout identified by the string location. Standard locations
are head, body, main and contextMenu.
The page layout, template or outerLayout must contain a corresponding
apos.templates.prepended('location') call, with the same location, to
actually insert the content.
Your function is called once per request, and will receive req as an argument
as a convenience. Since page rendering is in progress, req will be equal to
apos.templates.contextReq.
The output of functions added with append is appended just before the
closing tag of an element, such as </head>. Use prepend to insert material
after the opening tag.
This method is most often used when writing a module that adds new UI to Apostrophe and allows you to add that markup without forcing developers to customize their layout for your module to work.
# insert(end, location, helperFn)
Implementation detail of apos.templates.prepend and apos.templates.append.
# inserted(end, location)
Implementation detail of apos.templates.prepended and apos.templates.appended.
# prepended(location)
Invokes all of the prepend helper functions registered for the given
location and returns the resulting markup as a Nunjucks "safe" string
(HTML tags are allowed). Available as the apos.templates.prepended
helper, and invoked as such by outerLayoutBase.html.
# appended(location)
Invokes all of the append helper functions registered for the given
location and returns the resulting markup as a Nunjucks "safe" string
(HTML tags are allowed). Available as the apos.templates.appended
helper, and invoked as such by outerLayoutBase.html.
# showContextMenu(req)
Determines whether the aposContextMenu block, which contains the "Page Settings" and "Published" UIs in the lower left corner in addition to further UI pushed by modules like workflow, should appear or not. Override to add additional nuances to this decision.
# enableHelpers()
# Nunjucks template helpers
# showContextMenu()
# prepended(location)
Invokes all of the prepend helper functions registered for the given
location and returns the resulting markup as a Nunjucks "safe" string
(HTML tags are allowed). Available as the apos.templates.prepended
helper, and invoked as such by outerLayoutBase.html.
# appended(location)
Invokes all of the append helper functions registered for the given
location and returns the resulting markup as a Nunjucks "safe" string
(HTML tags are allowed). Available as the apos.templates.appended
helper, and invoked as such by outerLayoutBase.html.