From 3242edb645ffadd56c65b222ce158ebe273ee2ba Mon Sep 17 00:00:00 2001 From: "Jason A. Crome" Date: Sat, 14 Jun 2025 17:46:35 -0400 Subject: [PATCH 1/3] Retire our Template::Tiny fork; use CPAN's We ported the changes from our fork to the official Template::Tiny distribution, eliminating the need for our fork. --- cpanfile | 2 +- .../Template/Implementation/ForkedTiny.pm | 369 ------------------ lib/Dancer2/Template/Tiny.pm | 34 +- t/template_tiny/01_compile.t | 11 - t/template_tiny/02_trivial.t | 34 -- t/template_tiny/03_samples.t | 110 ------ t/template_tiny/04_compat.t | 107 ----- t/template_tiny/05_preparse.t | 69 ---- t/template_tiny/samples/01_hello.tt | 8 - t/template_tiny/samples/01_hello.txt | 6 - t/template_tiny/samples/01_hello.var | 3 - t/template_tiny/samples/02_null.tt | 1 - t/template_tiny/samples/02_null.txt | 1 - t/template_tiny/samples/02_null.var | 3 - t/template_tiny/samples/03_chomp.tt | 16 - t/template_tiny/samples/03_chomp.txt | 12 - t/template_tiny/samples/03_chomp.var | 1 - t/template_tiny/samples/04_nested.tt | 9 - t/template_tiny/samples/04_nested.txt | 9 - t/template_tiny/samples/04_nested.var | 14 - t/template_tiny/samples/05_condition.tt | 14 - t/template_tiny/samples/05_condition.txt | 6 - t/template_tiny/samples/05_condition.var | 4 - t/template_tiny/samples/06_object.tt | 5 - t/template_tiny/samples/06_object.txt | 5 - t/template_tiny/samples/06_object.var | 5 - t/template_tiny/samples/07_nesting.tt | 20 - t/template_tiny/samples/07_nesting.txt | 13 - t/template_tiny/samples/07_nesting.var | 4 - t/template_tiny/samples/08_foreach.tt | 11 - t/template_tiny/samples/08_foreach.txt | 6 - t/template_tiny/samples/08_foreach.var | 15 - t/template_tiny/samples/09_trim.tt | 2 - t/template_tiny/samples/09_trim.txt | 1 - t/template_tiny/samples/09_trim.var | 2 - 35 files changed, 14 insertions(+), 918 deletions(-) delete mode 100644 lib/Dancer2/Template/Implementation/ForkedTiny.pm delete mode 100644 t/template_tiny/01_compile.t delete mode 100644 t/template_tiny/02_trivial.t delete mode 100644 t/template_tiny/03_samples.t delete mode 100644 t/template_tiny/04_compat.t delete mode 100644 t/template_tiny/05_preparse.t delete mode 100644 t/template_tiny/samples/01_hello.tt delete mode 100644 t/template_tiny/samples/01_hello.txt delete mode 100644 t/template_tiny/samples/01_hello.var delete mode 100644 t/template_tiny/samples/02_null.tt delete mode 100644 t/template_tiny/samples/02_null.txt delete mode 100644 t/template_tiny/samples/02_null.var delete mode 100644 t/template_tiny/samples/03_chomp.tt delete mode 100644 t/template_tiny/samples/03_chomp.txt delete mode 100644 t/template_tiny/samples/03_chomp.var delete mode 100644 t/template_tiny/samples/04_nested.tt delete mode 100644 t/template_tiny/samples/04_nested.txt delete mode 100644 t/template_tiny/samples/04_nested.var delete mode 100644 t/template_tiny/samples/05_condition.tt delete mode 100644 t/template_tiny/samples/05_condition.txt delete mode 100644 t/template_tiny/samples/05_condition.var delete mode 100644 t/template_tiny/samples/06_object.tt delete mode 100644 t/template_tiny/samples/06_object.txt delete mode 100644 t/template_tiny/samples/06_object.var delete mode 100644 t/template_tiny/samples/07_nesting.tt delete mode 100644 t/template_tiny/samples/07_nesting.txt delete mode 100644 t/template_tiny/samples/07_nesting.var delete mode 100644 t/template_tiny/samples/08_foreach.tt delete mode 100644 t/template_tiny/samples/08_foreach.txt delete mode 100644 t/template_tiny/samples/08_foreach.var delete mode 100644 t/template_tiny/samples/09_trim.tt delete mode 100644 t/template_tiny/samples/09_trim.txt delete mode 100644 t/template_tiny/samples/09_trim.var diff --git a/cpanfile b/cpanfile index 6638c4e2c..852c469f9 100644 --- a/cpanfile +++ b/cpanfile @@ -35,7 +35,7 @@ requires 'Ref::Util'; requires 'Safe::Isa'; requires 'Sub::Quote'; requires 'Template'; -requires 'Template::Tiny'; +requires 'Template::Tiny', '1.16'; requires 'Test::Builder'; requires 'Test::More'; requires 'Types::Standard'; diff --git a/lib/Dancer2/Template/Implementation/ForkedTiny.pm b/lib/Dancer2/Template/Implementation/ForkedTiny.pm deleted file mode 100644 index 6347a90da..000000000 --- a/lib/Dancer2/Template/Implementation/ForkedTiny.pm +++ /dev/null @@ -1,369 +0,0 @@ -package Dancer2::Template::Implementation::ForkedTiny; - -# ABSTRACT: Dancer2 own implementation of Template::Tiny - -use 5.00503; -use strict; -no warnings; -use Ref::Util qw; - -# Evaluatable expression -my $EXPR = qr/ [a-z_][\w.]* /xs; - -sub new { - my $self = bless { - start_tag => '[%', - end_tag => '%]', - @_[ 1 .. $#_ ] - }, - $_[0]; - -# Opening tag including whitespace chomping rules - my $LEFT = $self->{LEFT} = qr/ - (?: - (?: (?:^|\n) [ \t]* )? \Q$self->{start_tag}\E\- - | - \Q$self->{start_tag}\E \+? - ) \s* -/xs; - -# Closing %] tag including whitespace chomping rules - my $RIGHT = $self->{RIGHT} = qr/ - \s* (?: - \+? \Q$self->{end_tag}\E - | - \-\Q$self->{end_tag}\E (?: [ \t]* \n )? - ) -/xs; - -# Preparsing run for nesting tags - $self->{PREPARSE} = qr/ - $LEFT ( IF | UNLESS | FOREACH ) \s+ - ( - (?: \S+ \s+ IN \s+ )? - \S+ ) - $RIGHT - (?! - .*? - $LEFT (?: IF | UNLESS | FOREACH ) \b - ) - ( .*? ) - (?: - $LEFT ELSE $RIGHT - (?! - .*? - $LEFT (?: IF | UNLESS | FOREACH ) \b - ) - ( .+? ) - )? - $LEFT END $RIGHT -/xs; - - $self->{CONDITION} = qr/ - \Q$self->{start_tag}\E\s - ( ([IUF])\d+ ) \s+ - (?: - ([a-z]\w*) \s+ IN \s+ - )? - ( $EXPR ) - \s\Q$self->{end_tag}\E - ( .*? ) - (?: - \Q$self->{start_tag}\E\s \1 \s\Q$self->{end_tag}\E - ( .+? ) - )? - \Q$self->{start_tag}\E\s \1 \s\Q$self->{end_tag}\E -/xs; - - $self; -} - -# Copy and modify -sub preprocess { - my $self = shift; - my $text = shift; - $self->_preprocess( \$text ); - return $text; -} - -sub process { - my $self = shift; - my $copy = ${ shift() }; - my $stash = shift || {}; - - local $@ = ''; - local $^W = 0; - - # Preprocess to establish unique matching tag sets - $self->_preprocess( \$copy ); - - # Process down the nested tree of conditions - my $result = $self->_process( $stash, $copy ); - if (@_) { - ${ $_[0] } = $result; - } - elsif ( defined wantarray ) { - require Carp; - Carp::carp( - 'Returning of template results is deprecated in Template::Tiny 0.11' - ); - return $result; - } - else { - print $result; - } -} - - -###################################################################### -# Support Methods - -# The only reason this is a standalone is so we can -# do more in-depth testing. -sub _preprocess { - my $self = shift; - my $copy = shift; - - # Preprocess to establish unique matching tag sets - my $id = 0; - 1 while $$copy =~ s/ - $self->{PREPARSE} - / - my $tag = substr($1, 0, 1) . ++$id; - "\[\% $tag $2 \%\]$3\[\% $tag \%\]" - . (defined($4) ? "$4\[\% $tag \%\]" : ''); - /sex; -} - -sub _process { - my ( $self, $stash, $text ) = @_; - - $text =~ s/ - $self->{CONDITION} - / - ($2 eq 'F') - ? $self->_foreach($stash, $3, $4, $5) - : eval { - $2 eq 'U' - xor - !! # Force boolification - $self->_expression($stash, $4) - } - ? $self->_process($stash, $5) - : $self->_process($stash, $6) - /gsex; - - # Resolve expressions - $text =~ s/ - $self->{LEFT} ( $EXPR ) $self->{RIGHT} - / - eval { - $self->_expression($stash, $1) - . '' # Force stringification - } - /gsex; - - # Trim the document - $text =~ s/^\s*(.+?)\s*\z/$1/s if $self->{TRIM}; - - return $text; -} - -# Special handling for foreach -sub _foreach { - my ( $self, $stash, $term, $expr, $text ) = @_; - - # Resolve the expression - my $list = $self->_expression( $stash, $expr ); - is_arrayref($list) or return ''; - - # Iterate - return join '', - map { $self->_process( { %$stash, $term => $_ }, $text ) } @$list; -} - -# Evaluates a stash expression -sub _expression { - my $cursor = $_[1]; - my @path = split /\./, $_[2]; - foreach (@path) { - - # Support for private keys - return if substr( $_, 0, 1 ) eq '_'; - - # Split by data type - ref $cursor or return ''; - if ( is_arrayref($cursor) ) { - return '' unless /^(?:0|[0-9]\d*)\z/; - $cursor = $cursor->[$_]; - } - elsif ( is_plain_hashref($cursor) ) { - $cursor = $cursor->{$_}; - } - else { - $cursor = $cursor->$_(); - } - } - - # If the last expression is a CodeRef, execute it - is_coderef($cursor) - and $cursor = $cursor->(); - return $cursor; -} - -1; - -__END__ - -=pod - -=head1 NAME - -Dancer2::Template::Implementation::ForkedTiny - Template Toolkit reimplemented in as little code as possible, forked from Template::Tiny - -=head1 SYNOPSIS - - my $template = Dancer2::Template::Implementation::ForkedTiny->new( - TRIM => 1, - ); - - # Print the template results to STDOUT - $template->process( <<'END_TEMPLATE', { foo => 'World' } ); - Hello [% foo %]! - END_TEMPLATE - -=head1 DESCRIPTION - -B is a reimplementation of a subset of the functionality from -L