telf - Process templates using YAML input
telf --recurse [options] template|directory... directory
telf --iterate [options] template
telf [options] template
telf is a general-purpose template-processing program that makes it possible to define template variables and configuration settings using YAML files. It processes templates written in Template Toolkit (version 2) syntax and is meant as a more powerful alternative to both tpage(1) and ttree(1).
telf may be invoked in different ways (the so-called run modes) to accomplish three different tasks:
This processes a file tree containing multiple templates, putting the output of each file into the corresponding file in a separate file tree, and is similar to the use of ttree(1).
Patterns may be used to limit the files to process as templates, to specify files that should be copied rather than being processed as templates, and to filter out files that should be skipped altogether.
Recursive processing is indicated by use of the -r (or --recurse) option.
In iterative processing, a single template is processed multiple times, once for each value found in a YAML data file.
For example, take the following simple template:
# Template `person.tt2':
[% person.name %] is [% person.age %] years old.
Assume the following data file, which contains two values in YAML format:
# Data file `people.yaml':
--- #YAML:1.0
name: Ulysses K. Fishwick
age: 93
--- #YAML:1.0
name: Yolanda P. Ipswich
age: 2
To process a template iteratively, use the -e or --iterate option to specify the YAML data file and the name of the variable which will hold each value in turn, like this:
telf --iterate variable=datafile template
In the case of this example, the command would be as follows:
telf --iterate person=people.yaml person.tt2
The output will be as follows:
Ulysses K. Fishwick is 93 years old.
Yolanda P. Ipswich is 2 years old.
(Other options may be specified as well, in any order.)
This corresponds to the use of tpage(1) to process a single template, except that the resulting output is always simply written to standard output.
Single-template processing is indicated by the absence of -r, --recurse, -e, and --iterate options.
Command-line options fall mostly into three categories: template configuration (specifying Template Toolkit configuration settings), template variables (data used by the template itself to generate the desired output), and template selection (specifying which template(s) to apply).
Most options have a long form (e.g., --recurse) as well as a short form (e.g., -r).
The following options have special meaning:
Print helpful information and exit.
Print version information and exit.
Be verbose in reporting files processed or skipped.
The following options are used to define Template Toolkit configuration parameters, and are valid in any run mode.
-c ABSOLUTE=1
-c TAG_STYLE=star
-c INTERPOLATE=1
-c DEBUG=parser,provider
-c COMPILE_EXT=.ttc
-c COMPILE_DIR=/tmp/ttc
Set a template configuration parameter. See the Template Toolkit documentation for a complete list.
NOTE: Since the names of all Template Toolkit configuration parameters contain no lower-case letters, the configuration parameter name is normalized to all upper case; hence, the following are all equivalent:
-c ABSOLUTE=1
-c absolute=1
-c aBsOLUte=1
-C INCLUDE_PATH=includes.yaml
-C config.yaml
Read configuration information from a YAML file.
If a name is specified, this option sets the value of the named configuration parameter to the value found in the given YAML file.
Otherwise, the specified file must contain a single hash in YAML format; each element of this hash defines a configuration parameter.
As in the -c or --config option, configuration parameter names are case-insensitive; hence, the following are equivalent:
-C INCLUDE_PATH=includes.yaml
-C include_path=includes.yaml
(File names may or may not be case-sensitive, of course, depending on your operating system and other factors.)
The following options are used to define variables whose values may be used in processing templates; these options are valid in any run mode.
-d foo=bar
-d baz='In a hole in the ground there lived a Hobbit.'
Define a template variable, setting it to a simple scalar value. The variable
name is separated from its value using a single equals sign (=), which must
not have any whitespace around it. The value may be empty; for example:
-d qux=
-D variables.yaml
-D news=news.yaml
This option allows one to set the values of variables to complex values such as hashes, arrays, or objects. A variable can thus have any value that can be serialized into YAML form.
If a name is specified, this option sets the value of the named template
variable to the value found in the given YAML file. The variable name is
separated from the file name using a single equals sign (=), which must not
have any whitespace around it.
If no variable name is specified, the data file must contain a single hash in YAML format; each element of this hash defines a variable. For example, the following file if named in a -D option with no variable name would set the values of the variables foo, bar, and baz:
--- #YAML:1.0
foo: abcdef
bar:
- four
- five
- six
baz:
seven: 7
eight: 8
nine: [ neuf, nueve, neun ]
ten: 10
Template variables may be defined using any combination of -d (or --variable) and -D (or variable-file) options. Any number of variables may be defined (up to the limits of your shell, of course); these will be merged together using Hash::Merge, with values ocurring later taking precedent.
For example, the following command will result in the value of
the template variable foo being set to 123:
$ telf -d foo=abc -d foo=xyz -D foo=bar.yaml -d foo=123
Define template variables using the YAML document found at the beginning of each
template and separated from the template proper by a line consisting of the
string .... The value of a variable set in this way overrides any other
definition for the variable; unlike the other options, there is no merging of
values.
For example, suppose that the file foo.tt2 looks like this:
--- #YAML:1.0
foo: bar
baz: qux
...
My foo is *[% foo %]* and my baz is /[% baz %]/. Watch out!
The result of running the command telf -d foo=12345 -H foo.tt2 is this:
My foo is *bar* and my baz is /qux/. Watch out!
When in iterative or recursive run mode, variables set from a template's header are in effect only during the processing of that template, and do not persist to be used by templates processed later in the run.
Note: If this option is specified, every template processed must begin with a single YAML document.
Process the named template, printing the result to standard output. This is the default run mode, so this option may be omitted as long as the other run mode options aren't used.
Process templates in the specified directory and all subdirectories, recursively processing each file in the entire tree rooted at the directory and writing the result to the corresponding file in the designated destination tree (the directory named in the last argument on the command line).
Files whose names match a skip pattern (specified using an -s or --skip option, as described below) are ignored, and files whose names match a copy pattern (in a -u or --copy option) are copied rather being processed as templates.
All other files are processed as templates unless one or more process patterns are specified using the -p or --process option described below, in which case only those files that match a process pattern (and that weren't skipped or copied) are processed as templates.
Unless the -f or --force option is specified, a template will not be processed if it hasn't been modified since the last time it was processed.
This option is mutually exclusive with the -e or --iterate option.
Use the iterative run mode to process the template once for each value in the specified YAML file.
The YAML file must consist of a sequence of YAML values, like this:
--- #YAML:1.0
one: 1
two: 2
--- #YAML:1.0 foobar
--- #YAML:1.0
- three
- four
This option is mutually exclusive with the -r or --recurse option.
The next two options may be used in any run mode to specify templates for pre- or post-processing. Their significance varies slightly depending on the run mode.
Specify a template that is to be processed immediately before each template.
If the -e or --iterate option is specified, a template specified using -b or --before is processed just once; this is very different than what happens using -c PRE_PROCESS=template, when the named template is processed once for each value in the YAML data file named in the -e or --iterate option.
If the -e or --iterate option is not specified, on the other hand, the use of -b template or --before template is equivalent to -c PRE_PROCESS=template except that this option may be repeated to specify multiple pre-processed templates.
If you want to pre-process multiple templates before each iteration when using -e or --iterate, use -C PRE_PROCESS=preprocess.yaml (or -C config.yaml with PRE_PROCESS set to multiple values).
Specify a template that is to be processed immediately after each template.
The same caveats apply to -a or --after that apply to -b and --before.
The following options are valid only in recursive processing; they delimit which files are to be processed as templates, which files are to be copied, and which files are to be skipped altogether.
Process or copy all non-skipped files in the source directory regardless of whether they've been modified since the last time they were processed.
This option is invalid if the -r or --recurse option is not specified.
Don't process any files; instead, report what would have been processed (or copied, skipped, etc.). This is handy for testing skip and copy patterns.
See DIAGNOSTICS below for more information on what is reported.
Delete files in the destination directory whose corresponding files in the source directory are to be skipped. Files in the destination directory that have no corresponding file in the source directory will not be deleted.
Generally speaking, the only time you'll use this option is after you've changed skip patterns so that files that formerly were not skipped now are.
Limit the processing of templates to those files whose names match the specified pattern. If this option is not specified (and no -s or --skip option is given), every file in the source tree is processed by default (subject to exclusion by copy and skip patterns as described below).
The pattern may be a file glob (e.g., *.html) or a Perl-style regular
expression surrounded by slashes (e.g., /\.html$/. Careful quoting may be
needed to keep your shell from interpreting special characters such as $ and
*.
This option may be repeated; a file will be processed if its name matches any of the specified patterns, unless its name also matches a skip pattern or copy pattern as described below.
This option is invalid if the -r or --recurse option is not specified.
Copy files matching the given pattern without processing them as templates. The pattern may be a file glob or a Perl-style regular expression surrounded by slashes, as described above for the option -p. For example, wither of these commands will copy GIF image files:
telf -u '*.gif' ...
telf -u '/\.gif$/' ...
This option may be repeated; a file will be copied if its name matches any of the specified copy patterns, regardless of whether its name also matches a process pattern (but subject to exclusion by a skip pattern, for which see below).
This option is invalid if the -r or --recurse option is not specified.
Do not process or copy files whose names match the specified pattern. The pattern may be a file glob or a Perl-style regular expression surrounded by slashes, as described above for the option -p.
This option may be repeated; a file will be skipped if its name matches any of the specified skip patterns, regardless of whether its name also matches a process pattern or skip pattern.
This option is invalid if the -r or --recurse option is not specified.
When processing a template (not when simply copying a file), strip the specified suffix from the resulting file name. The suffix may be specified with or without a leading period (`.').
This option comes in handy when you want to use a file suffix to identify all the files to process as templates; for example, the following command will process only those source files whose names end in `.tt2', stripping the suffix from the names of the resulting files and simply copying all other files:
telf -p '*.tt2' -x .tt2 -u '*' src dest
This option may be repeated; it's invalid if the -r or --recurse option is not specified.
Specify a file containing patterns that designate files to be processed. This is equivalent to specifying each line in the file in a -p or --process option.
This option may be repeated.
Specify a file containing patterns that designate files to be copied. This is equivalent to specifying each line in the file in a -u or --copy option.
This option may be repeated.
Specify a file containing patterns that designate files to be skipped. This is equivalent to specifying each line in the file in a -s or --skip option.
This option may be repeated.
Specify a file containing suffixes to be stripped from file names. This is equivalent to specifying each line in the file in an -x or --strip-suffix option.
This option may be repeated.
These next options are valid only in iterative processing.
After each numberth iteration, print the iteration number to standard error (unless the --report-key option is specified: see below).
This option is assumed if the --report-key option is specified.
This option is invalid if the -e or --iterate option is not specified.
If iterated values are hashes (i.e., aggregate data containing named elements), print the named element of each reported value. Otherwise, fall back to printing the number of the iteration.
This option is invalid if the -e or --iterate option is not specified.
In recursive mode, and if you've specified verbose mode (-v or --verbose), each source file will be reported along with a code indicating whether the file was processed as a template, copied, skipped, and so on.
If a file in the destination tree was deleted (because the corresponding file in the source tree was skipped and the -Z or --delete-skipped-files option was specified), then the deleted file is reported, not the source file corresponding to it. Otherwise, it's the source file that's reported.
The following symbols are used:
The file has been (or would be) added to the destination tree.
The file has been modified.
The file has been copied.
The file has not changed since the last time telf was run.
The file has been skipped.
The file has been deleted.
telf doesn't know what to do with the file.
An error occurred, and the file couldn't be handled properly.
This is used to denote a comment.
Enable the use of dotted-path notation to set variables. For example:
telf -D variables.yaml -d people.3.name=Fishwick
Extract core functionality into a Perl module and leave hooks for data formats other than YAML?
Paul Hoffman (nkuitse AT nkuitse DOT com)
Copyright 2004-2006 Paul M. Hoffman.
This is free software, distributed under the same terms as Perl itself.
No known bugs.
Template, YAML, IO::YAML.