Offline Packagers
Offline packagers are features of portal themes, and are placed beneath the root-level
/packagers
folder in the theme, for example,
/packagers/webhelp
.
The /packagers
directory may include other files and directories that
are used by more than one packager. Packager directories are distinguished by having
a
packager.ftl
file and an optional config.json
file
directly within them. For example, in the following directory list, only the
webhelp
directory is a packager directory. The others contain common
templates and resources that may be used by all packagers.
packagers/ common/ helpers/ scripts/ webhelp/ config.json packager.ftl
The packager folder consists of the following files.
- A
packager.ftl
Freemarker script, which is the entry-point for the creation of the package's contents. - An optional configuration file called
config.json
that specifies various options for the packager. - Any Freemarker component scripts referenced by
packager.ftl
. - Files to be included in all generated packages, like styling assets, licensing boilerplate, or other static assets not used by the online theme.
In terms of the actual output file format, all packages are ZIP archives. However, many other file formats, such as ePub, Java WAR applications, and even Microsoft Office documents are actually implemented as ZIP archives. A packager script could be written to emit archives meeting any of these specifications.
The packager.ftl
file will have access to a set of APIs specific to
building packages. It will not have access to most of the tag library used for online
portal pages, though similar tags will be provided by the API in some cases. For example,
a
tag called <@packager.docContents/>
will serve a similar purpose to
<@td.content/>
in online templates, namely, inserting XML, HTML, or
text content into a file, possibly with an XSLT transform.
The config.json
file specifies metadata for a package, such as its file
name, MIME type, and the algorithm to use when determining where in the package to
place the
documents being packaged, and what their output extensions will be. These algorithms
are
expressed using Freemarker expressions.
When a portal user requests a package for a document or documents, the server will
execute
the packager.ftl
template. That script will receive the list of documents
to be packaged as well as a number of other configuration options. Using those variables
and
the packager APIs, the script will add content to the package, and then the built
package will
be delivered to the user.
A Simple Packager
A very basic package builder might look like this.
<#-- Add the /static folder from the theme to the root of the archive --> <@package.put src="/static"/> <#-- Compile the SASS stylesheet --> <@package.preprocessCSS src="/static/style/main/default.scss" dest="/static/style/main/default.css"/> <#-- Add a LICENSE statement from the current packager's directory --> <@package.put src="LICENSE.txt" dest="/about/LICENSE.txt"/> <#-- Generate homepage with links to the documents --> <@package.generate dest="/index.html"> <!DOCTYPE html> <html> <head> <title>${(parameters.title!'WebHelp')?html}</title> <link rel="stylesheet" href="static/style/main/default.css"/> </head> <body> <h1>${portal.displayName?html} Export for ${user.displayName?html}</h1> <ul> <#list documents as doc> <li> <a href="${package.relativeUri(doc)?html}"> ${doc.metadata.title[0]?html} </a> </li> </#list> </ul> </body> </html> </@package.generate> <#-- Generate web pages for the content --> <#list documents as doc> <#-- Actual page templates managed as standalone files --> <#if doc.contentType?contains('pdf')> <#include "docPages/pdf.ftl"/> <#elseif doc.properties.is_ditaMap??> <#include "docPages/map.ftl"/> <#elseif doc.properties.is_ditaTopic??> <#include "docPages/topic.ftl"/> <#else> <#-- Just copy the source into the package. --> <#-- The getDocLocation() function above will determine 'dest' --> <@package.putDocument document=doc/> </#if> </#list>