Re: [Templates] TT and PHP
[prev]
[thread]
[next]
[Date index for 2005/02/25]
--0IvGJv3f9h+YhkrH
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
[reposted - not CC'd to the list first time around]
Denis Banovic wrote:
> Yes, that's correct, I'm looking for a way to convert (some parts of )
> TT ( eg. [ FOREACH and IF ] ) to PHP. Our PHP templates are very similar
> to TT-Templates,
One approach is to subclass Template::Directive (the part of TT that
generates compiled Perl code from the source template) and intercept
the various methods that generate the foreach, if, and other directives.
In the usual case, the methods generate Perl code to implements the foreach,
if, etc. e.g.
# template # regular compiled Perl code
[% IF x %]... => if ($stash->get('x')) { ...
You would instead need to generate Perl code that when run, emits the PHP
equivalent of the original directive.
# template # output PHP directive
[% IF x %]... => $output .= '<? if ($x) { ?>...';
The end result is that you process your TT templates, and you get PHP
templates generated as the output.
There is a Template::Directive::PHP module attached which I just knocked
up to test this idea. Be warned that it is a proof of concept only and
will almost certainly break when you feed it other TT directives. However
it may be useful as a starting point if you decide that's a good way to go.
The difficulty is that in TT2 there isn't a clear separation between the
parser and back end directive generator (yet another weakness that I've
been trying to address in TT3). You need to become intimately familiar
with the workings and output generated by both the parser and current
Template::Directives methods, and it's not something to be taken lightly.
I suspect there may be several things that are hard, if not impossible to
do correctly without hacking on the parser grammar itself, and therein
lies dragons!
So if you're not already totally confused by the examples above, you soon
will be once you start delving deeper :-)
Anyway, here's an example of my quick hack in use:
use strict;
use warnings;
use Template;
use Template::Parser;
use Template::Directive::PHP;
# -d flag enables debugging output
if (grep(/^-d/, @ARGV)) {
$Template::Parser::DEBUG = 1;
$Template::Directive::PRETTY = 1;
}
my $tt = Template->new( FACTORY => 'Template::Directive::PHP' )
|| die Template->error();
$tt->process(\*DATA)
|| die $tt->error();
__DATA__
This is a test template
[% IF x < 10 %]
do this
[% ELSIF y < 20 %]
do this instead
[% ELSE %]
don't do anything at all
[% END %]
[% z %]
[% FOREACH y IN z %]
y is [% y %]
[% END %]
And this is the output:
This is a test template
<? if ($x < 10) { ?>
do this
<? } elsif ($y < 20) { ?>
do this instead
<? } else { ?>
don't do anything at all
<? } ?>
<? $z ?>
<? foreach ($z as $y) { ?>
y is <? $y ?>
<? } ?>
Cheers
A
--0IvGJv3f9h+YhkrH
Content-Type: application/x-perl
Content-Disposition: attachment; filename="PHP.pm"
Content-Transfer-Encoding: quoted-printable
package Template::Directive::PHP;=0A=0Ause strict;=0Ause Template::Directiv=
e;=0Ause base 'Template::Directive';=0A=0Aour $OUTPUT =3D '$output .=3D ';=
=0A=0A=0Asub php_tag {=0A my $php =3D shift;=0A return "$OUTPUT '<? $=
php ?>';";=0A}=0A=0Asub php_block {=0A my ($php, $block) =3D @_;=0A r=
eturn php_tag($php) . "\n" . $block . "\n";=0A}=0A=0A=0A#------------------=
------------------------------------------------------=0A# ident(\@ident)=
=0A#-----------------------------------------------------------------------=
-=0A=0Asub ident {=0A my ($class, $ident) =3D @_;=0A return "''" unle=
ss @$ident;=0A my @names;=0A=0A while (@$ident) {=0A my $name =
=3D shift @$ident;=0A my $args =3D shift @$ident;=0A=0A # rem=
ove single quotes added by parser =0A for ($name) {=0A s/=
^'//;=0A s/'$//;=0A }=0A push(@names, $name);=0A =
}=0A return '$' . join('.', @names);=0A=0A}=0A =0A#----------------------=
--------------------------------------------------=0A# get($expr)=0A#------=
------------------------------------------------------------------=0A=0Asub=
get {=0A my ($class, $expr) =3D @_; =0A return php_tag($expr);=0A}=
=0A=0A#--------------------------------------------------------------------=
----=0A# if($expr, $block, $else)=0A#--------------------------------------=
----------------------------------=0A=0Asub if {=0A my ($class, $expr, $=
block, $else) =3D @_;=0A my @else =3D $else ? @$else : ();=0A $else =
=3D pop @else;=0A=0A my $output =3D php_block("if ($expr) {", $block);=
=0A=0A foreach my $elsif (@else) {=0A ($expr, $block) =3D @$elsif=
;=0A $output .=3D php_block("} elsif ($expr) {", $block);=0A }=0A=
if (defined $else) {=0A $output .=3D php_block("} else {", $else=
);=0A }=0A=0A $output .=3D php_tag('}');=0A=0A return $output;=0A}=
=0A=0A#--------------------------------------------------------------------=
----=0A# foreach($target, $list, $args, $block)=0A#------------------------=
------------------------------------------------=0A=0Asub foreach {=0A m=
y ($class, $target, $list, $args, $block) =3D @_;=0A my $output =3D php_=
block("foreach ($list as \$$target) {", $block);=0A $output .=3D php_tag=
('}');=0A return $output;=0A}=0A=0A1;=0A=0A__END__=0A=0A
--0IvGJv3f9h+YhkrH--
_______________________________________________
templates mailing list
templates@xxxxxxxxxxxxxxxx.xxx
http://lists.template-toolkit.org/mailman/listinfo/templates