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@40 d5a88997-0a34-4036-9ed2-92fb5d660d91
  • Loading branch information...
commit 8a49dc518ff74b687542128257be0c5defcf5ea3 1 parent aab04dd
@abw authored
View
22 Changes
@@ -13,6 +13,27 @@
#========================================================================
#------------------------------------------------------------------------
+# Version 2.00 beta 4
+#------------------------------------------------------------------------
+
+* Fixed an obscure bug in the Template::Stash which was ignoring the
+ last element in a compound variable when followed by an empty
+ argument list. e.g. [% cgi.param() %] would be treated as [% cgi %].
+ Thanks to Jonas Liljegren for reporting the problem.
+
+* Changes parser to automatically unescape any escaped characters in
+ double quoted strings except for \n and \$. This permits strings to
+ be constructed that include tag characters. e.g.
+
+ [% directive = "[\% INSERT thing %\]" %]
+
+* Added $Template::Test::PRESERVE package variable which can be set to
+ prevent newlines in test output from being automatically mangled to
+ literal '\n'.
+
+* Fixed various documentation problems, e.g. OUTPUT_PATH
+
+#------------------------------------------------------------------------
# Version 2.00 beta 3 10th August 2000
#------------------------------------------------------------------------
@@ -899,5 +920,6 @@ out.
* $Template::Directive::While::MAXITER is now
$Template::Directive::WHILE_MAX and may change again.
+* into() filter is obsolete, replaced by ***TODO***
View
9 TODO
@@ -2,6 +2,15 @@
# KNOWN BUGS AND/OR LIMITATIONS
#------------------------------------------------------------------------
+* fix end of Changes (gotchas)
+
+* references are required!
+
+* empty hashes cause parser error.
+
+* complex filenames don't all intermediates paths constructed
+ use File::Basename on $compiled in _compile()
+
* The .pod form of the documentation doesn't get installed properly
because it lives in docs/pod instead of lib. The man pages should
get built and installed OK, which is fine as long as you have 'man'
View
2  lib/Template/Directive.pm
@@ -208,7 +208,7 @@ sub args {
push(@$args, '{ ' . join(', ', @$hash) . ' }')
if @$hash;
- return '' unless @$args;
+ return '0' unless @$args;
return '[ ' . join(', ', @$args) . ' ]';
}
View
3  lib/Template/Parser.pm
@@ -413,7 +413,8 @@ sub tokenise_directive {
# unescape " and \ but leave \$ escaped so that
# interpolate_text() doesn't incorrectly treat it
# as a variable reference
- $token =~ s/\\([\\"])/$1/g;
+# $token =~ s/\\([\\"])/$1/g;
+ $token =~ s/\\([^\$n])/$1/g;
$token =~ s/\\n/\n/g;
push(@tokens, ('"') x 2,
@{ $self->interpolate_text($token) },
View
15 lib/Template/Stash.pm
@@ -187,21 +187,20 @@ sub get {
my ($root, $result);
$root = $self;
- if (ref $ident) {
+ if (ref $ident eq 'ARRAY') {
my $size = $#$ident;
# if $ident is a list reference, then we evaluate each item in the
# identifier against the previous result, using the root stash
# ($self) as the first implicit 'result'...
- foreach (my $i = 0; $i < $size; $i += 2) {
+ foreach (my $i = 0; $i <= $size; $i += 2) {
$result = $self->_dotop($root, @$ident[$i, $i+1]);
last unless defined $result;
$root = $result;
}
}
else {
- # ...otherwise, $ident is a string and we can call _dotop() once
$result = $self->_dotop($root, $ident, $args);
}
@@ -231,7 +230,7 @@ sub set {
$root = $self;
ELEMENT: {
- if (ref $ident) {
+ if (ref $ident eq 'ARRAY') {
# a compound identifier may contain multiple elements (e.g.
# foo.bar.baz) and we must first resolve all but the last,
# using _dotop() with the $lvalue flag set which will create
@@ -248,7 +247,6 @@ sub set {
$value, $default);
}
else {
- # if $ident is a simple variable name then we just call _assign()
$result = $self->_assign($root, $ident, 0, $value, $default);
}
}
@@ -305,8 +303,8 @@ sub _dotop {
$args ||= [ ];
$lvalue ||= 0;
-# print STDERR "_dotop(root=$root, item=$item, args=[@$args])\n"
-# if $DEBUG;
+ print STDERR "_dotop(root=$root, item=$item, args=[@$args])\n"
+ if $DEBUG;
# return undef without an error if either side of the dot is unviable
# or if an attempt is made to access a private member, starting _ or .
@@ -365,9 +363,8 @@ sub _dotop {
# UNIVERSAL object base class) then we call the item as a method.
# If that fails then we try to fallback on HASH behaviour if
# possible.
-
eval { @result = $root->$item(@$args); };
-
+
if ($@ && UNIVERSAL::isa($root, 'HASH')
&& defined($value = $root->{ $item })) {
return $value unless ref $value eq 'CODE'; ## RETURN
View
14 lib/Template/Test.pm
@@ -29,7 +29,7 @@ package Template::Test;
require 5.004;
use strict;
-use vars qw( @ISA @EXPORT $VERSION $DEBUG $EXTRA $loaded %callsign);
+use vars qw( @ISA @EXPORT $VERSION $DEBUG $EXTRA $PRESERVE $loaded %callsign);
use Template qw( :template );
use Exporter;
@@ -39,7 +39,9 @@ $DEBUG = 0;
@EXPORT = qw( ntests ok flush test_expect callsign banner );
$| = 1;
-$EXTRA = 0; # any extra tests to come after test_expect()
+$EXTRA = 0; # any extra tests to come after test_expect()
+$PRESERVE = 0 # don't mangle newlines in output/expect
+ unless defined $PRESERVE;
my @results = ();
my ($ntests, $ok_count);
@@ -261,9 +263,11 @@ sub test_expect {
unless $match;
my ($copyi, $copye, $copyo) = ($input, $expect, $output);
- foreach ($copyi, $copye, $copyo) {
- s/\n/\\n/g;
- };
+ unless ($PRESERVE) {
+ foreach ($copyi, $copye, $copyo) {
+ s/\n/\\n/g;
+ }
+ }
printf(" input: [%s]\nexpect: [%s]\noutput: [%s]\n",
$copyi, $copye, $copyo);
}
View
54 t/cgi.t
@@ -22,7 +22,9 @@ use Template;
use Template::Test;
$^W = 1;
-#$Template::Parser::DEBUG = 0;
+#$Template::Parser::DEBUG = 1;
+#$Template::Parser::PRETTY = 1;
+#$Template::Stash::DEBUG = 1;
eval "use CGI";
if ($@) {
@@ -30,27 +32,55 @@ if ($@) {
exit(0);
}
-test_expect(\*DATA);
+my $cgi = CGI->new('');
+$cgi = join("\n", $cgi->checkbox_group(
+ -name => 'words',
+ -values => [ 'eenie', 'meenie', 'minie', 'moe' ],
+ -defaults => [ 'eenie', 'meenie' ],
+));
+
+
+test_expect(\*DATA, undef, { cgicheck => $cgi });
__END__
-- test --
-[% USE cgi = CGI('id=abw&name=Andy+Wardley') -%]
-name: [% cgi.param('name') %]
+[% USE cgi = CGI('id=abw&name=Andy+Wardley'); global.cgi = cgi -%]
+name: [% global.cgi.param('name') %]
+-- expect --
+name: Andy Wardley
+
+-- test --
+name: [% global.cgi.param('name') %]
+
+-- expect --
+name: Andy Wardley
+
+-- test --
+[% FOREACH key = global.cgi.param.sort -%]
+ * [% key %] : [% global.cgi.param(key) %]
+[% END %]
+-- expect --
+ * id : abw
+ * name : Andy Wardley
+
+-- test --
+[% FOREACH key = global.cgi.param().sort -%]
+ * [% key %] : [% global.cgi.param(key) %]
+[% END %]
+-- expect --
+ * id : abw
+ * name : Andy Wardley
-[% FOREACH x = cgi.checkbox_group(
+-- test --
+[% FOREACH x = global.cgi.checkbox_group(
name => 'words'
values => [ 'eenie', 'meenie', 'minie', 'moe' ]
defaults => [ 'eenie', 'meenie' ] ) -%]
[% x %]
[% END %]
-name: [% cgi.param('name') %]
-- expect --
-name: Andy Wardley
+-- process --
+[% cgicheck %]
-<INPUT TYPE="checkbox" NAME="words" VALUE="eenie" CHECKED>eenie
-<INPUT TYPE="checkbox" NAME="words" VALUE="meenie" CHECKED>meenie
-<INPUT TYPE="checkbox" NAME="words" VALUE="minie">minie
-<INPUT TYPE="checkbox" NAME="words" VALUE="moe">moe
-name: Andy Wardley
View
16 t/filter.t
@@ -514,6 +514,22 @@ FILTER [[% dir | eval %]]
[% a %] blah blah [% b %]
FILTER [alpha blah blah bravo]
+-- start --
+-- test --
+[% TRY %]
+[% dir = "[\% FOREACH a = { 1 2 3 } %\]a: [\% a %\]\n[\% END %\]" %]
+[% dir | eval %]
+[% CATCH %]
+error: [[% error.type %]] [[% error.info %]]
+[% END %]
+-- expect --
+a: 1
+a: 2
+a: 3
+
+-- stop --
+
+
-- test --
nothing
[% TRY;
View
4 t/include.t
@@ -59,13 +59,15 @@ my $tproc = Template->new({
DEFAULT => 'default',
});
+my $incpath = [ "$dir/src", '/nowhere' ];
my $tt_reset = Template->new({
INTERPOLATE => 1,
- INCLUDE_PATH => "$dir/src:$dir/lib",
+ INCLUDE_PATH => $incpath,
TRIM => 1,
RECURSION => 1,
DEFAULT => 'bad_default',
});
+$incpath->[1] = "$dir/lib";
# we want to process 'metadata' directly so that the correct top-level
# 'template' reference is set instead of 'input text'
View
51 t/parser.t
@@ -24,7 +24,10 @@ use Template::Parser;
$^W = 1;
#$Template::Test::DEBUG = 0;
-#$Template::Parser::DEBUG = 0;
+#$Template::Test::PRESERVE = 0;
+$Template::Stash::DEBUG = 1;
+$Template::Parser::DEBUG = 1;
+$Template::Parser::PRETTY = 1;
my $p2 = Template::Parser->new({
START_TAG => '\[\*',
@@ -50,7 +53,10 @@ my $tt = [
tt4 => Template->new(PARSER => $p4),
];
-test_expect(\*DATA, $tt, &callsign());
+my $replace = &callsign;
+$replace->{ alist } = [ 'foo', 0, 'bar', 0 ];
+
+test_expect(\*DATA, $tt, $replace);
__DATA__
#------------------------------------------------------------------------
@@ -156,3 +162,44 @@ SQL: [% sql %]
SQL:
SELECT *
FROM table
+
+-- test --
+[% a = "\a\b\c\ndef" -%]
+a: [% a %]
+-- expect --
+a: abc
+def
+
+-- test --
+[% a = "\f\o\o"
+ b = "a is '$a'"
+ c = "b is \$100"
+-%]
+a: [% a %] b: [% b %] c: [% c %]
+
+-- expect --
+a: foo b: a is 'foo' c: b is $100
+
+-- test --
+[% tag = {
+ a => "[\%"
+ z => "%\]"
+ }
+ quoted = "[\% INSERT foo %\]"
+-%]
+A directive looks like: [% tag.a %] INCLUDE foo [% tag.z %]
+The quoted value is [% quoted %]
+
+-- expect --
+A directive looks like: [% INCLUDE foo %]
+The quoted value is [% INSERT foo %]
+
+-- start --
+
+-- test --
+alist: [% $alist %]
+-- expect --
+alist: ??
+
+-- test --
+[% foo.bar.baz %]
Please sign in to comment.
Something went wrong with that request. Please try again.