Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

*** empty log message ***

git-svn-id: svn://svn.tt2.org/tt/Template2/trunk@22 d5a88997-0a34-4036-9ed2-92fb5d660d91
  • Loading branch information...
commit e39913fdf696f2f88012d62c57a6ffec2be50f5d 1 parent 2d44872
@abw authored
View
384 Changes
@@ -13,6 +13,7 @@
#========================================================================
+
#========================================================================
# ***** VERSION 2.00 *****
#
@@ -125,7 +126,18 @@ New Language Features
* Comments now only extend to the end of the current line.
- [%
+ [% # this is a comment
+ a = 10
+ # so is this
+ b = 20
+ %]
+
+ Placing the '#' character immediately inside the directive will comment
+ out the entire directive
+
+ [%# entire directive
+ is ignored
+ %]
* The TAGS directive can now be used to switch tag styles by name.
Several new tag styles are defined (e.g. html, asp, php, mason).
@@ -282,14 +294,14 @@ Configuration Options
The new Template::Provider which manages the loading of template files
will correctly adapt to chahges in the INCLUDE_PATH and act accordingly.
-* The TEMPLATES option allows you to specify a list of one or more
+* The LOAD_TEMPLATES option allows you to specify a list of one or more
Template::Provider object which will take responsibility for loading
templates. Each provider can have it's own INCLUDE_PATH, caching
options (e.g CACHE_SIZE) and so on. You can sub-class the
Template::Provider module to allow templates to be loaded from a
database, for example, and then define your new provider in the
- TEMPLATES list. The providers are queried in order as a "Chain of
- Responsiblity". Each may return a compiled template, raise an
+ LOAD_TEMPLATES list. The providers are queried in order as a "Chain
+ of Responsiblity". Each may return a compiled template, raise an
error, or decline to serve the template and pass control onto the
next provider in line.
@@ -315,14 +327,19 @@ Configuration Options
(e.g. /tmp/somefile) or relative (e.g. ../tmp/another) filenames. Both
are disabled by default.
-* The PLUGINS option is similar to TEMPLATES but allows you to specify
- one or more plugin providers. These take responsibility for loading
- and instantiating plugins. The Template::Plugins module is the default
- provider and multiplexes requests out to other Template::Plugin::*
- plugin modules.
+* The LOAD_PLUGINS option is similar to LOAD_TEMPLATES but allows you
+ to specify one or more plugin providers. These take responsibility
+ for loading and instantiating plugins. The Template::Plugins module
+ is the default provider and multiplexes requests out to other
+ Template::Plugin::* plugin modules. Loading of plugins has been
+ simplified and improved in general The PLUGINS option can be used to
+ map plugin names to specific modules and PLUGIN_BASE can map plugins
+ into particular namespaces. The LOAD_PERL option can be used to
+ load (almost) any regular Perl module and use it as a plugin.
-* The FILTERS option is the same but for providing filters. The
- Template::Filters module is the default provider here.
+* The LOAD_FILTERS option is similar to LOAD_TEMPLATES and LOAD_PLUGINS,
+ allowing one or more custom providers to be specified for providing
+ filters. The Template::Filters module is the default provider here.
* The TOLERANT option can be used to tailor the behaviour of providers
(e.g. Template::Provider, Template::Plugins, Template::Filters) when
@@ -346,155 +363,7 @@ Configuration Options
now we're interpolating variables again, like $var
* Added the TRIM option to automatically removed leading and trailing
- whitespace from the output of templates and BLOCKs. This was suggested
- by someone on the mailing list (was it Swen?) but I recall who at the
- moment. I'll check and fill in this **gap**, but thanks to him anwyay.
-
-
-Plugins and Filters
--------------------
-
-* Added the 'upper' and 'lower' filters for case folding text.
-
-* Added the Date plugin, as provided by Thierry-Michel Barral.
-
-Tools
------
-
-* Added the --define var=val option to ttree
-
-Gotchas
--------
-
- * Bare CATCH blocks are no longer permitted and must be explicitly
- scoped with a matching TRY. In most cases, this simply means adding
- a [% TRY %] to the start of any templates that define CATCH blocks,
- and ensuring that the CATCH blocks are moved to the end of the file
- (or relevant place).
-
- # version 1 - no longer supported
- blah blah blah...some error occurs
-
- [% CATCH some_kind_of_error %]
- handler template...
- [% END %]
-
- # version 2
- [% TRY %]
- blah blah blah...some error occurs...
-
- [% CATCH some_kind_of_error %]
- handler template...
- [% END %]
-
- Also be aware that this may change the expected output in case of
- errors. By default, all output in the TRY block up to the point
- of error will be returned, with the relevant catch block, and then
- and further template output appended. You can use [% CLEAR %] within
- a CATCH block to clear the output from the TRY block, if you prefer.
- TRY blocks can be nested indefinately.
-
- * The ERROR directive is no longer supported. It was very ill-defined
- anyway and serves no purpose that can't be acheived by defining
- custom filters, error handlers bound to template variables, or whatever.
- I haven't implemented any special error or logging facilities, other
- than the general purpose exception handling, but welcome any thoughts
- on what or if anything else is needed.
-
- * The current exception caught in a catch block is now aliased to the
- variable 'error' rather than 'e'. This is much more logical, IMHO,
- and was only prevented previously by 'error' being a reserved word.
- Note that 'e' is still defined, in addition to 'error'. This may
- be deprecated at some point in the future.
-
- * The use of a leading '$' on variables is no longer optional, and
- should only be used to explicitly to indicate interpolatation of a
- variable name. Most of the time you *don't* want to do this, so
- leave the '$' off. This represent a slight shift away from the
- (optional) Perlness of the language, but I think it's a necessary
- step to improve the clarity and consistency of the language.
-
- As previously discussed on the mailing list, in interpolated text
- (i.e. a "double quoted" string or regular template text with
- INTERPOLATE set), both '$foo' or '${foo}' are interpolated as the
- value of the variable 'foo'. This is good because it is a
- de-facto standard, consistent with Perl, shell, etc. But inside a
- directive, [% $foo %] and [% ${foo} %] mean different things, the
- first being equivalent to [% foo %] or [% GET foo %] (the leading
- '$' is ignored) but the second actually fetching a variable whose
- name is stored in the variable 'foo'. In other words, '${foo}'
- interpolates to the value of foo ('bar', say) and then this is
- used as the parameter to GET (which itself is optional). Thus, in
- this case, [% ${foo} %] is [% GET ${foo} %] is [% GET bar %].
-
- This makes more sense if you look at the common example of accesing
- an entry from a hash array using the value of an variable as the
- key (e.g. $hash->{ $key }). In version 1, the leading '$' on
- variables is ignored, meaning that the following are NOT identical.
-
- # version 1
- [% hash.$key %] # ERROR - '$' ignored => [% hash.key %]
- [% hash.${key} %] # OK - '$key' is interpolated first
-
- It gets more confusing if you excercise your right to add optional
- leading '$'s in other places (which is one reason why I've always
- suggested against their use).
-
- # version 1 - same as above
- [% $hash.$key %]
- [% $hash.${key} %]
-
- In particular, that last example should demonstrate the
- inconsistency. Unlike interpolated text, '$...' and '${...}' are
- not treated the same and '$hash' is not interpolate while '${key}'
- is. The only consistent solution I can see to this is to make
- both '$xxx' and '${xxx}' indicate interpolation in all cases, so
- that's what I've done. In version 2, the syntax becomes a lot
- clearer and aligns more closely to a markup language than a
- programming language. I think this is a Good Thing, but let me
- know what you think...
-
- Here's the Version 2 summary, assuming INTERPOLATE is set.
-
- # version 2
- my name is $name
- my name is $user.name
- my name is ${user.name}
-
-
- [% GET name %] [% name %]
- [% GET user.name %] [% user.name %]
- [% GET people.fred %] [% people.fred %]
- [% GET people.$name %] [% people.$name %]
- [% GET people.${user.name} %] [% people.${user.name} %]
-
- [% INCLUDE header
- title = "Home Page for $name"
- %]
- [% INCLUDE header
- title = "Home Page for $user.name"
- %]
- [% INCLUDE header
- title = "Home Page for ${user.name}"
- %]
-
- If you find it slightly confusing that the dollar should be
- missing inside directives, then you may find it helps to think
- of the '[% ... %]' as an even more advanced form of '${ ... }'.
- e.g.
-
- $foo ==> ${foo} ==> [% foo %]
-
- Personally, I think this solution works well and although it restricts
- your freedom in using '$'s wherever you like, it really does help to
- make things clearer. Let me know what you think. For now, there's
- a VERSION => 1 flag you can set to revert to the old behaviour.
-
-In addition to those changes, the main new features of the language are:
-
-
-There are a number of other significant changes in the architecture
-and implementation.
+ whitespace from the output of templates and BLOCKs.
Other Enhancements and Internal Features
----------------------------------------
@@ -578,14 +447,152 @@ Other Enhancements and Internal Features
returned according to the OUTPUT options specified for the module
and/or any output option passed explicitly to the process() method.
+Plugins and Filters
+-------------------
+
+* Added the 'upper' and 'lower' filters for case folding text.
+
+* Added the Date plugin.
+
+Tools and Tests
+---------------
-----------------------------------------------------------------------
+* Added the --define var=val option to ttree.
-* USERDIR and USERBLOCK are currently not supported (and may never be,
- given that they're experimental features of TT1 anyway).
+* Added '-- use name --' to Template::Test to switch between multiple
+ Template objects specified as a list reference as the second arg
+ to test_expect()
-* Changed default TAGS to
- to [% %] and changed names of some others
+* Totally updated the test suite.
+
+
+Gotchas
+-------
+
+Things that have changed between version 1 and 2 that might catch you
+out.
+
+* Bare CATCH blocks are no longer permitted and must be explicitly
+ scoped with a matching TRY. In most cases, this simply means adding
+ a [% TRY %] to the start of any templates that define CATCH blocks,
+ and ensuring that the CATCH blocks are moved to the end of the file
+ (or relevant place).
+
+ # version 1 - no longer supported
+ blah blah blah...some error occurs
+
+ [% CATCH some_kind_of_error %]
+ handler template...
+ [% END %]
+
+ # version 2
+ [% TRY %]
+ blah blah blah...some error occurs...
+
+ [% CATCH some_kind_of_error %]
+ handler template...
+ [% END %]
+
+ Also be aware that this may change the expected output in case of
+ errors. By default, all output in the TRY block up to the point of
+ error will be returned, with the relevant catch block, and then and
+ further template output appended. You can use [% CLEAR %] within a
+ CATCH block to clear the output from the TRY block, if you prefer.
+ TRY blocks can be nested indefinately.
+
+* The ERROR directive is no longer supported. It was very ill-defined
+ anyway and serves no purpose that can't be acheived by defining
+ custom filters, error handlers bound to template variables, or
+ whatever. I haven't implemented any special error or logging
+ facilities, other than the general purpose exception handling, but
+ welcome any thoughts on what or if anything else is needed.
+
+* The ERROR option is also different. It could previously be used
+ to specify an error handling sub-routine, but is no longer required
+ (see previous point). The ERROR option in version 2 is used to
+ define a map of error types to template names for automatic
+ redirection for error handling.
+
+* The current exception caught in a catch block is now aliased to the
+ variable 'error' rather than 'e'. This is much more logical, IMHO,
+ and was only prevented previously by 'error' being a reserved word.
+ Note that 'e' is still defined, in addition to 'error'. This may be
+ deprecated at some point in the future.
+
+* The use of a leading '$' on variables is no longer optional, and
+ should only be used to explicitly to indicate interpolatation of a
+ variable name. Most of the time you *don't* want to do this, so
+ leave the '$' off. This represent a slight shift away from the
+ (optional) Perlness of the language, but I think it's a necessary
+ step to improve the clarity and consistency of the language.
+
+ As previously discussed on the mailing list, in interpolated text
+ (i.e. a "double quoted" string or regular template text with
+ INTERPOLATE set), both '$foo' or '${foo}' are interpolated as the
+ value of the variable 'foo'. This is good because it is a de-facto
+ standard, consistent with Perl, shell, etc. But inside a directive,
+ [% $foo %] and [% ${foo} %] mean different things, the first being
+ equivalent to [% foo %] or [% GET foo %] (the leading '$' is
+ ignored) but the second actually fetching a variable whose name is
+ stored in the variable 'foo'. In other words, '${foo}' interpolates
+ to the value of foo ('bar', say) and then this is used as the
+ parameter to GET (which itself is optional). Thus, in this case, [%
+ ${foo} %] is [% GET ${foo} %] is [% GET bar %].
+
+ This makes more sense if you look at the common example of
+ accesing an entry from a hash array using the value of an variable
+ as the key (e.g. $hash->{ $key }). In version 1, the leading '$' on
+ variables is ignored, meaning that the following are NOT identical.
+
+ # version 1
+ [% hash.$key %] # ERROR - '$' ignored => [% hash.key %]
+ [% hash.${key} %] # OK - '$key' is interpolated first
+
+ It gets more confusing if you excercise your right to add optional
+ leading '$'s in other places (which is one reason why I've always
+ suggested against their use).
+
+ # version 1 - same as above
+ [% $hash.$key %]
+ [% $hash.${key} %]
+
+ In particular, that last example should demonstrate the
+ inconsistency. Unlike interpolated text, '$...' and '${...}' are
+ not treated the same and '$hash' is not interpolate while '${key}'
+ is. The only consistent solution I can see to this is to make both
+ '$xxx' and '${xxx}' indicate interpolation in all cases, so that's
+ what I've done. In version 2, the syntax becomes a lot clearer and
+ aligns more closely to a markup language than a programming
+ language. I think this is a Good Thing, but let me know what you
+ think...
+
+ Here's the Version 2 summary, assuming INTERPOLATE is set.
+
+ # version 2
+ my name is $name
+ my name is $user.name
+ my name is ${user.name}
+
+
+ [% GET name %] [% name %]
+ [% GET user.name %] [% user.name %]
+ [% GET people.fred %] [% people.fred %]
+ [% GET people.$name %] [% people.$name %]
+ [% GET people.${user.name} %] [% people.${user.name} %]
+
+ [% INCLUDE header
+ title = "Home Page for $name"
+ %]
+ [% INCLUDE header
+ title = "Home Page for $user.name"
+ %]
+ [% INCLUDE header
+ title = "Home Page for ${user.name}"
+ %]
+
+* Changed default TAG_STYLE to only recognise [% ... %] and not the MetaText
+ compatability %% ... %% style. Set TAG_STYLE => 'template1' to accept both,
+ or 'metatext' for just %% ... %%
* Changed how error/return values should be returned from user code.
All errors should be thrown via one of the following:
@@ -595,47 +602,10 @@ Other Enhancements and Internal Features
$context->throw($msg);
$context->throw($type, $info);
$context->throw($exception);
-
-* Added '-- use name --' to Template::Test to switch between multiple
- Template objects specified as a list reference as the second arg
- to test_expect()
+
+* USERDIR and USERBLOCK are not supported (they were experimental and
+ undocumented, anyway)
* $Template::Directive::While::MAXITER is now
- $Template::Directive::WHILE_MAX
-
-changes from alpha to beta
---------------------------
-
-* fixed bug in Context filter() provider method which wasn't caching
- filters with args.
-
-
-The Template Toolkit has been re-written for version 2 and includes
-many enhancements and new features. It remains backwardly compatible
-with version 1.* in all but a few minor areas where syntax or
-structure have been changed for the sake of clarity and/or progress.
-By and large it is a superset of version 1, being better, stronger and
-significantly faster without sacrificing existing functionality.
-
-The most important internal change is that all templates are now
-compiled to Perl code for greater speed, efficiency and portability.
-Doug Steinwand was instrumental in this and deserves much credit for
-providing the code and ideas around which the new parser was built.
-In trivial benchmarks, you can expect to see templates being processed
-roughly twice as fast under version 2 as version 1, without losing any
-features or functionality. Doug's original version was significantly
-faster still, although it acheived this by bypassing the stash for
-variable access and consequently losing some of the magical variable
-binding. For the initial release of version 2.00, I wanted to
-maintain backwards compatability with version 1.00 as much as
-possible, so I had to code the stash back in, and accept that it
-wouldn't be as fast as it could have been. But hey, it's still
-*twice* as fast.
-
-Better still is that the new, improved architecture makes it much
-easier to install an alternate parser grammar to generate Perl code
-from the template source. Once compiled to Perl, all templates can
-run alongside each other, regardless of how they were parsed and
-constructed. Thus we could have a alternate grammar based on Doug's
-code which could be switched in when you need absolute speed and
-don't mind if some things work a little different.
+ $Template::Directive::WHILE_MAX and may change again.
+
View
28 MANIFEST
@@ -2,7 +2,6 @@ Changes
MANIFEST
Makefile.PL
README
-RELEASE
TODO
bin/README
bin/tpage
@@ -11,21 +10,33 @@ docs/lib/author
docs/lib/copyright
docs/lib/exceptions
docs/lib/footer
+docs/lib/option/absolute
docs/lib/option/blocks
+docs/lib/option/cache
docs/lib/option/case
docs/lib/option/chomp
+docs/lib/option/compile
+docs/lib/option/delim
docs/lib/option/error
docs/lib/option/evalperl
docs/lib/option/filters
docs/lib/option/grammar
+docs/lib/option/include
docs/lib/option/interp
+docs/lib/option/loadfilt
+docs/lib/option/loadperl
+docs/lib/option/loadplug
+docs/lib/option/loadtmpl
+docs/lib/option/parser
+docs/lib/option/plugbase
docs/lib/option/plugins
docs/lib/option/preproc
+docs/lib/option/relative
docs/lib/option/reset
docs/lib/option/stash
docs/lib/option/tag
docs/lib/option/tagstyle
-docs/lib/option/templates
+docs/lib/option/tolerant
docs/lib/option/trim
docs/lib/option/variables
docs/lib/option/version
@@ -51,7 +62,6 @@ docs/pod/Service.pod
docs/pod/Stash.pod
docs/pod/Template.pod
docs/pod/Test.pod
-docs/pod/Utils.pod
docs/src/Base.pod
docs/src/Config.pod
docs/src/Constants.pod
@@ -68,7 +78,6 @@ docs/src/Service.pod
docs/src/Stash.pod
docs/src/Template.pod
docs/src/Test.pod
-docs/src/Utils.pod
docs/ttree.cfg
lib/Template.pm
lib/Template/Base.pm
@@ -98,16 +107,17 @@ lib/Template/README
lib/Template/Service.pm
lib/Template/Stash.pm
lib/Template/Test.pm
-lib/Template/Utils.pm
parser/Grammar.pm.skel
parser/Parser.yp
parser/README
parser/yc
t/README
+t/args.t
t/base.t
t/binop.t
t/block.t
t/capture.t
+t/case.t
t/cgi.t
t/compile1.t
t/compile2.t
@@ -130,15 +140,18 @@ t/list.t
t/object.t
t/output.t
t/parser.t
+t/plugins.t
t/provider.t
t/rss.t
t/service.t
t/skel.t
t/stop.t
+t/switch.t
t/table.t
t/tags.t
t/template.t
t/test/lib/README
+t/test/lib/badrawperl
t/test/lib/barfed
t/test/lib/blockdef
t/test/lib/config
@@ -150,6 +163,9 @@ t/test/lib/menu
t/test/lib/trimme
t/test/lib/udata1
t/test/lib/udata2
+t/test/plugin/MyPlugs/Bar.pm
+t/test/plugin/MyPlugs/Baz.pm
+t/test/plugin/MyPlugs/Foo.pm
t/test/src/README
t/test/src/bar/baz
t/test/src/bar/baz.txt
@@ -162,7 +178,9 @@ t/test/src/golf
t/test/tmp/README
t/test/xml/example.rdf
t/test/xml/testfile.xml
+t/text.t
t/try.t
t/url.t
t/vars.t
t/varsv1.t
+t/while.t
View
43 Makefile.PL
@@ -1,10 +1,49 @@
use ExtUtils::MakeMaker; # -*-perl-*-
+select STDERR;
+$| = 1;
+select STDOUT;
+
+# beep!
+print STDERR "\a";
+
+eval "use Template";
+unless ($@) {
+ warn(<<EOF);
+IMPORTANT NOTE:
+
+ Version $Template::VERSION of the Template Toolkit detected.
+
+ This installation will most likely trash that version and render
+ it totally useless. You probably don't want that to happen right
+ now, so please ensure that you install this beta release into a
+ separate directory. These co-existance problems will be solved
+ for version 2.00 proper.
+
+ If you are suitably wise and have issued the appropriate command
+ line incantation to ensure that this bundle is installed to a safe
+ location, e.g.
+
+ perl Makefile.PL LIB=/some/other/place
+
+ then we apologise. This script is too dumb to recognise the fact
+ and must issue this tedious warning regardless.
+
+EOF
+}
+
+warn(<<EOF);
+ This is beta code. Please read the README and Changes files for
+ details of the current status.
+
+EOF
+
+
+
my $man3pods = {
map { ("docs/pod/$_.pod" => "\$(INST_MAN3DIR)/Template::$_.\$(MAN3EXT)") }
qw( Base Config Constants Context Document Exception Filters
- Iterator Parser Plugin Plugins Provider Service Stash
- Test Utils )
+ Iterator Parser Plugin Plugins Provider Service Stash Test )
};
$man3pods->{'docs/pod/Template.pod'} = '$(INST_MAN3DIR)/Template.$(MAN3EXT)';
View
244 README
@@ -1,179 +1,69 @@
-This is an alpha release of version 2 of the Perl Template Toolkit.
-It is still in experimental form and should most definately not be
-used in production systems unless you really enjoy living dangerously.
-
-Don't even install it. No, I'm serious. It will overwrite your
-existing version 1.xx Template Toolkit modules and really spoil your
-day. There's no Makefile.PL anyway, just in case you felt tempted to
-install it without reading this README first.
-
-So, with that warning aside, down to business. This contains a current
-snapshot of my workings on version 2 of the Template Toolkit. The
-template language itself remains fairly constant, with a few minor
-changes, a couple of new features, and the cleaning up of a few loose
-ends and inconsistencies. The majority of the work has gone on improving
-the architecture and internal workings of the toolkit. Most significant
-is the fact that templates are now compiled to Perl code and evaluated
-as Perl sub-routines. This has 2 main advantages. The first is that
-the execution time is dramatically reduced. In a persistant server
-environment such as a web server, this is a major win. The second
-benefit is that once compiled, the Perl code can be written to a file
-so that it can be re-loaded at some later date in considerably less
-time. As an added bonus, this makes it much easier to integrate
-external modules, template components, and so on.
-
-only one significant
-change that might affect you. Up until now, the leading '$' on a variable
-has been optional and has no effect. From version 2 onwards, variables
-should NOT be prefixed with a '$'. More on that later, but for now rest
-assured that there's a VERSION compatability option which reverts this
-to the original behaviour. Another change is the behaviour of CATCH
-blocks, which up until now has always been a little weird. This has now
-been formalised into a properly structure TRY ... CATCH block. There's
-also a new SWITCH ... CASE statement
- The '$' is now used consistently to
-indicate that a variable name should interpolated, for example, when
-accessing a hash key by a symbolic name:
-
- hash.$key
-
-
-#------------------------------------------------------------------------
-Template::Document
-
- This defines an object class whose instances represent compiled template
- documents. The Template::Parser module creates Template::Document
- instances to encapsulate templates as it compiles them. The template
- content itself should be passed to the constructor as a reference to
- a sub-routine. The Template::Document object simply stores this
- reference internally and then calls it when its process($context)
- method is invoked. The sub-routine should expect a Template::Context
- reference as its only parameter and should return its output or raise
- an error via "die Template::Exception->new($type, $info)".
-
- my $doc = Template::Document->new(
- sub {
- my $context = shift;
- my $stash = $context->stash();
- my $foo = $stash->get('foo') || 'undefined';
- return "The value of foo is $foo";
- }
- );
-
- print $doc->process($context);
-
- Additional parameters passed to the constructor are treated as named
- metadata items. These are also stored internally and available via
- an AUTOLOAD method.
-
- my $doc = Template::Document->new(\&mytemplate,
- author => 'Andy Wardley',
- version => 3.14 );
-
- print "version ", $doc->version, " by ", $doc->author, "\n";
-
-
- Metadata items are accessible in templates via the 'template'
- variable which contains a reference to the parent Template::Document
- object, where 'parent' defines the outermost template being
- processed.
- [% template.author %]
-
- The BLOCKS parameter may be provided and should contain a reference to
- a hash array of other Template::Document objects, representing any
- additional BLOCK definitions within the template source file.
-
- my $hdr = Template::Document->new(\&myheader);
- my $ftr = Template::Document->new(\&myfooter);
-
- my $doc = Template::Document->new(\&mytemplate,
- BLOCKS => {
- header => $hdr,
- footer => $ftr,
- },
- author => 'Andy Wardley',
- version => 3.14 );
-
- Template::Document objects are usually created by the Template::Parser
- but can be manually instantiated, or indeed sub-classed to provide
- custom template components.
-
-
-#------------------------------------------------------------------------
-Template::Document
-
- This defines an object class whose instances represent compiled template
- documents. A "compiled template document" is a reference to an anonymous
- sub-routine.
-
- new(\&template, BLOCKS => \%blockdefs, metavar => $val, ...)
- process($context)
- blocks()
-
-Template::Context
-
- Runtime object:
-
- new(\%config)
- stash() # return Template::Stash reference
- template($name) # fetches compiled template by name
- plugin($name, \@args) # fetches plugin by name (USE)
- filter($name, \@args, $alias) # fetches filter by name (FILTER)
- process($template, \%params) # process template in context (PROCESS)
- include($template, \%params) # ditto in localised context (INCLUDE)
- throw($type, $info) # raise exception via die() (THROW)
- catch($error) # sanitise errors caught
- localise() # localise the context
- delocalise() # de-localise the context
-
-
-Template::Stash
-
- Variable storage:
-
- new(\%predefs)
- get('foo') # => [% foo %]
- get(['foo', \@args]) # => [% foo(args) %]
- get(['foo', 0, 'bar', 0]) # => [% foo.bar %]
- get(['foo', \@args1, 'bar', \@args2])
- # => [% foo(args1).bar(args2)... %]
-
- set('foo', 5) # => [% foo = 5 %]
- set('foo', 5, 1) # => [% DEFAULT foo = 5 %]
-
- set(['foo', 0, 'bar', 0], 5) # => [% foo.bar = 5 %]
- set(['foo', 0, 'bar', 0], 5, 1) # => [% DEFAULT foo.bar = 5 %]
-
-
-Template::Provider
-
- Provides and caches compiled templates.
-
- fetch($name) # return Template::Document object
- store($name, $template) # store Template::Document object
-
-
-Template::Parser
-
- Parses templates and compiles them down to Perl code. This is then
- evaluated to define an anonymous sub-routine which, when invoked,
- will generate the processed template output. The parser instantiates
- Template::Document objects to encapsulate the compiled template.
-
- parse($text)
-
-
-Template::Filters
-
- General provider for system-defined FILTER operations.
-
- fetch($name, \@args)
-
-
-Template::Plugins
-
- General provider for system-defined plugins operations.
-
- fetch($name, \@args, $context)
+ Template Toolkit Version 2.00 Beta Release 1
+
+ 10-July-2000
+
+
+ ** IMPORTANT WARNING **
+
+ If you install these modules you will totally screw up your existing
+ version 1.* installation. I do plan to make V1 and V2 work harmoniously
+ with each other but that time is not yet now. Install it to an entirely
+ different location or don't "make install" it at all. You have been
+ warned (and will be again).
+
+ ** END OF IMPORTANT WARNING **
+
+Hello World
+-----------
+
+This is the first beta release of version 2 of the Perl Template
+Toolkit. It is fully-featured, reliable and reasonably bug-free.
+Most of the modules are documented fully, or near-fully, but the main
+Template.pm documentation and some other bits and pieces still need
+some work. The API is almost frozen. Some of the option names may
+still change and the filters interface will almost certainly get
+improved a little before the real v2. Other than that, this is pretty
+much what version 2 will look like. If you think there's anything
+missing, or that which could be done better then now is the time to
+speak or forever hold your peace (or at least until version 2.01)
+
+Beware
+------
+
+Most, if not all of the modules are lacking specific cleanup code and
+many of them need it. In particular, the Template::Provider builds a
+linked list to cache compiled templates and the circular refs prevent
+it from being cleaned up automatically. It's not a major problem. I
+just need to write some fairly trivial code to clean it up here, and
+in a couple of other places (e.g. filters cache). Until then, it will
+leak memory like a sieve, so don't use it in a persistant server
+unless you take other precautions. Don't worry - it'll get fixed in
+the mix.
+
+Be Warned
+---------
+
+If you missed the IMPORTANT WARNING earlier, then let me just remind
+you not to install it unless you know what you're doing. There's a
+Makefile.PL now, but we still don't trust you not to do something
+silly, so it will issue an annoying warning when you run it. The
+version 2 modules are very different from the version 1 modules but
+overlap in name. I'm planning to release version 1.08 as a final
+swansong for the version 1.* dynasty. This will relocate all version
+1 modules to Template::v1::* so that they can continue to be used
+without getting in version 2+'s way.
+
+Please Read
+-----------
+
+The Changes file contains most of the interesting detail about the
+major differences between version 1 and 2, including new features and
+so on. Until the documentation is complete, this is the best source
+of information, even though it is itsefl incomplete or sketchy in
+places. The TODO file is a total mess and includes TODONE stuff that
+should be in the Changes file. It'll get cleaned up RSN.
+
+Enjoy
+A
View
59 RELEASE
@@ -1,59 +0,0 @@
-docs, dates, email, debug, etc.
-
-Core modules
-------------
-
-Template::Base all done - fully tested (t/base.t)
-Template::Config all done - fully tested (t/config.t)
-Template::Constants all done - no testing required
-Template::Context code OK - needs more testing via context.t,
- block.t, and so on. Needs better _dump() method.
-Template::Directive ** needs work (integrate with Parser.yp?)
-Template::Document all done - fully tested (t/document.t)
-Template::Exception all done - fully tested (t/exception.t)
-Template::Filters all done - fully tested (t/filter.t) (note redirect)
-Template::Iterator all done - fully tested
-Template::Parser code OK - needs testing
-Template::Plugins code OK - needs testing
-Template::Provider all done - fully tested
-
-Template::Plugin::*
--------
-CGI Broken by UNIVERSAL::isa problem in Stash
-Datafile OK + tested
-Format OK + tested
-Iterator OK + tested
-Table OK + tested
-URL OK + tested
-
-
-CHECK: use lib qw( ./lib, ../lib )
- no need for ntests
- email, copyright, dates
-
-t/base.t OK, but could do with more tests?
-t/binop.t OK
-t/block.t OK
-t/capture.t OK
-t/cgi.t OK
-t/compile1.t OK
-t/compile2.t OK
-t/compile3.t OK
-t/config.t OK
-t/document.t OK
-t/exception.t OK
-t/filter.t OK
-t/datafile.t OK
-t/iterator.t OK
-t/table.t OK
-t/url.t OK
-t/format.t OK
-
-
-TODO
-
-fixup t/block(t).t
-fixup t/service.t
-test parser line nos
-
-test exception via THROW
View
97 TODO
@@ -1,74 +1,59 @@
-
-Pending
--------
-
-* Template -> Service -> Context -> Stash
- -> Provider -> Parser -> Grammar
- -> Document
- -> Directive
- -> Plugins -> Plugin -> Plugin::*
- -> Filters
-
- + Base, Config, Constants, Exception, Iterator, Test, Utils
+===========================================
+It's a real mess in here. Don't even look.
+===========================================
-Misc
+TODO
----
-* move v1 Template::* to Template::v1::*
-* Add :preload use option to Template.pm
+* move v1 Template::* to Template::v1::*. Add 'version1' load flag
+ as an EXPORT_FAIL to Tempate.pm to load v1.
-* encorporate Service.pm into Context.pm as service() method? Not yet
- sure if this is a good idea or not.
+* Add :preload use option to Template.pm to preload all modules. Or should
+ it be :noload and have preload by default?
-* No \refs.
+* Note that \refs are not supported. I don't know if they ever should
+ be, but I think that some of the problems for which refs were conceived
+ are still valid.
-* faster parser back end which bypasses the stash, based on Doug's code.
+* Alternate parser back end which bypasses the stash, based on Doug's code.
-* Fix Plugin.pm - it's still basically v1 code and much can be discarded
+* A 'FOR', like 'FOREACH' but without using an iterator. You wouldn't get
+ the 'loop' reference to test 'first', 'last', etc., against, but it would
+ be faster for those cases when you didn't need that.
* Memory leaks (there's something creating circular references and it's
- probably glaringly obvious but I haven't bothered to look yet)
+ probably glaringly obvious but I haven't bothered to look yet) (time
+ passes... I've bothered to look now - it looks like the Template::Provider
+ but I haven't bothered to fix it yet)
-* Change ttree to have knowledge of new config options. Add --define option
- to define a template variable.
+* Change ttree to have knowledge of new config options.
* Improve tpage to do the same (i.e. have --define, at least)
* A COMPILE_DIR option to compliment COMPILE_EXT, specifying an alternate
- directory in which to store compiled template documents.
-
-* Modules are mostly autoloaded. Need PRELOAD option to preload all relevant
- modules? (e.g. for mod_perl)
-
-* a FOR, like FOREACH but without using an iterator?
+ directory in which to store compiled template documents.
* Change filter factory interface to accept $context as first parameter.
Dynamic dynamic filters can't grab context reference and some of them
need it.
-* add 'perl' filter - needs context access noted above to test EVAL_PERL
+* Add 'perl' filter, but can't do that until I fix the above.
-* filters and plugins cache may bloat. Perhaps reset() should accept
+* Filters and plugins cache may bloat. Perhaps reset() should accept
flags to clear BLOCKS, PLUGINS, FILTERS, etc.
* Do something (i.e. mail Lincoln) about the CGI special case in
Template::Stash to work around the problem of CGI objects disclaiming
membership of the UNVIERSAL class after the first method call.
-* copy over new plugins and filters from v1.07
-
-* Change docs/examples to uniformly name the template variable hash as
- '$replace'.
-
-* note that no recursion checking is performed for BLOCKs, only
- Template::Document instances
+* Note that no recursion checking is performed for BLOCKs, only
+ Template::Document instances. Should be documented.
-* options for provider retrievals such as DONT_USE_CACHE, DONT_CACHE,
- DONT_COMPILE (e.g. for [% INSERT file %] directive), or should there
- be public interfaces for load(), compile(), etc.?
-
-* move Template::Utils::output somewhere better (Template.pm?) and get rid
- of Template::Utils
+* There's still no easy way to [% INSERT file %] because there's no way
+ to tell the provider not to compile a file. We could keep file text
+ hanging around (nah) or pass options for provider retrievals such as
+ DONT_USE_CACHE, DONT_CACHE, DONT_COMPILE. Or should there be public
+ interfaces for load(), compile(), etc.? Not sure.
* should output redirection be handled by the service rather than
Template.pm?
@@ -76,14 +61,13 @@ Misc
* change all hardcoded object isa tests to use $Template::Config:XXXXX
e.g. if (UNIVERSAL::isa($foo, $Template::Config::CONTEXT))
-
* check [% INCLUDE $template %] works where $template is a Template::Document
-* merge Directive into Parse.yp via template?
+* merge Directive into Parse.yp via template process?
--- DONE --
+-- TODONE --
* Template::Context include()/process() should work with raw CODE refs.
@@ -133,4 +117,21 @@ Misc
* fixed TRIM option to work with all BLOCKs and templates. Moved TRIMing
operation into context process() and include() methods. Also changed
service to call $context->process($template) rather than call the sub/
- doc itself, thus ensuring that the output can get TRIMmed.
+ doc itself, thus ensuring that the output can get TRIMmed.
+
+* Fix Plugin.pm - it's still basically v1 code and much can be discarded
+
+* Added --define option to ttree.
+
+* copy over new plugins and filters from v1.07
+
+* Move Template::Utils::output somewhere better (Template.pm?) and get rid
+ of Template::Utils
+
+* fixed bug in Context filter() provider method which wasn't caching
+ filters with args.
+
+* [% CASE DEFAULT %] is now an alias for [% CASE %] (the default case),
+ in consistency with [% CATCH DEFAULT %] / [% CATCH %]
+
+
View
535 lib/Template.pm
@@ -33,12 +33,13 @@ use Template::Base;
use Template::Config;
use Template::Provider;
use Template::Service;
-use Template::Utils;
-#use Template::Parser; # autoloaded on demand
+use File::Basename;
+use File::Path;
+# use Template::Parser; # autoloaded on demand
## This is the main version number for the Template Toolkit.
## It is extracted by ExtUtils::MakeMaker and inserted in various places.
-$VERSION = '1.52';
+$VERSION = '2.00-beta1';
$ERROR = '';
$DEBUG = 0;
@@ -66,7 +67,7 @@ sub process {
# send processed template to output stream, checking for error
return ($self->error($error))
- if ($error = &Template::Utils::output($outstream, $output));
+ if ($error = &_output($outstream, $output));
return 1;
}
@@ -106,6 +107,9 @@ sub context {
# -- PRIVATE METHODS --
#========================================================================
+#------------------------------------------------------------------------
+# _init(\%config)
+#------------------------------------------------------------------------
sub _init {
my ($self, $config) = @_;
@@ -120,485 +124,58 @@ sub _init {
}
+#------------------------------------------------------------------------
+# _output($where, $text)
+#------------------------------------------------------------------------
-1;
-
-__END__
-
-=head1 NAME
-
-Template - front-end module for the Template Toolkit
-
-=head1 SYNOPSIS
-
- use Template;
-
- $tt = Template->new(\%config)
- || die Template->error(), "\n";
-
- $tt->process($template, \%vars)
- || die $tt->error(), "\n";
-
-=head1 DESCRIPTION
-
-The Template Toolkit is a collection of modules which implement a
-fast, flexible and powerful template processing system. The modules
-that comprise the toolkit can be customised and interconnected in
-different ways to create bespoke template processing engines for
-different application areas or environments.
-
-The Template.pm module is a front-end to the Template Toolkit,
-providing access to the full range of functionality through a single
-module with a simple interface. It loads the other modules as
-required and instantiates a default set of objects to handle
-subsequent template processing requests. Configuration parameters may
-be passed to the Template.pm constructor, new(), which are then used
-to configure the individual objects.
-
-Example:
-
- use Template;
-
- my $tt = Template->new({
- INCLUDE_PATH => '/usr/local/templates',
- EVAL_PERL => 1,
- }) || die Template->error(), "\n";
-
- my $vars = {
- foo => 'The Foo Value',
- bar => 'The Bar Value',
- };
-
- $tt->process('welcome.html', $vars)
- || die $tt->error(), "\n";
-
-
-=head1 METHODS
-
-=head2 new(\%config)
-
-The new() constructor method (implemented by the Template::Base base
-class) instantiates a new Template object. A reference to a hash
-array of configuration items may be passed as a parameter.
-
- my $tt = Template->new({
- INCLUDE_PATH => '/usr/local/templates',
- EVAL_PERL => 1,
- }) || die Template->error(), "\n";
-
-A reference to a new Template object is returned, or undef on error. In
-the latter case, the error message can be retrieved by calling error()
-as a class method (e.g. C<Template-E<gt>error()>) or by examing the $ERROR
-package variable directly (e.g. C<$Template::ERROR>).
-
- my $tt = Template->new(\%config)
- || die Template->error(), "\n";
-
- my $tt = Template->new(\%config)
- || die $Template::ERROR, "\n";
-
-For convenience, configuration items may also be specified as a list
-of items instead of a hash array reference. These are automatically
-folded into a hash array by the constructor.
-
- my $tt = Template->new(INCLUDE_PATH => '/tmp', POST_CHOMP => 1)
- || die Template->error(), "\n";
-
-
-=head2 process($template, \%vars, $output)
-
-The process() method is called to process a template. The first
-parameter indicates the template by filename (relative to
-INCLUDE_PATH, if defined), or by reference to a text string containing
-the template text, or to a file handle (e.g. IO::Handle or sub-class)
-or GLOB (e.g. \*STDIN), from which the template can be read.
-
- $text = "[% INCLUDE header %]\nHello world!\n[% INCLUDE footer %]";
-
- $tt->process('welcome.tt2')
- || die $tt->error(), "\n";
-
- $tt->process(\$text)
- || die $tt->error(), "\n";
-
- $tt->process(\*DATA)
- || die $tt->error(), "\n";
-
- __END__
- [% INCLUDE header %]
- This is a template defined in the __END__ section which is
- accessible via the DATA "file handle".
- [% INCLUDE footer %]
-
-A reference to a hash array may be passed as the second parameter,
-containing definitions of template variables. This may contain values
-of virtually any Perl type, including simple values, list and hash
-references, sub-routines and objects. The Template Toolkit will
-automatically apply the correct procedure to accesing these values as
-they are used in the template (e.g. index into a hash or array, call
-code or object methods, provide virtual methods such as 'first', 'last',
-etc.)
-
-Example:
-
- my $vars = {
- foo => 'The Foo Value',
- bar => [ 2, 3, 5, 7, 11, 13 ],
- baz => { id => 314, name => 'Mr. Baz' },
- wiz => sub { return "You called the 'wiz' sub-routine!" },
- woz => MyObject->new(),
- };
-
- $tt->process('welcome.tt2', $vars)
- || die $tt->error(), "\n";
-
-F<welcome.tt2>:
-
- [% foo %]
- [% bar.first %] - [% bar.last %], including [% bar.3 %]
- [% bar.size %] items: [% bar.join(', ') %]
- [% baz.id %]: [% baz.name %]
- [% wiz %]
- [% woz.method(123) %]
-
-Output:
-
- The Foo Value
- 2 - 13, including 7
- 6 items: 2, 3, 5, 7, 11, 13
- 314: Mr. Baz
- You called the 'wiz' sub-routine!
- # output of calling $vars->{'woz'}->method(123)
-
-By default, the processed template output is printed to STDOUT. The
-process() method then returns 1 to indicate success. A third
-parameter may be passed to the process() method to specify a different
-output location. This value may be one of; a plain string indicating
-a filename which will be opened (relative to OUTPUT_PATH, if defined)
-and the output written to; a file GLOB opened ready for output; a
-reference to a scalar (e.g. a text string) to which output/error is
-appended; a reference to a sub-routine which is called, passing the
-output as a parameter; or any object reference which implements a
-'print' method (e.g. IO::Handle, Apache::Request, etc.) which will
-also be called, passing the generated output.
-
-Examples:
-
- $tt->process('welcome.tt2', $vars, 'welcome.html')
- || die $tt->error(), "\n";
-
- $tt->process('welcome.tt2', $vars,
- sub { my $output = shift; print $output })
- || die $tt->error(), "\n";
-
- my $output = '';
-
- $tt->process('welcome.tt2', $vars, \$output)
- || die $tt->error(), "\n";
+sub _output {
+ my ($where, $text) = @_;
+ my $reftype;
+ my $error = 0;
- print "output: $output\n";
-
-In an Apache/mod_perl handler:
-
- sub handler {
- my $r = shift;
- my $file = $r->path_info();
-
- my $tt = Template->new();
- my $vars = { ... }
-
- # direct output to Apache::Request via $r->print($output)
- $tt->process($file, $vars, $r) || do {
- $r->log_reason($tt->error());
- return SERVER_ERROR;
- };
-
- return OK;
+ # call a CODE referenc
+ if (($reftype = ref($where)) eq 'CODE') {
+ &$where($text);
+ }
+ # print to a glob (such as \*STDOUT)
+ elsif ($reftype eq 'GLOB') {
+ print $where $text;
+ }
+ # append output to a SCALAR ref
+ elsif ($reftype eq 'SCALAR') {
+ $$where .= $text;
+ }
+ # call the print() method on an object that implements the method
+ # (e.g. IO::Handle, Apache::Request, etc)
+ elsif (UNIVERSAL::can($where, 'print')) {
+ $where->print($text);
+ }
+ # a simple string is taken as a filename
+ elsif (! $reftype) {
+ local *FP;
+ # make destination directory if it doesn't exist
+ my $dir = dirname($where);
+ eval { mkpath($dir) unless -d $dir; };
+ if ($@) {
+ # strip file name and line number from error raised by die()
+ ($error = $@) =~ s/ at \S+ line \d+\n?$//;
+ }
+ elsif (open(FP, ">$where")) {
+ print FP $text;
+ close FP;
+ }
+ else {
+ $error = "$where: $!";
+ }
+ }
+ # give up, we've done our best
+ else {
+ $error = "output_handler() cannot determine target type ($where)\n";
}
-The OUTPUT configuration item can be used to specify a default output
-location other than \*STDOUT. The OUTPUT_PATH specifies a directory
-which should be prefixed to all output locations specified as filenames.
-
- my $tt = Template->new({
- OUTPUT => sub { ... }, # default
- OUTPUT_PATH => '/tmp',
- ...
- }) || die Template->error(), "\n";
-
- # use default OUTPUT (sub is called)
- $tt->process('welcome.tt2', $vars)
- || die $tt->error(), "\n";
-
- # write file to '/tmp/welcome.html'
- $tt->process('welcome.tt2', $vars, 'welcome.html')
- || die $tt->error(), "\n";
-
-The process() method returns 1 on success or undef on error. The error
-message generated in the latter case can be retrieved by calling the
-error() method. See also L<CONFIGURATION ITEMS> which describes how
-error handling may be further customised.
-
-
-=head2 error()
-
-When called as a class method, it returns the value of the $ERROR package
-variable. Thus, the following are equivalent.
-
- my $tt = Template->new()
- || die Template->error(), "\n";
-
- my $tt = Template->new()
- || die $Template::ERROR, "\n";
-
-When called as an object method, it returns the value of the internal
-_ERROR variable, as set by an error condition in a previous call to
-process().
-
- $tt->process('welcome.tt2')
- || die $tt->error(), "\n";
-
-
-=head2 service()
-
-The Template module delegates most of the effort of processing templates
-to an underlying Template::Service object. This method returns a reference
-to that object.
-
-=head2 context()
-
-The Template::Service module uses a core Template::Context object for
-runtime processing of templates. This method returns a reference to
-that object and is equivalent to $template->service->context();
-
-=head1 CONFIGURATION ITEMS
-
-The Template module constructor, new(), accepts a hash array reference as
-a parameter, or a list of keys and values which are folded into a hash
-array. e.g.
-
- my $tt = Template->new({
- INCLUDE_PATH => '/home/abw/templates',
- POST_CHOMP => 1,
- });
-
- my $tt = Template->new(
- INCLUDE_PATH => '/home/abw/templates',
- POST_CHOMP => 1
- );
-
-This configuration hash is then passed to the other Template Toolkit
-object constructors as they are called. The following sections
-described the configuration items used by each module. See the
-individual module documentation for further details.
-
-=head2 Template
-
-The Template module provides a front-end to the Template Toolkit. It calls
-on an underlying Template::Service object to process templates and then
-directs the returned output according to the OUTPUT and OUTPUT_PATH
-values, or any specific output location provided as the third parameter
-to process().
-
-=over 4
-
-=item OUTPUT
-
-Default output location or handler. May be overridden by specifying a
-third parameter to process().
-
-=item OUTPUT_PATH
-
-The OUTPUT_PATH can be used to specify the output directory to which
-output files are written.
-
-=item SERVICE
-
-A reference to a Template::Service object, or sub-class thereof, to which
-the Template module should delegate. If unspecified, a Template::Service
-object is automatically created using the current configuration hash.
-
-=back
-
-=head2 Template::Service
-
-The Template::Service module implements a service object which
-processes templates, adding headers and footers (PRE_PROCESS and
-POST_PROCESS templates), and checking for errors. These may be
-handled automatically be specification of an ERROR hash array which
-maps error types to template files. Errors raised in a template will
-then be handled by processing the appropriate template.
-
-=over 4
-
-=item PRE_PROCESS, POST_PROCESS
-
-One or more templates to be processed before and/or after the main
-template. Multiple templates may be delimited by any sequence of
-non-word characters, or specified as a list reference,
-
- my $tt = Template->new({
- PRE_PROCESS => 'config, header', # or ['config', 'header']
- POST_PROCESS => 'footer',
- });
-
-=item ERROR
-
-Hash array of error handling templates. If an exception is thrown in
-the main process template that has a relevant handler defined in the
-ERROR hash (i.e. the hash key matches the error type), then the
-template named as the relevant hash value will be processed in place
-of the original template. A 'default' template may be provided to
-handle any otherwise uncaught error types.
-
-Any PRE_PROCESS and/or POST_PROCESS templates will be added to the
-ERROR template. The 'error' template variable is set to reference the
-Template::Exception object representing the error. Errors raised in
-PRE_PROCESS or POST_PROCESS templates, or in the ERROR templates
-themselves will be returned immediately without any further error
-handling.
-
- my $tt = Template->new({
- PRE_PROCESS => 'config, header',
- POST_PROCESS => 'footer',
- ERROR => {
- dbi => 'errors/database.tt2',
- default => 'error.tt2',
- },
- });
-
-=item BLOCKS
-
-A hash array of pre-defined template blocks that may be subsequently
-used via the INCLUDE directive. The values should contain instances
-of Template::Document objects or code references which take a reference
-to a Template::Context as a parameter and return the output generated.
-
- my $tt = Template->new({
- PRE_PROCESS => 'config',
- POST_PROCESS => 'footer',
- BLOCKS => {
- 'header' => sub { my $context = shift; return "HEADER!" },
- 'footer' => Template::Document->new(...),
- },
- });
-
-=item CONTEXT
-
-A reference to a Template::Context object, or sub-class thereof, which
-manages runtime processing of templates and implements the main
-directive features. If undefined, a Template::Context object is
-automatically created using the current configuration hash.
-
-=back
-
-=head2 Template::Context
-
-=over 4
-
-=item TEMPLATES
-
-A list of Template::Provider or derived objects which implement a
-chain of command for loading, compiling and caching templates. If
-undefined, a default Template::Provider object is created as the sole
-TEMPLATES item using the current configuration hash.
-
-=item PLUGINS
-
-Ditto for loading plugins. A default Template::Plugins object is created
-if undefined.
-
-=item FILTERS
-
-Ditto for loading filters. A default Template::Filters object is created
-if undefined.
-
-=item VARIABLES, PRE_DEFINE
-
-May be used to specify a set of variables which should be pre-defined
-each time the service is run (i.e. process() is called). These are
-passed to the Template::Stash constructor but are ignore if the STASH
-item is defined (see below). The names 'VARIABLES' and 'PRE_DEFINE'
-are synonymous and either can be used to equal effect.
-
-=item STASH
-
-A reference to a Template::Stash object, or sub-class thereof, which
-manages template variables.
-
-=back
-
-=head2 Template::Provider
-
-The Template::Provider module is used for loading, compiling and
-caching template documents. The Template.pm new() constructor creates
-a Template::Provider object unless the PROVIDERS option is set (see below).
-The following options are applicable:
-
-=over 4
-
-=item INCLUDE_PATH
-
-A string containing one or more directories, delimited by ':', from
-which templates should be loaded. Alternatively, a list reference
-of directories may be provided.
-
-=item ABSOLUTE
-
-Flag used to indicate if files specified by absolute filename (e.g.
-'/foo/bar') should be loaded.
-
-=item RELATIVE
-
-Flag used to indicate if files specified by relative filename (e.g.
-'./foo/bar') should be loaded.
-
-=item SIZE
-
-The maximum number of compiled templates that the object should cache.
-A zero value indicates that no caching should be performed. If undefined
-then all templates will be cached.
-
-=item TOLERANT
-
-If the TOLERANT flag is set then all errors will downgraded to declines.
-
-=item DELIMITER
-
-Alternative character(s) for delimiting INCLUDE_PATH (default ':').
-May be useful for operating systems that use ':' in file names.
-
-=item PARSER
-
-Used to provide a reference to a Template::Parser object, or derivative,
-which should be used to compile template documents as they are loaded.
-A default Template::Parser object is created if unspecified.
-
-=back
-
-=head1 AUTHOR
-
-Andy Wardley E<lt>abw@kfs.orgE<gt>
-
-=head1 REVISION
-
-$Revision$
-
-=head1 COPYRIGHT
-
-Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
-
-This module is free software; you can redistribute it and/or
-modify it under the same terms as Perl itself.
-
-=head1 SEE ALSO
-
-L<Template|Template>
-
-=cut
-
+ return $error;
+}
+1;
-if PROVIDERS
- foreach p in PROVIDERS
View
2  parser/Parser.yp
@@ -137,6 +137,7 @@ switch: SWITCH expr ';'
case: CASE term ';' block
case { unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
+ | CASE DEFAULT ';' block { [ $_[4] ] }
| CASE ';' block { [ $_[3] ] }
| /* NULL */ { [ undef ] }
;
@@ -297,6 +298,7 @@ expr: expr BINOP expr { "$_[1] $_[2] $_[3]" }
;
setlist: setlist assign { push(@{$_[1]}, @{$_[2]}); $_[1] }
+ | setlist COMMA
| assign
;
View
24 t/README
@@ -27,13 +27,17 @@ iterator.t Template::Iterator and Iterator plugin modules
list.t List definition and access via various methods
object.t Binding objects to template variables
output.t OUTPUT_PATH and OUTPUT options
+parser.t Template::Parser module
+plugins.t Template::Plugins provider module (incomplete)
provider.t Template::Provider module
rss.t XML::RSS plugin (Template::Plugin::XML::RSS)
service.t Template::Service module
-skelt. Skeleton test file. Copy and edit to create your own tests.
+skel.t Skeleton test file. Copy and edit to create your own tests.
stop.t STOP directive and throwing 'stop' exception
+switch.t SWITCH / CASE directives
table.t Table plugin (Template::Plugin::Table)
tags.t TAGS directive
+template.t Template front-end module
text.t Plain text blocks, ensuring all characters are reproducable
try.t TRY / THROW / CATCH / FINAL directives
url.t URL plugin (Template::Plugin::URL)
@@ -42,17 +46,9 @@ varsv1.t As above, using version 1 handling of leading '$'
while.t WHILE directive
TODO:
+ anonymous blocks
+ MACROS
+ caching options in Template::Provider
+ recursion option
+ return/stop/break
-parser.t Template::Parser module
-switch.t SWITCH / CASE directives
-plugins.t Template::Plugins provider module
-template.t Template front-end module
-
-===
-anonblock
-macro
-cache
-recursion << OPTION
-return/stop/etc
-
-format => plugins
View
19 t/config.t
@@ -165,21 +165,20 @@ $context = $factory->context(INCLUDE_PATH => 'anywhere')
|| print STDERR $factory->error(), "\n";
ok( $context );
-ok( $context->{ TEMPLATES }->[0]->{ INCLUDE_PATH }->[0] eq 'anywhere' );
+ok( $context->{ LOAD_TEMPLATES }->[0]->{ INCLUDE_PATH }->[0] eq 'anywhere' );
$context = $factory->context({
- TEMPLATES => [ $provider ],
- PLUGINS => [ $plugins ],
- FILTERS => [ $filters ],
- STASH => $stash,
+ LOAD_TEMPLATES => [ $provider ],
+ LOAD_PLUGINS => [ $plugins ],
+ LOAD_FILTERS => [ $filters ],
+ STASH => $stash,
}) || print STDERR $factory->error(), "\n";
ok( $context );
ok( $context->stash->get('foo') == 30 );
-ok( $context->{ TEMPLATES }->[0]->{ PARSER }->{ INTERPOLATE } == 1);
-ok( $context->{ PLUGINS }->[0]->{ LOAD_PERL } == 1 );
-ok( $context->{ FILTERS }->[0]->{ TOLERANT } == 1 );
-
+ok( $context->{ LOAD_TEMPLATES }->[0]->{ PARSER }->{ INTERPOLATE } == 1);
+ok( $context->{ LOAD_PLUGINS }->[0]->{ LOAD_PERL } == 1 );
+ok( $context->{ LOAD_FILTERS }->[0]->{ TOLERANT } == 1 );
#------------------------------------------------------------------------
# service
@@ -192,6 +191,6 @@ $service = $factory->service(INCLUDE_PATH => 'amsterdam')
|| print STDERR $factory->error(), "\n";
ok( $service );
-ok( $service->{ CONTEXT }->{ TEMPLATES }->[0]->{ INCLUDE_PATH }->[0]
+ok( $service->{ CONTEXT }->{ LOAD_TEMPLATES }->[0]->{ INCLUDE_PATH }->[0]
eq 'amsterdam' );
View
54 t/object.t
@@ -178,31 +178,51 @@ Tuesday
-- expect --
Wednesday Thursday Friday Saturday Sunday .
+
-- stop --
+#========================================================================
+# TODO: test _private and .private members
+#========================================================================
+
#------------------------------------------------------------------------
# test private methods do not get exposed
#------------------------------------------------------------------------
-- test --
-[% thing._private %]
+[% TRY %]
+before[% thing._private %]after
+[% CATCH %]
+ERROR: [% error.info %]
+[% END %]
-- expect --
-ERROR: invalid member name '_private'
-- test --
+[% TRY %]
[% thing._private = 10 %]
+[% CATCH %]
+ERROR: [% error.info %]
+[% END %]
-- expect --
ERROR: invalid member name '_private'
-- test --
+[% TRY %]
[% key = '_private' -%]
[% thing.${key} %]
+[% CATCH %]
+ERROR: [% error.info %]
+[% END %]
-- expect --
ERROR: invalid member name '_private'
-- test --
+[% TRY %]
[% key = '.private' -%]
[% thing.${key} = 'foo' %]
+[% CATCH %]
+ERROR: [% error.info %]
+[% END %]
-- expect --
ERROR: invalid member name '.private'
@@ -216,33 +236,3 @@ bar
Help Yourself
-#------------------------------------------------------------------------
-# test that a regular list returned is converted to a list reference
-#------------------------------------------------------------------------
-
--- test --
-[% FOREACH item = thing.items -%]
- * [% item %]
-[% END %]
-
--- expect --
- * foo
- * bar
- * baz
-
--- test --
-before
-[% thing.halt %]
-after
-
--- expect --
-before
-
--- test --
-before
-[% thing.halt = 5 %]
-after
-
--- expect --
-before
-
View
119 t/parser.t
@@ -2,7 +2,7 @@
#
# t/parser.t
#
-# Test the parser, including quoting, interpolation flags, etc.
+# Test the Template::Parser module.
#
# Written by Andy Wardley <abw@kfs.org>
#
@@ -19,30 +19,127 @@
use strict;
use lib qw( . ../lib );
use Template::Test;
+use Template::Config;
+use Template::Parser;
$^W = 1;
#$Template::Test::DEBUG = 0;
#$Template::Parser::DEBUG = 0;
-my $config = {
+my $p2 = Template::Parser->new({
+ START_TAG => '\[\*',
+ END_TAG => '\*\]',
+ PRE_CHOMP => 1,
+ V1DOLLAR => 1,
+});
+
+my $p3 = Template::Config->parser({
+ TAG_STYLE => 'html',
+ POST_CHOMP => 1,
INTERPOLATE => 1,
-};
+});
+
+my $p4 = Template::Config->parser({
+ CASE => 1,
+});
-my $vars = {
- a => 'alpha',
- b => 'bravo',
- c => 'charlie',
-};
+my $tt = [
+ tt1 => Template->new(),
+ tt2 => Template->new(PARSER => $p2),
+ tt3 => Template->new(PARSER => $p3),
+ tt4 => Template->new(PARSER => $p4),
+];
-test_expect(\*DATA, $config, $vars);
+test_expect(\*DATA, $tt, &callsign());
__DATA__
+#------------------------------------------------------------------------
+# tt1
+#------------------------------------------------------------------------
+-- test --
+start $a
+[% BLOCK a %]
+this is a
+[% END %]
+=[% INCLUDE a %]=
+=[% include a %]=
+end
+-- expect --
+start $a
+
+=
+this is a
+=
+=
+this is a
+=
+end
+
+#------------------------------------------------------------------------
+# tt2
+#------------------------------------------------------------------------
+-- test --
+-- use tt2 --
+begin
+[% this will be ignored %]
+[* a *]
+end
+-- expect --
+begin
+[% this will be ignored %]alpha
+end
+
+-- test --
+$b does nothing:
+[* c = 'b'; 'hello' *]
+stuff:
+[* $c *]
+-- expect --
+$b does nothing: hello
+stuff: b
+
+#------------------------------------------------------------------------
+# tt3
+#------------------------------------------------------------------------
-- test --
-[% a %] at $b @ [% c %]
+-- use tt3 --
+begin
+[% this will be ignored %]
+<!-- a -->
+end
-- expect --
-alpha at bravo @ charlie
+begin
+[% this will be ignored %]
+alphaend
+-- test --
+$b does something:
+<!-- c = 'b'; 'hello' -->
+stuff:
+<!-- $c -->
+end
+-- expect --
+bravo does something:
+hellostuff:
+bravoend
+#------------------------------------------------------------------------
+# tt4
+#------------------------------------------------------------------------
+-- test --
+-- use tt4 --
+start $a[% 'include' = 'hello world' %]
+[% BLOCK a -%]
+this is a
+[%- END %]
+=[% INCLUDE a %]=
+=[% include %]=
+end
+-- expect --
+start $a
+=this is a=
+=hello world=
+end
View
158 t/plugins.t
@@ -0,0 +1,158 @@
+#============================================================= -*-perl-*-
+#
+# t/plugins.t
+#
+# Test the Template::Plugins module.
+#
+# Written by Andy Wardley <abw@kfs.org>
+#
+# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
+# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+# $Id$
+#
+#========================================================================
+
+use strict;
+use lib qw( ./lib ../lib );
+use Template::Test;
+use Cwd qw( abs_path );
+$^W = 1;
+
+#$Template::Test::DEBUG = 0;
+#$Template::Plugins::DEBUG = 0;
+
+my $dir = abs_path( -d 't' ? 't/test/plugin' : 'test/plugin' );
+unshift(@INC, $dir);
+
+my $tt1 = Template->new({
+ PLUGIN_BASE => 'MyPlugs',
+});
+
+require "MyPlugs/Bar.pm";
+my $bar = MyPlugs::Bar->new(4);
+
+my $tt2 = Template->new({
+ PLUGINS => {
+ bar => 'MyPlugs::Bar',
+ baz => 'MyPlugs::Foo',
+ cgi => 'MyPlugs::Bar',
+ },
+});
+
+my $tt3 = Template->new({
+ LOAD_PERL => 1,
+});
+
+my $tt = [
+ def => Template->new(),
+ tt1 => $tt1,
+ tt2 => $tt2,
+ tt3 => $tt3,
+];
+
+test_expect(\*DATA, $tt, &callsign());
+
+__END__
+#------------------------------------------------------------------------
+# basic plugin loads
+#------------------------------------------------------------------------
+-- test --
+[% USE Table([2, 3, 5, 7, 11, 13], rows=2) -%]
+[% Table.row(0).join(', ') %]
+-- expect --
+2, 5, 11
+
+-- test --
+[% USE table([17, 19, 23, 29, 31, 37], rows=2) -%]
+[% table.row(0).join(', ') %]
+-- expect --
+17, 23, 31
+
+-- test --
+[% USE t = Table([41, 43, 47, 49, 53, 59], rows=2) -%]
+[% t.row(0).join(', ') %]
+-- expect --
+41, 47, 53
+
+-- test --
+[% USE t = table([61, 67, 71, 73, 79, 83], rows=2) -%]
+[% t.row(0).join(', ') %]
+-- expect --
+61, 71, 79
+
+#------------------------------------------------------------------------
+# load Foo plugin through custom PLUGIN_BASE
+#------------------------------------------------------------------------
+-- test --
+-- use tt1 --
+-- test --
+[% USE t = table([89, 97, 101, 103, 107, 109], rows=2) -%]
+[% t.row(0).join(', ') %]
+-- expect --
+89, 101, 107
+
+-- test --
+[% USE Foo(2) -%]
+[% Foo.output %]
+-- expect --
+This is the Foo plugin, value is 2
+
+-- test --
+[% USE Bar(4) -%]
+[% Bar.output %]
+-- expect --
+This is the Bar plugin, value is 4
+
+#------------------------------------------------------------------------
+# load Foo plugin through custom PLUGINS
+#------------------------------------------------------------------------
+
+-- test --
+-- use tt2 --
+[% USE t = table([113, 127, 131, 137, 139, 149], rows=2) -%]
+[% t.row(0).join(', ') %]
+-- expect --
+113, 131, 139
+
+-- test --
+[% TRY -%]
+[% USE Foo(8) -%]
+[% Foo.output %]
+[% CATCH -%]
+ERROR: [% error.info %]
+[% END %]
+-- expect --
+ERROR: Foo: plugin not found
+
+-- test --
+[% USE bar(16) -%]
+[% bar.output %]
+-- expect --
+This is the Bar plugin, value is 16
+
+-- test --
+[% USE qux = baz(32) -%]
+[% qux.output %]
+-- expect --
+This is the Foo plugin, value is 32
+
+-- test --
+[% USE wiz = cgi(64) -%]
+[% wiz.output %]
+-- expect --
+This is the Bar plugin, value is 64
+
+#------------------------------------------------------------------------
+# LOAD_PERL
+#------------------------------------------------------------------------
+
+-- test --
+-- use tt3 --
+[% USE baz = MyPlugs.Baz(128) -%]
+[% baz.output %]
+-- expect --
+This is the Baz module, value is 128
View
6 t/provider.t
@@ -136,15 +136,15 @@ sub denied {
# we can pass to text_expect() to do some template driven testing
#------------------------------------------------------------------------
-my $ttinc = Template->new( TEMPLATES => [ $provinc ] )
+my $ttinc = Template->new( LOAD_TEMPLATES => [ $provinc ] )
|| die "$Template::ERROR\n";
ok( $ttinc );
-my $ttabs = Template->new( TEMPLATES => [ $provabs ] )
+my $ttabs = Template->new( LOAD_TEMPLATES => [ $provabs ] )
|| die "$Template::ERROR\n";
ok( $ttabs );
-my $ttrel = Template->new( TEMPLATES => [ $provrel ] )
+my $ttrel = Template->new( LOAD_TEMPLATES => [ $provrel ] )
|| die "$Template::ERROR\n";
ok( $ttrel );
View
277 t/switch.t
@@ -0,0 +1,277 @@
+#============================================================= -*-perl-*-
+#
+# t/switch.t
+#
+# Template script testing SWITCH / CASE blocks
+#
+# Written by Andy Wardley <abw@kfs.org>
+#
+# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
+# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+# $Id$
+#
+#========================================================================
+
+use strict;
+use lib qw( ./lib ../lib );
+use Template::Test;
+$^W = 1;
+
+$Template::Test::DEBUG = 0;
+#$Template::Parser::DEBUG = 0;
+
+my $ttcfg = {
+# INCLUDE_PATH => [ qw( t/test/lib test/lib ) ],
+ POST_CHOMP => 1,
+};
+
+test_expect(\*DATA, $ttcfg, &callsign());
+
+__DATA__
+#------------------------------------------------------------------------
+# test simple case
+#------------------------------------------------------------------------
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% END %]
+after
+
+-- expect --
+before
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE x %]
+not matched
+[% END %]
+after
+
+-- expect --
+before
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE not_defined %]
+not matched
+[% END %]
+after
+
+-- expect --
+before
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE 'alpha' %]
+matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE a %]
+matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH 'alpha' %]
+this is ignored
+[% CASE a %]
+matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE b %]
+matched
+[% END %]
+after
+
+-- expect --
+before
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE a %]
+matched
+[% CASE b %]
+not matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE b %]
+not matched
+[% CASE a %]
+matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+#------------------------------------------------------------------------
+# test default case
+#------------------------------------------------------------------------
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE a %]
+matched
+[% CASE b %]
+not matched
+[% CASE %]
+default not matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE a %]
+matched
+[% CASE b %]
+not matched
+[% CASE DEFAULT %]
+default not matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE z %]
+not matched
+[% CASE x %]
+not matched
+[% CASE %]
+default matched
+[% END %]
+after
+
+-- expect --
+before
+default matched
+after
+
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE z %]
+not matched
+[% CASE x %]
+not matched
+[% CASE DEFAULT %]
+default matched
+[% END %]
+after
+
+-- expect --
+before
+default matched
+after
+
+#------------------------------------------------------------------------
+# test multiple matches
+#------------------------------------------------------------------------
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE [ a b c ] %]
+matched
+[% CASE d %]
+not matched
+[% CASE %]
+default not matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
+-- test --
+before
+[% SWITCH a %]
+this is ignored
+[% CASE [ a b c ] %]
+matched
+[% CASE a %]
+not matched, no drop-through
+[% CASE DEFAULT %]
+default not matched
+[% END %]
+after
+
+-- expect --
+before
+matched
+after
+
View
15 t/template.t
@@ -2,7 +2,9 @@
#
# t/template.t
#
-# Test the Template.pm module.
+# Test the Template.pm module. Does nothing of any great importance
+# at the moment, but all of its options are tested in the various other
+# test scripts.
#
# Written by Andy Wardley <abw@kfs.org>
#
@@ -18,15 +20,8 @@
use strict;
use lib qw( ./lib ../lib );
-use vars qw( $DEBUG );
+use Template;
use Template::Test;
-ntests(1);
-$DEBUG = 1;
-
-my $tt = Template->new(INCLUDE_PATH => 'here')
- || die $Template::ERROR;
-
+my $tt = Template->new();
ok( $tt );
-#ok( $tt->context->{ TEMPLATES }->[0]->{ INCLUDE_PATH }->[0] eq 'here' );
-#print $tt->service->context->{ TEMPLATES }->[0]->_dump();
View
6 t/test/src/complex
@@ -29,3 +29,9 @@ This is the footer, author: [% template.author %], version: [% template.version
+
+
+
+
+
+
View
2  t/try.t
@@ -2,7 +2,7 @@
#
# t/try.t
#
-# Template script testing TRY blocks
+# Template script testing TRY / THROW / CATCH / FINAL blocks.
#
# Written by Andy Wardley <abw@kfs.org>
#
Please sign in to comment.
Something went wrong with that request. Please try again.