Dist::Zilla::Role::TextTemplater::Manual - TextTemplater role user manual
TextTemplater
Version v0.8.7, released on 2018-02-27 21:17 UTC.
Dist-Zilla-Role-TextTemplater is a Dist::Zilla role, a replacement for standard role TextTemplate. Both roles have the same great Text::Template engine under the hood, but this one provides better control over the engine and much better error reporting.
Dist-Zilla-Role-TextTemplater
Dist::Zilla
TextTemplate
Text::Template
This is TextTemplater role user manual. Read this if you are using a TextTemplater-based plugin.
If you want to have text templating capabilities in your Dist::Zilla plugin, read the module documentation. General topics like getting source, building, installing, bug reporting and some others are covered in the README.
In your dist.ini:
[APlugin] delimiters = (* *) package = MY prepend = use strict; prepend = use warnings; … ; Other APlugin-specific options.
(It is assumed you are using Text-Templater-based plugin named APlugin.)
Text-Templater
For sake of brevity in this manual the term APlugin means "any TextTemplater-based plugin" or "any plugin which consumes TextTemplater role".
TextTemplater is a Dist::Zilla role. It cannot be directly used by the end user. However, the role provides the same behavior and options for all TextTemplater-based plugins (including APlugin, of course). Describing common behavior and options in single place makes documenting APlugin simpler.
TextTemplater is just a bridge between APlugin and the great Text::Template templating engine, so reading Text::Template documentation is highly recommended for better understanding of gory details.
Must read this first: "Philosophy" in Text::Template.
Template is text with (zero or more) embedded Perl code fragments:
…plain text {{ Perl code fragment }} plain text again…
TextTemplater evaluates code fragments in order of appearance and replaces each fragment with the result of its evaluation. For example, template
2 + 2 = {{ 2 + 2 }}.
is processed to
2 + 2 = 4.
The example above is trivial, but Perl code fragments can be arbitrary complex: full Perl power is at your service.
As stated above, template is just text. It could be a source file, a value of an option from your dist.ini, or whatever else — it depends on APlugin. TextTemplater processes ("fills in") the provided template, while providing the template is APlugin responsibility.
Gory details: "Template Parsing" in Text::Template. However, take into account that TextTemplater default delimiters are likely "alternative delimiters" for Text::Template, so backslash escaping does not work.
In order to be recognized a Perl code fragment must be separated from surrounding plain text by the pair of delimiters: opening delimiter and closing delimiter. TextTemplater default opening delimiter is {{, default closing delimiter is }}, they are used in all the code fragment examples in this manual.
{{
}}
Note: APlugin can override TextTemplater default, though. Also, user can set desired delimiters in the delimiters option.
delimiters
Gory details: "Alternative Delimiters" in Text::Template.
There are few predefined variables which can be used in Perl code fragments. TextTemplater defines two variables, and one is defined by Text::Temlate.
Note: APlugin may define more variables or cancel definitions of $plugin and $dist.
$plugin
$dist
Reference to Dist::Zilla object. Primary purpose of the variable is providing access to the distribution properties, like
This is {{$dist->name}} version {{$dist->version}}…
but $dist gives full access to Dist::Zilla object:
The list of installed modules: {{ join( ", ", map( { $_->name } @{ $dist->find_files( ":InstallModules" ) } ) ); }}.
Reference to the plugin. The variable is provided for compatibility with GatherDir::Template plugin. The variable can be used for debug or error reporting, e. g.:
GatherDir::Template
{{ …; $plugin->log_debug( … ); …; }} {{ …; if ( … ) { $plugin->log_fatal( … ); }; … }}
Gory details: "The $OUT variable" in Text::Template.
By default all the code fragments in a template are evaluated in the context of the same private package ("private" is not the package name). The package called "private" because it is created specially for processing of this template, code fragments of another template are evaluated in the context of another private package.
Default behavior can be changed by package option. If value of the option is not empty, all templates share the same package. Use it carefully because one template can affect another template implicitly.
package
Note: APlugin can set another default or ignore package option specified by user.
Gory details: "PACKAGE" in Text::Template. Note that default behavior (when package is not explicitly set) in Text::Template and TextTemplate differs.
If every your Perl code fragment starts with the same prologue (e. g. use strict;), you can let the template engine insert this prologue automatically. Just specify your prologue in the "prepend" option.
use strict;
Gory details: "PREPEND feature and using strict in templates" in Text::Template.
The role provides three options: delimiters, package and prepend. Options can be specified by user in the APlugin section of the dist.ini file:
prepend
[APlugin] delimiters = (* *) package = MY prepend = use strict;
Pair of delimiters to separate code fragments from surrounding text, see "Delimiters".
The value should consist of two whitespace-separated delimiters: opening delimiter and closing delimiter. Leading and trailing whitespaces are ignored.
Name of package to evaluate code fragments in, see "Package".
Perl code to automatically prepend to the beginning of every code fragment, see "Prepend".
Option may be specified several times. Every value will be a separate line of code.
prepend = use strict; prepend = use warnings; prepend = use utf8;
TextTemplate role from Dist::Zilla distribution v5.037 has the same great Text::Template engine under the hood, but lacks of control and has awful error reporting.
Let us consider an example. For sake of example simplicity, it contains only one file, dist.ini. Two files, lib/Assa.pm and lib/Assa.pod, are generated on-the-fly with GenerateFile plugin.
GenerateFile
Have a look at dist.ini:
name = Assa version = 0.001 abstract = Example [GenerateFile/lib/Assa.pm] filename = lib/Assa.pm content = package Assa; 1; [GenerateFile/lib/Assa/Manual.pod] filename = lib/Assa/Manual.pod content = =head1 NAME content = content = {{$dst->name} - {{$dist->abstract}} content = content = Version {{$dist->version}}. content = content = {{$dist->license->notice}} [TemplateFiles] filename = lib/Assa.pm filename = lib/Assa/Manual.pod [MetaResources::Template] homepage = https://example.org/release/{{$dist->name}} license = {{$dist->license->url}}
(Do you see a typo? How many? Note this is a small example, real files are much larger.) Now let us build the distribution:
$ dzil build [DZ] beginning to build Assa [TemplateFiles] Filling in the template returned undef for: [TemplateFiles] =head1 NAME [TemplateFiles] [TemplateFiles] {{$dst->name} - {{$dist->abstract}} [TemplateFiles] [TemplateFiles] Version {{$dist->version}}. [TemplateFiles] [TemplateFiles] {{$dist->license->notice}} [TemplateFiles] Filling in the template returned undef for: [TemplateFiles] =head1 NAME [TemplateFiles] [TemplateFiles] {{$dst->name} - {{$dist->abstract}} [TemplateFiles] [TemplateFiles] Version {{$dist->version}}. [TemplateFiles] [TemplateFiles] {{$dist->license->notice}} at /home/vdb/.usr/opt/local-lib/lib/perl5/x86_64-linux-thread-multi/Moose/Meta/Method/Delegation.pm line 110.
Oops. What's happened? Where? Why? All we have is a highly unclear error message
Filling in the template returned undef for:
and file content printed twice. (Yep, if the file had 1000 lines, we would have it printed twice too.) We do not ever have a file name and have to guess it by the content. Good bug hunting, dude.
Ok, let us fix the problem (mistyped closing delimiter in the first line of file lib/Assa/Manual.pod) and build the distribution again:
$ dzil build [DZ] beginning to build Assa Can't call method "name" on an undefined value at template line 3.
Oops. Error message much is better now, but where the problem is? There are many templates in the project: lib/Assa.pm, lib/Assa/Manual.pod, and even resources in META.yml — all are generated from templates. Where is the problem? Good bug hunting for us all.
Such error reporting is simply unacceptable. I am a human, I often make mistakes, and I want the tool clearly warns me what and where the problem is, so I can fix it quickly. For example, in the first case I want to see:
$ dzil build [DZ] beginning to build Assa [Templates] Unmatched opening delimiter at lib/Assa/Manual.pod line 3. [Templates] lib/Assa/Manual.pod: [Templates] 1: =head1 NAME [Templates] 2: [Templates] 3: {{$dst->name} - {{$dist->abstract}} [Templates] ^^^ Unmatched opening delimiter at lib/Assa/Manual.pod line 3. ^^^ [Templates] 4: [Templates] 5: Version {{$dist->version}}. [Templates] ... skipped 2 lines ... Aborting...
In the second case:
$ dzil build [DZ] beginning to build Assa [Templates] Can't call method "name" on an undefined value at lib/Assa/Manual.pod line 3. [Templates] Bad code fragment begins at lib/Assa/Manual.pod line 3. [Templates] lib/Assa/Manual.pod: [Templates] 1: =head1 NAME [Templates] 2: [Templates] 3: {{$dst->name}} - {{$dist->abstract}} [Templates] ^^^ Can't call method "name" on an undefined value at lib/Assa/Manual.pod line 3. ^^^ [Templates] ^^^ Bad code fragment begins at lib/Assa/Manual.pod line 3. ^^^ [Templates] 4: [Templates] 5: Version {{$dist->version}}. [Templates] ... skipped 2 lines ... Aborting...
TextTemplater makes it real. All I need is using TextTemplater-based plugins: Templates, MetaResources::Template (starting from v0.002).
Templates
MetaResources::Template
TextTemplater allows the end-user to specify delimiters, package and prepend engine options in dist.ini file, while TextTemplate allows to specify prepend only programmatically, and does not allow to specify delimiters and package.
Van de Bugger <van.de.bugger@gmail.com>
Copyright (C) 2015, 2016, 2018 Van de Bugger
License GPLv3+: The GNU General Public License version 3 or later <http://www.gnu.org/licenses/gpl-3.0.txt>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
To install Dist::Zilla::Role::TextTemplater, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Dist::Zilla::Role::TextTemplater
CPAN shell
perl -MCPAN -e shell install Dist::Zilla::Role::TextTemplater
For more information on module installation, please visit the detailed CPAN module installation guide.