Read the Tutorial before this, otherwise you won't understand this chapter.
FMPP core and front-ends
FMPP consist of the FMPP core, and the front-ends wrapping that. Front-ends provide interface by which you can communicate with the FMPP core. For example the command-line tool (that we have used previously) is a front-end that provides command-line interface. The FMPP Ant task is another front-end that provides Ant task interface. A graphical front-end could be written too. But whatever front-end you use, you (indirectly) use the FMPP core. So most of the documentation is about the FMPP core, which basically encapsulates all abilities of FMPP.
Note that the FMPP core wraps FreeMarker, the template engine.
For more info see the chapter about writing front-ends.
Settings are variables that describe for the FMPP core what and how to do. Examples of settings you have already met:
data. Front-ends basically do nothing else, just set the settings of the core, and then "trigger" the core to do the job. So if you know all settings, then basically you know everything FMPP can do.
It's a good practice to store the settings of your project in configuration files (as
config.fmpp was). As the FMPP core understand them, you can use them with all front-ends. Configuration files use a simple FMPP specific language, TDD.
File processing and related terms
Processing a file is the act of the generation of the output file (or files) based on a source file. This may means the execution of the file as FreeMarker template, or binary-copying the file, processing the file as XML, or, in extreme case, create no output the file (say, for a
.bak file). The path of the output file relatively to the
outputRoot will be the same as the path of the corresponding source file relatively to the
sourceRoot (at least initially; the template can change the output file path on-the-fly).
Term processing mode refers to how a certain file is processed. In the Quick Tour, the HTML files were processed in "execute" mode, and the image file was processed in "copy" mode. You can find all details about processing modes here.
Processing session: This is the course of batch processing the (selected) files of the source directory. For example, all
fmpp call in the Quick Tour did a processing session.
Strictly speaking, FMPP only processes files, not directories. It looks for source files in the sub-directories of the source root directory recursively, and when an output file has to be created, its missing parent directories will be created automatically. Any setting that deals with processing things is applicable only to files, not to directories (with some exceptions, like
FMPP doesn't use the term "processing" for data files like
data/birds.csv was in the tutorial. A data file isn't processed like a template file (or an image file), it does not produce output file itself. Instead, it can be loaded into a variable for later usage in templates.
Data, data loader
In FMPP context data means data coming from data sources as XML file, CSV file, MySQL database, etc. In the Quick Tour,
data/birds.csv are data files. Files that are processed to produce output files, as the HTML-s and the image are not data files.
The FreeMarker templates see the "data" as variables. This set of variables is called the data model with FreeMarker terminology. The data model is shared, visible for all templates. During output generation the template may creates new variables for temporary calculations, but those variables are not part of the data model, and will gone when the template execution is finished. Templates can't modify the data model, so all templates get the same data model, which was filled with the
data setting at the very beginning of the processing session.
Data loaders are objects that load and interpret data from certain type of data source, so FMPP can expose the data as variables for the templates. For example, in the Quick Tour we have used data loader
csv that interprets CSV files. When the data source is file based, you use paths as data
data/birds.csv. Relative paths are relative to the directory dictated by the
dataRoot setting, which is be default the same as
sourceRoot. Data loaders are described in more details here.
The pp hash
The data model always contains a hash with name
pp (stands for PreProcessor). This hash contains directives and methods and other variables that templates can use to control output generation, do path calculations, and do various other FMPP specific operations. You can find the description of the
pp hash here.
FMPP works with 3 file systems: the real file system, and 2 virtual file systems:
- source file system: The root directory of this file system is the
sourceRootdirectory. Template files usually see this file system, as when they
<#include ...>other template files. All files that FMPP processes must be inside this file system, thus inside the source root directory.
- output file system: The root directory of this file system is the
outputRootdirectory. In templates, directives that control output file names and paths (as
<@pp.changeOutputFile ...>) use this file system. It is guaranteed that all output files will be inside this file system, thus inside the output root directory.
Most directives/methods in templates that require path parameters use one of the virtual file systems. These paths are called virtual paths. Virtual paths always use UN*X style format, so they always use slash (
/), not back-slash (
\). Absolute virtual paths (as
/foo/bar) always start from the virtual file system root (not from the root of the real file-system). You can't leave this root, not even with tricky path as
/... Relative virtual paths (as
../foo/bar) are resolved relatively to:
- If they are used in built-in FreeMarker directives (as
<#import ...>): the directory of the currently executing template.
- If they are used in other directives to refer to source files: the directory of the currently processed source file.
- If they are used in directives to refer to output files: the directory of the currently written output file.
Note that the
dataRoot setting (used by data loaders) just specifies a base directory, not a virtual file system root. So you can leave it with
Paths that navigate in the real file system (not in a virtual file systems) are called real paths. Real paths always use the native path format of the host operating system. However, Windows users can and should use slash (
/) instead of backslash (
\), to keep UN*X compliance, and to avoid escaping issues.
Real paths are used in these cases:
- For setting values that store a path (or paths), such as
outputRoot. Relative paths in these settings are resolved relatively to the, so called, configuration base (unless explicitly stated otherwise for a certain setting). If the setting value comes from a configuration file, then it is the directory that contains the configuration file (however, this can be overridden with the
configurationBasesetting). If the value comes from other source (such as from a command-line argument), then the front-end specifies what the configuration base is for that setting value (see the documentation of the front-end).
- For data loaders that load files, as
csv(data/birds.csv). If the path is relative, then it is relative to the
dataRoot, which defaults to the
sourceRoot. Note that the usage of
/instead of the native path separator (as backslash) is always allowed and recommended here.
- As the parameter to some
ppdirectives/methods that explicitly state this.
In other cases FMPP uses virtual paths.
Adopted FreeMarker type names
FMPP adopts some of FreeMarker's terms regarding the type names, to decrease confusion:
- String: text.
- Boolean: logical value. It can be
- Number: Number... maybe decimal, maybe whole. You often will also see term "integer", which means whole number.
- Sequence: You may know this with name list, or array, or vector. It is a list of values of any type. The items in the list are indexed with integers, starting from 0.
- Hash: You may know this with name dictionary, or map, or associative array. This is a set of name-value pairs. The names are unique strings in the hash, so they identify the values associated with them. As it used to be said, they are "keys".