Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

*** empty log message ***

git-svn-id: svn://svn.tt2.org/tt/Template2/trunk@17 d5a88997-0a34-4036-9ed2-92fb5d660d91
  • Loading branch information...
commit 9d806e606b60a2578a942fbdf3ec8cbd564811da 1 parent c1d9c89
Andy Wardley authored
536 Changes
View
@@ -1,3 +1,506 @@
+#========================================================================
+#
+# Changes
+#
+# DESCRIPTION
+# Revision history for Template Toolkit.
+#
+# AUTHOR
+# Andy Wardley <abw@kfs.org>
+#
+#------------------------------------------------------------------------
+# $Id$
+#========================================================================
+
+
+#========================================================================
+# ***** VERSION 2.00 *****
+#
+# The following list outlines the major differences between version 1.*
+# and version 2.00 of the Template Toolkit.
+#========================================================================
+
+New Language Features
+---------------------
+
+* New SWITCH / CASE statement. SWITCH takes an expression, CASE takes
+ a value or list of values to match. CASE may also be left blank or
+ written as [% CASE default %] to specify a default match. Only one
+ CASE matches, there is no drop-through between CASE statements.
+
+ [% SWITCH myvar %]
+ [% CASE value1 %]
+ ...
+ [% CASE [ value2 value3 ] %] # multiple values to match
+ ...
+ [% CASE myhash.keys %] # ditto
+ ...
+ [% CASE %] # default, or [% CASE default %]
+ ...
+ [% END %]
+
+* New TRY / CATCH / FINAL construct for fully functional, nested
+ exception handling. The block following the TRY is executed and
+ output if no exceptions are throw. Otherwise, the relevant CATCH
+ block is executed. CATCH types are hierarchical (e.g 'foo' catches
+ 'foo.bar') or the CATCH type may be left blank or specified as [%
+ CATCH default %] to provide a default handler. The contents of a
+ FINAL block, if specified, will be processed last of all, regardless
+ of the result (except an uncaught exception which is throw upwards
+ to any enclosing TRY block).
+
+ [% TRY %]
+ ...blah...blah...
+ [% CALL somecode %] # may throw an exception
+ ...etc...
+ [% INCLUDE someblock %] # may have a [% THROW ... %] directive
+ ...and so on...
+ [% CATCH file %] # catch system-generated 'file' exception
+ ...
+ [% CATCH DBI %] # catch 'DBI' or 'DBI.*'
+ ...
+ [% CATCH %] # catch anything else
+ ...
+ [% FINAL %] # optional
+ All done!
+ [% END %]
+
+* New CLEAR directive to clear the current output buffer. This is typically
+ used in a CATCH block to clear the output of a failed TRY block. Any output
+ generated in a TRY block up to the point that an exception was thrown will
+ be output by default. The [% CLEAR %] directive in a catch block clears
+ this output from the TRY block.
+
+ [% TRY %]
+ blah blah blah, this is the current output block
+ [% THROW some.error 'Danger Will Robinson!' %]
+ not reached...
+ [% CATCH %]
+ [% # at this point, the output block contains the 'blah blah...' line
+ # up to the point where the THROW occured, but we don't want it
+ CLEAR
+ %]
+ Here we can add some more text if we want...
+ [% END %]
+
+ In general, the CLEAR directive clears the current output from the
+ template or enclosing block.
+
+* New META directive allowing you to define metadata items for your
+ template. These are attached to the compiled template and wrapped
+ up as a Template::Document object. The 'template' variable is a
+ reference to the current parent document and metadata items may be
+ accessed directly. Of particular note is the fact that the
+ 'template' variable is correctly defined for all PRE_PROCESS and
+ POST_PROCESS headers. Thus, your headers and footers can access
+ items from the main template (e.g. title, author, section, keywords,
+ flags, etc) and display them or act accordingly.
+
+ mytemplate:
+ [% META
+ title = 'This is a Test'
+ author = 'Andy Wardley'
+ copyright = "2000, Andy Wardley"
+ %]
+
+ <h1>[% template.title %]</h1>
+ blah blah
+
+ header: (a PRE_PROCESS template)
+ <html>
+ <head><title>[% template.title %]</title></head>
+ <body>
+
+ footer: (a POST_PROCESS template)
+ <hr>
+ &copy; Copyright [% template.copyright or '2000, MyCompany' %]
+
+* New RAWPERL ... END block directive allows you to write raw Perl
+ code which is integrated intact and unsullied into the destination
+ template sub-routine. The existing PERL ... END directive continues
+ to be supported, offering runtime evaluation of a block which may
+ contain other template directives, etc, which are first evaluated
+ (e.g. PERL...END processes the block and filters the output into
+ Perl evaluation at runtime).
+
+* The output from any directive or block can now be captured and assigned to
+ a variable.
+
+ [% htext = INCLUDE header %]
+ [% btext = BLOCK %]
+ blah blah
+ [% x %] [% y %] [% z %]
+ [% END %]
+
+ # you can even assign the output of loops, conditions, etc.
+ [% numbers = FOREACH n = [2, 3, 5, 7, 11, 13] %]
+ blah blah [% n %]
+ [% END %]
+
+* The handling of complex expressions has been improved, permitting
+ basic directives to contain logical shortcut operators, etc.
+
+ [% foo or bar %] # GET foo, or bar if foo is false (0/undef)
+ [% CALL func1 and func2 %] # func2 only called if func1 returns true
+ [% name = user.id or cgi.param('id') %].
+
+* A new "x ? y : z" operation is provided as a shorthand for
+ "if x then y else z"
+
+ [% foo = bar ? baz : qux %]
+
+* Various new pseudo-methods have been added for inspecting and manipulating
+ data. The full list now looks something like this:
+
+ [% value.defined %] # value is defined
+ [% value.length %] # length of string
+ [% value.split(delimiter, limit) %] # split string as Perl does
+
+ [% hash.keys %] # return list of hash keys
+ [% hash.values %] # ditto hash values
+
+ [% list.size %] # number of items in list
+ [% list.max %] # last item number (size - 1)
+ [% list.first %] # first item
+ [% list.last %] # last item
+ [% list.reverse %] # list in reverse order
+ [% list.sort(field) %] # list in sorted order
+ [% list.join(joint) %] # join items into single string
+
+
+Templates Compiled to Perl Code
+-------------------------------
+
+* Templates are now compiled to Perl code, with credit and respect due
+ to Doug Steinwand for providing an implementation around which the
+ new parser was built. This brings a number of important benefits:
+
+ - Speed and Memory Efficiency
+
+ Version 1 used a list of opcodes to represent directives and
+ lower-level operations. These were evaluated by the hideously
+ contrived, and darkly sinister Template::Context::_evaluate()
+ method. In version 2, all templates are parsed and rebuilt as
+ Perl code. This is then evaluated and stored as a reference to a
+ Perl sub-routine which can then be executed and re-executed
+ significantly faster and with far less memory overhead.
+
+ - Persistance.
+
+ Once a template has been compiled to Perl code it can be saved to
+ disk as a "compiled template" by defining the COMPILE_EXT option.
+ This allows you to specify a filename extension (e.g. '.ttc')
+ which is added to the template filename and used to create a new
+ file containg the Perl code. Next time you use the template, even
+ if you've shut down your program/server/computer in the mean time,
+ the compiled template is there in a file as Perl code and is
+ simply require()d and executed. It all happens significantly
+ faster because there's no Template::Parser to run. In fact, if
+ all your templates are "compiled" on disk then the
+ Template::Parser and Template::Grammar modules won't even be
+ loaded, further reducing startup time and memory consumption (the
+ grammar file, in particular is rather large). The
+ Template::Provider module handles the loading, caching and
+ persistance of templates, and will examine file timestamps and
+ re-compiled modified templates as required.
+
+ - Flexibility.
+
+ Because "compiled templates" are now nothing more than Perl
+ sub-routines, you can use anyone or anything to generate them and
+ run them all under the same roof. Different parser back-ends can
+ generate Perl code optimised for speed or functionality, for example.
+ Or different parsers can compile different template languages
+ (PHP, ASP, Mason, roll-your-own, etc.) and run them alongside
+ regular templates. Or if you don't trust a parser, you can wri
+ even write your own Perl code and have your templates execute
+ as fast as the code you can write.
+
+* Templates (i.e. sub-routines) now return their generated output,
+ rather than sending it to $context->output(). This speeds things
+ up and makes the code simpler, as well as allowing greater
+ flexibility in how template sub-routines can work.
+
+* Exceptions (errors) are now raised via Perl's die() and caught by
+ an enclosing eval { } block. Again, this simplifies the code generated
+ and improves runtime efficiency.
+
+* The directives [% RETURN %] and [% STOP %] are now implemented as
+ special case exceptions which are caught in the appropriate place
+ and handled accordingly.
+
+
+Miscellaneous Features
+----------------------
+
+* The INTERPOLATE option is now automatically disabled within PERL and
+ RAWPERL blocks to prevent Perl $variables from being interpreted as
+ template variables.
+
+ # INTERPOLATE = 1
+ This $var will get interpolated...
+ [% PERL %]
+ # but these won't
+ my $foo = 'some value';
+ my $bar = 'another value';
+ # etc...
+ [% END %]
+ no 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.
+
+
+
+ * 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.
+
+
+ * Local named BLOCK definitions are better behaved and don't permanently
+ mask any real files. Currently, INCLUDE does not import BLOCKs, but
+ PROCESS does (as per variables), although this may change slightly.
+
+ * The Template::Stash object now encapsulates all the magical variable
+ resolution code. Both simple and compound variables can be accessed
+ or updated using the get() and set() methods, with all "variable magic"
+ happening automatically.
+
+ * The Template::Context object is now greatly simplified. This acts
+ as a general interface to the Template Toolkit functionality, being
+ a collection of the various other modules that actually implement
+ the functionality (e.g. Template::Stash, Template::Provider,
+ Template::Document, Template::Plugins, etc.)
+
+ * The Template::Provider object provides a general facility for
+ retrieving templates from disk (or other source), and if necessary
+ compiling via a call to a Template::Parser helper object.
+ Multiple Template::Provider objects may be specified as the
+ TEMPLATES option to a Template::Context. These form a
+ chain-of-command in which each successive provider is asked to
+ fetch() a template and may return a compiled template, an error,
+ or decline to service the request, thereby deferring to the next
+ provider in the chain. The Template::Provider also handles
+ caching of compiled templates and has many improvements over the
+ version 1 Template::Cache, most significant of which is the
+ ability to limit the cache to a maximum number of templates.
+
+ * The Template::Parser object now compiles template text into Perl code
+ and then evaluates it into a sub-routine reference using Perl's
+ eval(). This is then wrapped up into a Template::Document object,
+ including any metadata items and/or additional named BLOCKs defined
+ in the input template.
+
+ * The Template::Document object is a thin wrapper around a compiled
+ template sub-routine. It provides a process() method for processing
+ the template and a blocks() method for returning a reference to the
+ hash array of any additional named BLOCKs defined in the original
+ template text. An AUTOLOAD method returns values of metadata items,
+ allowing a Template::Document reference to be used as the 'template'
+ variable.
+
+ * The Template::Service module provides a high-level service for
+ processing templates, using an underlying Template::Context
+ reference to access the toolkit functionality. PRE_PROCESS and
+ POST_PROCESS templates may be specified which are added to all
+ templates processed via this service. An ERROR template may also
+ be specified, or as a reference to a hash array mapping error
+ types to template names. This is then used to provide consistent
+ and automatic error handling in response to uncaught errors thrown
+ from templates. In such a case, the approporiate error template
+ is processed in place of the original template. PRE_PROCESS and
+ POST_PROCESS templates are added to the error template to maintain
+ the expected consistency of the service. The Template::Service
+ module may be sub-classed, or replaced by other modules to implement
+ different template based services.
+
+ * The Template::Plugins module is a special purpose provider variant
+ for loading and instantiating plugins. Multiple plugin providers
+ may be specified as the PLUGINS option to a context and these act
+ in a chain-of-command as per the TEMPLATES providers.
+
+ * The Template::Filters module is similar to Template::Plugins, but
+ for providing access to filters. The FILTERS options may also
+ contain multiple entries as above.
+
+ * The Template::Base module defines a common base class for many of
+ the toolkit modules. It implements shared functionality such as a
+ constructor, error reporting and handling, etc. Modules are now
+ much easier to sub-class, all using separate new() and _init()
+ methods.
+
+ * The Template::Config module (name may change) provides methods for
+ loading and instantiating different Template Toolkit modules. Using
+ this factory-based approach makes it far easier to change the default
+ object class for a specific part of the toolkit. e.g.
+
+ use Template;
+ use Template::Config;
+
+ $Template::Config::PARSER = 'MyTemplate::MyParser';
+
+ my $tt = Template->new({ ... })
+ ...
+
+ # $tt object will use a MyTemplate::MyParser object for PARSER
+
+ * The Template module remains, as it ever was, a simple front-end
+ to the Template Toolkit. This creates a single Template::Service
+ to which it delegates control for processing templates. Output
+ is returned according to the OUTPUT options specified for the module
+ and/or any output option passed explicitly to the process() method.
+
+There's still some debug code in the wrong places, and some things that
+need to be tidied up to boost performance. In particular, the parser
+goes out of its way to pretty-print generated Perl code (for the sake of
+easy debugging - set $Template::Parser::DEBUG to see the generated code)
+so expect it to run a little sluggish. Once the templates are compiled,
+they should execute measurably faster than before but unless you're
+running a persistant server, you probably won't notice how fast they
+run because the process time is overshadowed by the parse time.
+I did some very rough benchmarks and had it processing templates
+around 2 - 3 times faster than version 1. This still falls short of
+what's possible, but for now it represents a good start. :-)=
+
+
+
+
+
This list isn't complete - it's more of a reminder to me at the moment.
----------------------------------------------------------------------
@@ -37,4 +540,35 @@ changes from alpha to beta
--------------------------
* fixed bug in Context filter() provider method which wasn't caching
- filters with args.
+ 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.
17 MANIFEST
View
@@ -34,7 +34,24 @@ docs/lib/ref/despat
docs/lib/revision
docs/lib/seealso
docs/lib/version
+docs/pod/Base.pod
+docs/pod/Config.pod
+docs/pod/Constants.pod
+docs/pod/Context.pod
+docs/pod/Document.pod
+docs/pod/Exception.pod
+docs/pod/Filters.pod
+docs/pod/Iterator.pod
+docs/pod/Parser.pod
+docs/pod/Plugin.pod
+docs/pod/Plugins.pod
+docs/pod/Provider.pod
docs/pod/README
+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
3  MANIFEST.SKIP
View
@@ -9,5 +9,6 @@
^parser/Parser\.output
^docs/design/
^docs/tpj/
-^docs/pod/.*\.pod$
+^docs/about
+^docs/release
7 Makefile.PL
View
@@ -26,10 +26,13 @@ WriteMakefile(
sub build_docs {
return <<EOF;
echo "Building documentation for version \$(VERSION)" ; \\
-\$(CHMOD) 644 docs/pod/*.pod; \\
\$(PERL) bin/ttree -f ./docs/ttree.cfg -a; \\
-\$(CHMOD) 444 docs/pod/*.pod; \\
EOF
}
+# Could add these before/after call to ttree to write-protect output docs
+# to prevent accidental editing. Better to edit the source files...
+# \$(CHMOD) 644 docs/pod/*.pod; \\
+# \$(CHMOD) 444 docs/pod/*.pod; \\
+
2  lib/Template.pm
View
@@ -38,7 +38,7 @@ use Template::Utils;
## This is the main version number for the Template Toolkit.
## It is extracted by ExtUtils::MakeMaker and inserted in various places.
-$VERSION = '1.51';
+$VERSION = '1.52';
$ERROR = '';
$DEBUG = 0;
190 lib/Template/Grammar.pm
View
@@ -41,7 +41,6 @@ $VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
my (@RESERVED, %CMPOP, $LEXTABLE, $RULES, $STATES);
my $factory;
-my $v1compat;
#========================================================================
@@ -4254,25 +4253,25 @@ sub
[#Rule 34
'atomdir', 1,
sub
-#line 112 "Parser.yp"
+#line 111 "Parser.yp"
{ $factory->clear() }
],
[#Rule 35
'atomdir', 1,
sub
-#line 113 "Parser.yp"
+#line 112 "Parser.yp"
{ $factory->break() }
],
[#Rule 36
'atomdir', 1,
sub
-#line 114 "Parser.yp"
+#line 113 "Parser.yp"
{ $factory->return() }
],
[#Rule 37
'atomdir', 1,
sub
-#line 115 "Parser.yp"
+#line 114 "Parser.yp"
{ $factory->stop() }
],
[#Rule 38
@@ -4281,219 +4280,219 @@ sub
[#Rule 39
'condition', 6,
sub
-#line 120 "Parser.yp"
+#line 119 "Parser.yp"
{ $factory->if(@_[2, 4, 5]) }
],
[#Rule 40
'condition', 3,
sub
-#line 121 "Parser.yp"
+#line 120 "Parser.yp"
{ $factory->if(@_[3, 1]) }
],
[#Rule 41
'condition', 6,
sub
-#line 123 "Parser.yp"
+#line 122 "Parser.yp"
{ $factory->if("!($_[2])", @_[4, 5]) }
],
[#Rule 42
'condition', 3,
sub
-#line 124 "Parser.yp"
+#line 123 "Parser.yp"
{ $factory->if("!($_[3])", $_[1]) }
],
[#Rule 43
'else', 5,
sub
-#line 128 "Parser.yp"
+#line 127 "Parser.yp"
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 44
'else', 3,
sub
-#line 130 "Parser.yp"
+#line 129 "Parser.yp"
{ [ $_[3] ] }
],
[#Rule 45
'else', 0,
sub
-#line 131 "Parser.yp"
+#line 130 "Parser.yp"
{ [ undef ] }
],
[#Rule 46
'switch', 6,
sub
-#line 135 "Parser.yp"
+#line 134 "Parser.yp"
{ $factory->switch(@_[2, 5]) }
],
[#Rule 47
'case', 5,
sub
-#line 139 "Parser.yp"
+#line 138 "Parser.yp"
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 48
'case', 3,
sub
-#line 141 "Parser.yp"
+#line 140 "Parser.yp"
{ [ $_[3] ] }
],
[#Rule 49
'case', 0,
sub
-#line 142 "Parser.yp"
+#line 141 "Parser.yp"
{ [ undef ] }
],
[#Rule 50
'loop', 5,
sub
-#line 146 "Parser.yp"
+#line 145 "Parser.yp"
{ $factory->foreach(@{$_[2]}, $_[4]) }
],
[#Rule 51
'loop', 3,
sub
-#line 147 "Parser.yp"
+#line 146 "Parser.yp"
{ $factory->foreach(@{$_[3]}, $_[1]) }
],
[#Rule 52
'loop', 5,
sub
-#line 149 "Parser.yp"
+#line 148 "Parser.yp"
{ $factory->while(@_[2, 4]) }
],
[#Rule 53
'loop', 3,
sub
-#line 150 "Parser.yp"
+#line 149 "Parser.yp"
{ $factory->while(@_[3, 1]) }
],
[#Rule 54
'loopvar', 4,
sub
-#line 153 "Parser.yp"
+#line 152 "Parser.yp"
{ [ @_[1, 3, 4] ] }
],
[#Rule 55
'loopvar', 2,
sub
-#line 154 "Parser.yp"
+#line 153 "Parser.yp"
{ [ 0, @_[1, 2] ] }
],
[#Rule 56
'try', 5,
sub
-#line 158 "Parser.yp"
+#line 157 "Parser.yp"
{ $factory->try(@_[3, 4]) }
],
[#Rule 57
'final', 5,
sub
-#line 162 "Parser.yp"
+#line 161 "Parser.yp"
{ unshift(@{$_[5]}, [ @_[2,4] ]);
$_[5]; }
],
[#Rule 58
'final', 5,
sub
-#line 165 "Parser.yp"
+#line 164 "Parser.yp"
{ unshift(@{$_[5]}, [ undef, $_[4] ]);
$_[4]; }
],
[#Rule 59
'final', 4,
sub
-#line 168 "Parser.yp"
+#line 167 "Parser.yp"
{ unshift(@{$_[4]}, [ undef, $_[3] ]);
$_[4]; }
],
[#Rule 60
'final', 3,
sub
-#line 170 "Parser.yp"
+#line 169 "Parser.yp"
{ [ $_[3] ] }
],
[#Rule 61
'final', 0,
sub
-#line 171 "Parser.yp"
+#line 170 "Parser.yp"
{ [ 0 ] }
],
[#Rule 62
'use', 2,
sub
-#line 174 "Parser.yp"
+#line 173 "Parser.yp"
{ $factory->use($_[2]) }
],
[#Rule 63
'@1-2', 0,
sub
-#line 177 "Parser.yp"
+#line 176 "Parser.yp"
{ ${$_[0]->{ INPERL }}++; }
],
[#Rule 64
'perl', 5,
sub
-#line 178 "Parser.yp"
+#line 177 "Parser.yp"
{ ${$_[0]->{ INPERL }}--;
$factory->perl($_[4]) }
],
[#Rule 65
'@2-2', 0,
sub
-#line 182 "Parser.yp"
+#line 181 "Parser.yp"
{ ${$_[0]->{ INPERL }}++; }
],
[#Rule 66
'rawperl', 5,
sub
-#line 183 "Parser.yp"
+#line 182 "Parser.yp"
{ ${$_[0]->{ INPERL }}--;
$factory->rawperl($_[4]) }
],
[#Rule 67
'filter', 5,
sub
-#line 188 "Parser.yp"
+#line 187 "Parser.yp"
{ $factory->filter(@_[2,4]) }
],
[#Rule 68
'filter', 3,
sub
-#line 190 "Parser.yp"
+#line 189 "Parser.yp"
{ $factory->filter(@_[3,1]) }
],
[#Rule 69
'defblock', 5,
sub
-#line 194 "Parser.yp"
+#line 193 "Parser.yp"
{ $_[0]->define_block(@_[2, 4]);
undef }
],
[#Rule 70
'anonblock', 4,
sub
-#line 198 "Parser.yp"
+#line 197 "Parser.yp"
{ $factory->anon_block($_[3]) }
],
[#Rule 71
'capture', 3,
sub
-#line 201 "Parser.yp"
+#line 200 "Parser.yp"
{ $factory->capture(@_[1, 3]) }
],
[#Rule 72
'macro', 6,
sub
-#line 205 "Parser.yp"
+#line 204 "Parser.yp"
{ $factory->macro(@_[2, 6, 4]) }
],
[#Rule 73
'macro', 3,
sub
-#line 206 "Parser.yp"
+#line 205 "Parser.yp"
{ $factory->macro(@_[2, 3]) }
],
[#Rule 74
@@ -4502,31 +4501,31 @@ sub
[#Rule 75
'mdir', 4,
sub
-#line 210 "Parser.yp"
+#line 209 "Parser.yp"
{ $_[3] }
],
[#Rule 76
'margs', 2,
sub
-#line 213 "Parser.yp"
+#line 212 "Parser.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 77
'margs', 2,
sub
-#line 214 "Parser.yp"
+#line 213 "Parser.yp"
{ $_[1] }
],
[#Rule 78
'margs', 1,
sub
-#line 215 "Parser.yp"
+#line 214 "Parser.yp"
{ [ $_[1] ] }
],
[#Rule 79
'metadata', 2,
sub
-#line 218 "Parser.yp"
+#line 217 "Parser.yp"
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 80
@@ -4538,20 +4537,20 @@ sub
[#Rule 82
'meta', 3,
sub
-#line 223 "Parser.yp"
+#line 222 "Parser.yp"
{ for ($_[3]) { s/^'//; s/'$// };
[ @_[1,3] ] }
],
[#Rule 83
'meta', 5,
sub
-#line 225 "Parser.yp"
+#line 224 "Parser.yp"
{ [ @_[1,4] ] }
],
[#Rule 84
'meta', 3,
sub
-#line 226 "Parser.yp"
+#line 225 "Parser.yp"
{ [ @_[1,3] ] }
],
[#Rule 85
@@ -4563,31 +4562,31 @@ sub
[#Rule 87
'lterm', 3,
sub
-#line 238 "Parser.yp"
+#line 237 "Parser.yp"
{ "[ $_[2] ]" }
],
[#Rule 88
'lterm', 3,
sub
-#line 239 "Parser.yp"
+#line 238 "Parser.yp"
{ "[ $_[2] ]" }
],
[#Rule 89
'lterm', 3,
sub
-#line 240 "Parser.yp"
+#line 239 "Parser.yp"
{ "{ $_[2] }" }
],
[#Rule 90
'sterm', 1,
sub
-#line 243 "Parser.yp"
+#line 242 "Parser.yp"
{ $factory->ident($_[1]) }
],
[#Rule 91
'sterm', 3,
sub
-#line 244 "Parser.yp"
+#line 243 "Parser.yp"
{ $factory->quoted($_[2]) }
],
[#Rule 92
@@ -4599,7 +4598,7 @@ sub
[#Rule 94
'list', 2,
sub
-#line 249 "Parser.yp"
+#line 248 "Parser.yp"
{ "$_[1], $_[2]" }
],
[#Rule 95
@@ -4611,7 +4610,7 @@ sub
[#Rule 97
'range', 3,
sub
-#line 254 "Parser.yp"
+#line 253 "Parser.yp"
{ $_[1] . '..' . $_[3] }
],
[#Rule 98
@@ -4623,7 +4622,7 @@ sub
[#Rule 100
'params', 2,
sub
-#line 262 "Parser.yp"
+#line 261 "Parser.yp"
{ "$_[1], $_[2]" }
],
[#Rule 101
@@ -4635,25 +4634,25 @@ sub
[#Rule 103
'param', 3,
sub
-#line 267 "Parser.yp"
+#line 266 "Parser.yp"
{ "$_[1] => $_[3]" }
],
[#Rule 104
'param', 3,
sub
-#line 268 "Parser.yp"
+#line 267 "Parser.yp"
{ "'$_[1]' => $_[3]" }
],
[#Rule 105
'ident', 3,
sub
-#line 271 "Parser.yp"
+#line 270 "Parser.yp"
{ push(@{$_[1]}, @{$_[3]}); $_[1] }
],
[#Rule 106
'ident', 3,
sub
-#line 272 "Parser.yp"
+#line 271 "Parser.yp"
{ push(@{$_[1]}, $_[3], 0); $_[1] }
],
[#Rule 107
@@ -4662,88 +4661,87 @@ sub
[#Rule 108
'node', 1,
sub
-#line 276 "Parser.yp"
+#line 275 "Parser.yp"
{ [ $_[1], 0 ] }
],
[#Rule 109
'node', 4,
sub
-#line 277 "Parser.yp"
+#line 276 "Parser.yp"
{ [ $_[1], $factory->args($_[3]) ] }
],
[#Rule 110
'item', 1,
sub
-#line 280 "Parser.yp"
+#line 279 "Parser.yp"
{ "'$_[1]'" }
],
[#Rule 111
'item', 3,
sub
-#line 281 "Parser.yp"
+#line 280 "Parser.yp"
{ $_[2] }
],
[#Rule 112
'item', 2,
sub
-#line 282 "Parser.yp"
-{ ($v1compat ||=
- ($_[0]->{ VERSION } == 1))
+#line 281 "Parser.yp"
+{ $_[0]->{ V1DOLLAR }
? "'$_[2]'"
: $factory->ident(["'$_[2]'", 0]) }
],
[#Rule 113
'expr', 3,
sub
-#line 288 "Parser.yp"
+#line 286 "Parser.yp"
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 114
'expr', 3,
sub
-#line 289 "Parser.yp"
+#line 287 "Parser.yp"
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 115
'expr', 3,
sub
-#line 290 "Parser.yp"
+#line 288 "Parser.yp"
{ "$_[1] $CMPOP{ $_[2] } $_[3]" }
],
[#Rule 116
'expr', 3,
sub
-#line 291 "Parser.yp"
+#line 289 "Parser.yp"
{ "($_[1]) && ($_[3])" }
],
[#Rule 117
'expr', 3,
sub
-#line 292 "Parser.yp"
+#line 290 "Parser.yp"
{ "($_[1]) || ($_[3])" }
],
[#Rule 118
'expr', 2,
sub
-#line 293 "Parser.yp"
+#line 291 "Parser.yp"
{ "!($_[2])" }
],
[#Rule 119
'expr', 5,
sub
-#line 294 "Parser.yp"
+#line 292 "Parser.yp"
{ "(($_[1]) ? ($_[3]) : ($_[5]))" }
],
[#Rule 120
'expr', 3,
sub
-#line 295 "Parser.yp"
+#line 293 "Parser.yp"
{ $factory->assign(@{$_[2]}) }
],
[#Rule 121
'expr', 3,
sub
-#line 296 "Parser.yp"
+#line 294 "Parser.yp"
{ "($_[2])" }
],
[#Rule 122
@@ -4752,7 +4750,7 @@ sub
[#Rule 123
'setlist', 2,
sub
-#line 300 "Parser.yp"
+#line 298 "Parser.yp"
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 124
@@ -4761,43 +4759,43 @@ sub
[#Rule 125
'assign', 3,
sub
-#line 305 "Parser.yp"
+#line 303 "Parser.yp"
{ [ $_[1], $_[3] ] }
],
[#Rule 126
'assign', 3,
sub
-#line 306 "Parser.yp"
+#line 304 "Parser.yp"
{ [ @_[1,3] ] }
],
[#Rule 127
'args', 2,
sub
-#line 313 "Parser.yp"
+#line 311 "Parser.yp"
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 128
'args', 2,
sub
-#line 314 "Parser.yp"
+#line 312 "Parser.yp"
{ push(@{$_[1]->[0]}, $_[2]); $_[1] }
],
[#Rule 129
'args', 2,
sub
-#line 315 "Parser.yp"
+#line 313 "Parser.yp"
{ $_[1] }
],
[#Rule 130
'args', 0,
sub
-#line 316 "Parser.yp"
+#line 314 "Parser.yp"
{ [ [ ] ] }
],
[#Rule 131
'lnameargs', 3,
sub
-#line 326 "Parser.yp"
+#line 324 "Parser.yp"
{ push(@{$_[3]}, $_[1]); $_[3] }
],
[#Rule 132
@@ -4809,7 +4807,7 @@ sub
[#Rule 134
'lvalue', 3,
sub
-#line 331 "Parser.yp"
+#line 329 "Parser.yp"
{ $factory->quoted($_[2]) }
],
[#Rule 135
@@ -4818,37 +4816,37 @@ sub
[#Rule 136
'nameargs', 3,
sub
-#line 335 "Parser.yp"
+#line 333 "Parser.yp"
{ [ $factory->ident($_[2]), $_[3] ] }
],
[#Rule 137
'nameargs', 4,
sub
-#line 336 "Parser.yp"
+#line 334 "Parser.yp"
{ [ $factory->quoted($_[2]), $_[4] ] }
],
[#Rule 138
'nameargs', 2,
sub
-#line 337 "Parser.yp"
+#line 335 "Parser.yp"
{ [ $_[1], $_[2] ] }
],
[#Rule 139
'nameargs', 4,
sub
-#line 338 "Parser.yp"
+#line 336 "Parser.yp"
{ [ "'$_[1]'", $_[3] ] }
],
[#Rule 140
'nameargs', 2,
sub
-#line 339 "Parser.yp"
+#line 337 "Parser.yp"
{ [ "'$_[1]'", $_[2] ] }
],
[#Rule 141
'filename', 3,
sub
-#line 342 "Parser.yp"
+#line 340 "Parser.yp"
{ "$_[1].$_[3]" }
],
[#Rule 142
@@ -4866,32 +4864,32 @@ sub
[#Rule 146
'quoted', 2,
sub
-#line 356 "Parser.yp"
+#line 354 "Parser.yp"
{ push(@{$_[1]}, $_[2])
if defined $_[2]; $_[1] }
],
[#Rule 147
'quoted', 0,
sub
-#line 358 "Parser.yp"
+#line 356 "Parser.yp"
{ [ ] }
],
[#Rule 148
'quotable', 1,
sub
-#line 361 "Parser.yp"
+#line 359 "Parser.yp"
{ $factory->ident($_[1]) }
],
[#Rule 149
'quotable', 1,
sub
-#line 362 "Parser.yp"
+#line 360 "Parser.yp"
{ $factory->text($_[1]) }
],
[#Rule 150
'quotable', 1,
sub
-#line 363 "Parser.yp"
+#line 361 "Parser.yp"
{ undef }
]
];
4 lib/Template/Parser.pm
View
@@ -97,7 +97,7 @@ sub new {
INTERPOLATE => 0,
PRE_CHOMP => 0,
POST_CHOMP => 0,
- VERSION => 2,
+ V1DOLLAR => 0,
GRAMMAR => undef,
_ERROR => '',
}, $class;
@@ -697,7 +697,7 @@ sub _dump {
my $self = shift;
my $output = "$self:\n";
foreach my $key (qw( START_TAG END_TAG TAG_STYLE CASE INTERPOLATE
- PRE_CHOMP POST_CHOMP VERSION ) ) {
+ PRE_CHOMP POST_CHOMP V1DOLLAR ) ) {
$output .= sprintf("%-12s => %s\n", $key, $self->{ $key });
}
1  parser/Grammar.pm.skel
View
@@ -41,7 +41,6 @@ $VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
my (@RESERVED, %CMPOP, $LEXTABLE, $RULES, $STATES);
my $factory;
-my $v1compat;
#========================================================================
4 parser/Parser.yp
View
@@ -108,7 +108,6 @@ atomdir: GET expr { $factory->get($_[2]) }
| PROCESS nameargs { $factory->process($_[2]) }
# | PLUGIN nameargs { $factory->plugin($_[2]) }
| THROW nameargs { $factory->throw($_[2]) }
-# | ERROR sterm { $factory->error($_[2]) }
| CLEAR { $factory->clear() }
| BREAK { $factory->break() }
| RETURN { $factory->return() }
@@ -279,8 +278,7 @@ node: item { [ $_[1], 0 ] }
item: IDENT { "'$_[1]'" }
| '${' sterm '}' { $_[2] }
- | '$' IDENT { ($v1compat ||=
- ($_[0]->{ VERSION } == 1))
+ | '$' IDENT { $_[0]->{ V1DOLLAR }
? "'$_[2]'"
: $factory->ident(["'$_[2]'", 0]) }
;
2  t/varsv1.t
View
@@ -81,7 +81,7 @@ my $params = {
# don't define a 'z' - DEFAULT test relies on its non-existance
};
-test_expect(\*DATA, { INTERPOLATE => 1, VERSION => 1 }, $params);
+test_expect(\*DATA, { INTERPOLATE => 1, V1DOLLAR => 1 }, $params);
#------------------------------------------------------------------------
# subs
Please sign in to comment.
Something went wrong with that request. Please try again.