<@page title="The pp Hash" keywords="pp hash">

The pp hash is a variable that is always present in the data model. This contains the built-in, standard variables of FMPP.

<@note>For more information about variable types, directives, etc. in general, please read the <@fma href="index.html">FreeMarker Manual. <@sect title="Information about the source"> <@variable name="sourceFile" type="string">

The path of the current source file (includes the file name), relatively to the source root directory. It does not start with slash. Uses UN*X path format.

<@variable name="sourceDirectory" type="string">

The path of the directory of the current source file, relatively to the source root directory. It is finished with a slash, except if the directory is the source root directory itself, in which case the result is an empty (0 length) string. The result never starts with slash. Uses UN*X path format.

<@variable name="sourceFileName" type="string">

The filename of the current source file.

<@variable name="sourceEncoding" type="string">

The encoding (charset) of the source file, e.g. <@c>ISO-8859-1. It is always a concrete charset name, never <@c>host.

<@variable name="sourceRoot" type="string">

The absolute real path of the source root directory, finished with a "native slash" (i.e. maybe a backslash). As it is a real path, it uses the native path format.

<@variable name="realSource" type="string">

The absolute real path of the current source file. As it is a real path, it uses the native path format.

<@variable name="realSourceDirectory" type="string">

The absolute real path of the directory of the current source file, finished with a "native slash" (i.e. maybe a backslash). As it is a real path, it uses the native path format.

<@sect title="Information about the output">

Note that as the output file name and directory, and the output encoding can be changed during the execution of template, the value of these variables can change during the execution of the template, to reflect the current situation.

<@variable name="outputFile" type="string">

The path of the current output file (includes the file name), relatively to the output root directory. It does not start with slash. Uses UN*X path format.

<@variable name="outputDirectory" type="string">

The path of the directory of the current output file, relatively to the output root directory. It is finished with a slash, except if the directory is the output root directory itself, in which case the result is an empty (0 length) string. The result never starts with slash. Uses UN*X path format.

<@variable name="outputFileName" type="string">

The filename of the current output file.

<@variable name="outputEncoding" type="string">

The encoding (charset) of the output file, e.g. <@c>ISO-8859-1. It is always a concrete charset name, never <@c>host or <@c>source.

<@variable name="outputRoot" type="string">

The absolute real path of the output root directory, finished with a "native slash" (i.e. maybe a backslash). As it is a real path, it uses the native path format.

<@variable name="realOutput" type="string">

The absolute real path of the current output file. As it is a real path, it uses the native path format.

<@variable name="realOutputDirectory" type="string">

The absolute real path of the directory of the current output file, finished with a "native slash" (i.e. maybe a backslash). As it is a real path, it uses the native path format.

<@sect title="Changing the output file"> <@variable name="changeOutputFile" type="directive"> <@param name="name" type="string"> The new <@a href="overview.html#virtualPath">virtual path of the output file. The path can point into a different directory than the directory of the current output file. <@param name="append" type="boolean" default="false"> If this is true, then if a file with the same name as the name of the new output file already exists, it will be continued, rather then overwritten. If the file does not already exist, then this parameter has no effect.

Closes the current output file, and starts a new output file with the new name. All further output goes into the new file. If the name of the new output file is the same as the current output file, then nothing happens.

A word of warning: Don't forget that the path that you specifiy is interpreted relatively to the <@e>current output file. So using a relative path like <@c>products/${'$'}{productName}.html ( instead of an absolute path like <@c>/shop/products/${'$'}{productName}.html) inside a loop is most certainly not what you want, because then 2nd product will go into the <@c>/shop/products/products/${'$'}{productName}.html directory, the 3rd into <@c>/shop/products/products/products/${'$'}{productName}.html, and so on. Of course this problem doesn't occur if the relative path is just a file name, like <@c>${'$'}{productName}.html.

<@variable name="renameOutputFile" type="directive"> <@param name="name" type="string" optional=true> The new <@a href="overview.html#virtualPath">virtual path of the output file. The path can point into a different directory than the directory of the current output file. <@param name="extension" type="string" optional=true> Replaces the extension (the part after the last dot in the file name) of the current output file, with the value of this parameter. If the file name has no extension (there is no dot in it), then a dot and the new extension is added to the end of the file name. (The parameter value should never contain the starting dot.)

Changes the name of the current output file, or moves the output file if neccessary. If a file with the same name already exists, this will overwrite that file without warning. If the new name is the same as the name of the current output file, then nothing happens.

Either the <@c>name or the <@c>extension parameter must be specified. You can't use both together. <@variable name="dropOutputFile" type="directive">

Deletes the current output file, and drops all further output that would go into this file. Call this directive at the beginning of templates that need to be processed, but you don't want any output files from them. (Of course, you can call this directive even at the end of the template, just that's slower...)

Note that this directive can be neutralized with directive <@c>pp.restartOutputFile.

<@variable name="restartOutputFile" type="directive">

Empties the current output file (but doesn't delete the file). The next character sent to the output will be the first character of the output file. Also, the charset of the output file can be safely set, exactly like if you were at the beginning of the output file creation.

Note that this directive neutralizes the effect of directive <@c>pp.dropOutputFile.

<@variable name="nestOutputFile" type="directive" nestedContent=true> <@param name="name" type="string"> The new <@a href="overview.html#virtualPath">virtual path (includes the file name) of the output file. The path can point into a different directory than the directory of the current output file. <@param name="append" type="boolean" default="false"> If this is true, then if a file with the same name as the name of the new output file already exists, it will be continued, rather then overwritten. If the file does not already exist, then this parameter has no effect.

This is similar to <@c>changeOutputFile, but it writes only the content generated in its nested content into the new file, and then it restores things, so the output will go into the same output file as before the calling of the directive. For example:

<@prg><#noparse> The 1st line of the original file. <@pp.nestOutputFile name="new.txt"> The 1st line of new.txt. The 2nd line of the original file. <@pp.nestOutputFile name="new.txt" append=true> The 2nd line of new.txt. The 3rd line of the original file.

A file can be nested into itself. For example:

<@prg><#noparse> <@pp.nestOutputFile name='1.txt'> The 1st line of 1.txt <@pp.nestOutputFile name='2.txt'> The 1st line of 2.txt <@pp.nestOutputFile name='1.txt'> The 2nd line of 1.txt The 2nd line of 2.txt The 3rd line of 1.txt

Note that <@c>append=true was not needed for adding the 2nd line to the <@c>1.txt, since the directive just switched back to the already opened <@c>1.txt.

<@variable name="setOutputEncoding" type="directive"> <@param name="encoding" type="string"> The name of the charset, e.g. <@c>ISO-8859-2. It understands the special values <@c>source and <@c>host.

Sets the encoding of the output. This will die with error if the output file is already partially written to the disk. Thus, if you want to change the output encoding, do it as early as possible. FMPP buffers the output for the output file in the memory until the buffer size reaches 160 characters, but after that it starts to flush the buffer to the disk. Also, directives that change the current output file may flush the buffer. When you start a new file (say, with <@c>changeOutputFile), it starts a new buffer in the memory, so you can set the encoding of the new file.

<@sect title="Utilities for paths"> <@variable name="pathTo" type="method" result="string"> <@param name="destination" type="string"> The <@a href="overview.html#virtualPath">virtual path in the output file system to the destination file or directory. The destination file or directory need not exist.

This method returns the relative virtual path that leads from the directory of the current output file, to the destination file or directory. For example, if you want to create a link that points to <@c><@r><outputroot>/products/index.html, then you can write:

<@prg><#noparse> Product index

and the link will always point to that file, does not mater where the file that contains the above link is.

The returned path never starts with <@c>/; it is always a relative path.

If the destination path is finished with slash, then, and only then, the resulting path will be also finished with slash, except if the only character in the result would be that slash, in which case the result will be an empty (0 length) string instead.

<@variable name="home" type="string">

Same as what <@c>pp.pathTo('/') would return. That is, the virtual path to the output root directory, from the current output file. It is finished with a slash, except if the current output file is directly in the output root directory, in which case the result is an empty (0 length) string. The result never starts with slash. So the possible values are something like: <@c>../../

Example: The <@c>src will always point to the file in the <@c>img directory of the output root, does not mater if you move the HTML file in the directory hierarchy:

<@prg><#noparse> Logo <@variable name="outputRootRelativePath" type="method" result="string"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual output path to convert. The output file pointed by the path need not exist.

Converts a virtual output path to a virtual output path that is relative to the output root directory. The resulting path will not start with slash.

<@variable name="sourceRootRelativePath" type="method" result="string"> <@param name="file path" type="string"> Same as the parameter of <@a href="#key_outputRootRelativePath">outputRootRelativePath, but it uses the the source file system.

Same as <@a href="#key_outputRootRelativePath">outputRootRelativePath, but it uses the source root directory and the current source file respectively.

<@variable name="sourcePathTo" type="method" result="string"> <@param name="destination" type="string"> Same as the parameter of <@a href="#key_pathTo">pathTo, but it uses the source file system.

Same as <@a href="#key_pathTo">pathTo, but it uses the source root directory and the current source file respectively.

<@variable name="slash" type="string">

The platform dependent slash character used in native paths. This will be backslash (<@c>\) on Windows.

<@variable name="urlEnc" type="method" result="string"> <@param name="string to encode" type="string"> The string to encode.

<@e>Deprecated: use the <@c>url built-in of FreeMarker instead. For example: <@c><#noparse>${"a+b/c"?url}.

Encodes a string with URL encoding. For example the result of <@c>pp.urlEnc("a+b/c") will be <@c>a%2Bb%2Fc, if the output charset is an US-ASCII based charset.

<@variable name="urlPathEnc" type="method" result="string"> <@param name="string to encode" type="string"> The string to encode.

Same as FreeMarker's <@c>url built-in (<@c>?url), except that it does not encode slash characters. For example the result of <@c>pp.urlPathEnc("new products/bálna.html") will be <@c>new%20products/b%E1lna.html, if the output charset is ISO-8859-1.

<@sect title="Utilities for files"> <@variable name="sourceFileSize" type="method" result="number"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the source file system.

Returns the size of the file in bytes. If the file does not exist, it returns 0.

<@variable name="sourceFileLastModified" type="method" result="date (date+time)"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the source file system.

Tells the last modification date+time of file. If the file does not exist, it raises an error.

<@variable name="sourceFileExists" type="method" result="boolean"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the source file system.

Tells if the file exists or not.

<@variable name="outputFileSize" type="method" result="number"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the output file system.

Returns the size of the file in bytes. If the file does not exist, it returns 0.

<@variable name="outputFileLastModified" type="method" result="date (date+time)"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the output file system.

Tells the last modification date+time of file. If the file does not exist, it raises an error.

<@variable name="outputFileExists" type="method" result="boolean"> <@param name="file path" type="string"> The <@a href="overview.html#virtualPath">virtual path of the file in the output file system.

Tells if the file exists or not.

<@variable name="realFileSize" type="method" result="number"> <@param name="file path" type="string"> The real path (native path) of the file. The file can be outside all root directories. FMPP passes the resolving of relative paths to the host OS, so it is not defined by FMPP what the end result will be. In general, it is better to use absolute paths here.
<@e>Windows users: According to the syntactical rules of FTL, you must use double backslashes in string literals: <@c>"C:\\work\\foo\\bar.txt", or use raw strings: <@c>r"C:\work\foo\bar.txt". Also, according to the Windows API rules, you can simply use slash: <@c>"C:/work/foo/bar.txt", which is probably the best solution.

Returns the size of the file in bytes. If the file does not exist, it returns 0.

<@variable name="realFileLastModified" type="method" result="date (date+time)"> <@param name="file path" type="string"> The real path (native path) of the file. The rules are the same as with <@a href="#key_realFileSize">realFileSize.

Tells the last modification date+time of file. If the file does not exist, it raises an error.

<@variable name="realFileExists" type="method" result="boolean"> <@param name="file path" type="string"> The real path (native path) of the file. The rules are the same as with <@a href="#key_realFileSize">realFileSize.

Tells if the file exists or not.

<@sect title="Writable hashes and sequences">

Writable sequences and hashes are an FMPP specific extension to FreeMarker, as FreeMarker does not support the modification of sequences and hashes. (This has good reasons in the on-the-fly dynamic page generation segment that FreeMarker mostly targets, but it can be a problem in extreme FreeMarker applications as FMPP.) To read the variables of these sequences and hashes, you can use the same expressions as with plain sequences and hashes. But, to modify the contents of them, you have to use the directives described below, since predefined directives as <@c><#assign <@r>...> can't modify subvariables. Unfortunately, sequence addition, sub-sequence operator (like <@c>seq[5..10]) and <@c>?reverse do not copy the original sequence, just wraps it (for efficiency), so the resulting sequence will change if the original sequence is changed later (this is basically an abnormal aliasing effect). The same problem exists with the result of hash addition; it just wraps the two hashes, so the resulting hash will magically change if you modify the hashes you have added earlier. As a work-around, after you did the above problematic operations, either be sure you will not modify the objects that were used as input, or create a copy of the result like: <@c><#assign b = pp.newWritableSequence(a[5..10])> and <@c><#assign c = pp.newWritableHash(hashA + hashB)>). Of course this is easy to miss... so rather try to build the data model so you will not need to modify collections. Keeping templates simple and moving complex calculations out to custom <@a href='dataloader.html'>data loaders or BeanShell scripts (see the <@c>bsh function of <@s>localData <@a href='settings.html#data'>here...) is advisable anyway.

Note that only the sequences that were made with the <@c>newWritableSequence method are writable. Also, only the hashes that were made with the <@c>newWritableHash method are writable. You can't modify plain sequences or hashes with the below directives.

Also note that writable sequences and hashes suffer from the effect called aliasing (that most programmers will find natural). This effect, explained with an example, looks like this:

<@prg><#noparse> <#assign a = pp.newWritableSequence()> <@pp.add seq=a value="red" /> <#assign b = a> <@pp.add seq=b value="green" /> a: <#list a as i>${i} b: <#list b as i>${i}

Here the output will be:

<@prg> a: red green b: red green

That is, FreeMarker variables just store a reference (pointer) to the sequence or hash, not the sequence or hash itself. So both <@c>a and <@c>b points to the same single sequence object, which floats somewhere in the memory. This fact becomes significant because you modify that object, otherwise you wouldn't notice it. To create individual copies, use <@a href="#key_newWritableSequence"><@c>newWritableSequence or <@a href="#key_newWritableHash"><@c>newWritableHash, for example:.

<@prg><#noparse> <#assign a = pp.newWritableSequence()> <@pp.add seq=a value="red" /> <#assign b = pp.newWritableSequence(a)> <@pp.add seq=b value="green" /> a: <#list a as i>${i} b: <#list b as i>${i}

Here <@c>b is a new sequence whose initial content is the same as the content of <@c>a. Thus, the output will be:

<@prg> a: red b: red green <@variable name="newWritableSequence" type="method" result="writable sequence"> <@param name="initial content" optional=true type="sequence" />

Creates a new empty writable sequence. However, if called with parameter then adds the items in the parameter sequence to this new sequence (known as "shallow copy" among programmers). Example:

<@prg><#noparse> <#assign a = pp.newWritableSequence()> <#assign b = pp.newWritableSequence(['red', 'green', 'blue'])> ${a?size} ${b?size}

The output will be:

<@prg><#noparse> 0 3 <@variable name="newWritableHash" type="method" result="writable hash"> <@param name="initial content" optional=true type="hash" />

Creates a new empty writable hash. However, if called with parameter then adds the items in the parameter hash to this new hash (known as "shallow copy" among programmers). Example:

<@prg><#noparse> <#assign a = pp.newWritableHash()> <#assign b = pp.newWritableHash({'red':'FE0000', 'green':'10F000', 'blue':'0007FF'})> ${a?size} ${b?size}

The output will be:

<@prg><#noparse> 0 3 <@variable name="copyWritable" type="method" result="writable hash or writable sequence" deprecated='Use <@a href="#key_newWritableSequence"><@c>newWritableSequence and <@a href="#key_newWritableHash"><@c>newWritableHash instead.'>

Copies a writable hash or sequence. (It is used to prevent aliasing effect. The result is a "shallow copy" of the original hash or sequence.)

<@variable name="add" type="directive"> <@param name="seq" type="writable sequence">The sequence to modify. <@param name="index" type="number" default="seq?size">The index where you want to insert the subvariable into the sequence. The index of the first subvariable is 0. <@param name="value" type="any">The new value of the subvariable.

Inserts a new subvariable into the sequence, at the specified index. Shifts the subvariable currently at that position (if any) and any subsequent subvariables to the right (adds one to their indices). If you do not use the <@c>index parameter, or if its value is 1 higher than the index of the last subvariable, then it appends the new subvariable at the end of the sequence.

<@variable name="set" type="directive"> <@param name="seq" type="writable sequence">The sequence to modify. <@param name="index" type="number">The index of subvariable to set. The index of the first subvariable is 0. <@param name="hash" type="writable hash">The hash to modify. <@param name="key" type="string">The name of the subvariable that you want to add to the hash, or that you want to replace. <@param name="value" type="any">The value of the new subvariable.

This can be used for two purposes, depending on if you use the <@c>seq or the <@c>hash parameter:

<@variable name="remove" type="directive"> <@param name="seq" type="writable sequence">The sequence to modify. <@param name="index" type="number">The index of the subvariable to remove. <@param name="hash" type="writable hash">The hash to modify. <@param name="key" type="string">The name of the subvariable that you want to remove from the hash.

This can be used for two purposes, depending on if you use the <@c>seq or the <@c>hash parameter:

<@variable name="clear" type="directive"> <@param name="seq" type="writable sequence">The sequence to clear. <@param name="hash" type="writable hash">The hash to clear.

Removes all subvariables of the sequence or hash.

<@sect title="Miscellaneous"> <@variable name="warning" type="directive"> <@param name="message" type="string">The warning message.

Issues a warning message. It depends on the concrete front-end in use and the settings, but usually the message will be displayed on the screen and/or will be added to the log file. The processing will not stop if you issue a warning. To stop processing with error message you should use <@c><#stop "<@r>message">.

<@variable name="ignoreOutput" type="directive" nestedContent=true>

All text generated inside the nested content of this directive will be thrown away.

<@variable name="locale" type="string">

The currently used locale in the usual format. For example: <@c>ar_SA, <@c>ar_IQ, <@c>en_US, <@c>en_UK, <@c>es_ES, ...etc. <@variable name="loadData" type="method" result="any" anchor="loadData"> <@param name="loader name" type="string"> The name of the data loader. <@param name="arguments..." type="any"> The arguments to the data loader. These are 0 or more arguments.

Loads data using <@a href="dataloader.html">data loaders, and returns the loaded data as the result of the method call. For example this:

<@prg><#noparse> <#assign foo = pp.loadData('csv', 'foo.txt', {'separator':',', 'encoding':'UTF-8'})>

does something similar as when you use the below in an FMPP configuration file:

<@prg> data: {foo:csv(foo.txt, {separator:',', encoding:UTF-8})}

The difference is that with the <@c>pp.loadData, you load the data on demand, and into a temporary variable that will be available only for a single template processing.

The <@c>get data loader can't be invoked with this method. <@variable name="now" type="date (date+time)">

Returns the current date and time.

For example this:

<@prg><#noparse> Current date and time: ${pp.now} Current time: ${pp.now?time} Current date: ${pp.now?date} Current day of week: ${pp.now?string("EEEE")} <#setting datetime_format="yyyy-MM-dd HH:mm:ss zzzz"> Current date and time: ${pp.now}

will output something like this:

<@prg> Current date and time: Apr 12, 2003 5:28:50 PM Current time: 5:28:50 PM Current date: Apr 12, 2003 Current day of week: Saturday Current date and time: 2003-04-12 17:28:50 Central European Summer Time

For more information about using date/time values, please read the <@fma>FreeMarker Manual.

<@variable name="sessionStart" type="date (date+time)">

Returns the date and time of the processing session starting.

<@variable name="s" type="writable hash">

Stands for "shared". This is a writable hash that keeps its content during the whole processing session. That is, if you add a subvariable to it during the execution of a template, then that subvariable will be visible for all templates processed later in the same session. An example of the usage of <@c>pp.s can be found in <@example 'session' />

<@variable name="doc" type="node">

This variable exists only while an XML file is processed in <@c>renderXml processing mode (see the documentation of the <@s>modes setting). This variable stores the source file (the XML file) as a node variable that corresponds to the W3C DOM document object.

An example that uses <@c>renderXml processing mode and <@c>pp.doc is <@example 'xml_rendering' />

<@variable name="version" type="string">

This is the version number of the FMPP engine.

<@variable name="freemarkerVersion" type="string">

This is the version number of the FreeMarker the FMPP engine currently uses.