You are viewing a plain text version of this content. The canonical link for it is here.
Posted to embperl@perl.apache.org by Konrad Eisele <ei...@gmx.de> on 2008/06/21 22:10:54 UTC

Simple template library

Hi,
Searching for template libraries I found some examples in the net. When 
thinking about it I came up with a own version that I'd
like to post here. It seems to me that it is the simples, and stil most powerful version
how to handle templates.

Instead of creating a own language on top of perl my version is a transformation
into perl. Creating a function that is then evaled into the current namespace. The template
creating is therefore a simple function call. The syntax elements are :

{* ... perl code *}  => copy as is
[* ... perl subblock *}  => $out .= &{sub {... }}();
{* ... perl forloop start *-}  ...  {-* ... forloop end  ... *} => transformed into a loop (real code yourself)

All other parts are transformed into a $out .= "..."; At the end $out is the functions return.

I'd like to ask: isnt everything else too much. All the library overhead you get
with all the different template libraries. 

-- Greetings Konrad


--------------- template.pl ----------------

$RE_template_b_squarebrackets =    qr'(?:[\[]((?:(?>[^\[\]]+)|(??{$RE_template_b_squarebrackets}))*)[\]])';
$RE_template_balanced_squarebrackets =    qr'(?:\[\*((?:(?>(?:(?:(?!\[\*)(?!\*\])[\s\S]))+)|(??{$RE_template_balanced_squarebrackets}))*)\*\])';
$RE_template_balanced_brackets       =    qr'(?:\{\*((?:(?>(?:(?:(?!\{\*)(?!\*\})[\s\S]))+)|(??{$RE_template_balanced_brackets}))*)\*\})';
$RE_template_balanced_brackets_inner =    qr'(?:\*-\}((?:(?>(?:(?:(?!\{-\*)(?!\*-\})[\s\S]))+)|(??{$RE_template_balanced_brackets_inner}))*)\{-\*)';

 $a = "x
      {
      {* my \@a = (1,2,3);
            foreach my \$a (\@a) {  *-}  y [* \$a *]  {-*  }  *}
      }
 ";

 print (convert_template('::func',$a));
 eval(convert_template('::func',$a));
 print $@ if ($@);

 print "'".func()."'";



sub convert_template {
    my ($n,$a) = @_;
    my $c = "";
    while(length($a)) {
        if ($a =~ /^$RE_template_balanced_squarebrackets/s ) {
            my ($all,$b) = ($&,$1);
            print ("Found '$all'\n");
            $a = substr($a,length($all));
            $c .= "\$out .= &{sub { $b }}();\n";
        } elsif ($a =~ /^$RE_template_balanced_brackets/s ) {
            my ($all,$b) = ($&,$1);
            print ("Found '$all'\n");
            $a = substr($a,length($all));
            if ($b =~ /$RE_template_balanced_brackets_inner/) {
                my ($pre,$b2,$post) = ($`,$1,substr($b,length($`.$&)));
                $c .= "my \@_a = (); $pre";
                $c .= "push(\@_a,&{".convert_template('',$b2)."}(\@_));\n";
                $c .= $post;
                $c .= "\$out .= join_template(\$out,\@_a);\n";
                $a =~ s/^\s*\n//;
            } else {
                $c .= $b;
            }
        } elsif ($a =~ /^.+?(?=\{\*|\[\*|$)/s)  {
            my ($all,$b) = ($&,$1);
            print ("Found '$all'\n");
            $a = substr($a,length($all));
            $c .= "\$out .= \"$all\";\n";
        } else {
            die("Cant decode '$a'");
        }
    }
    return "sub $n { my (\$out,\$self) = ('',\@_); $c; return \$out; }";
}

sub join_template {
    my ($out,@a) = @_;
    my $post = 0;
    $post = length($1) if ($out =~ /([^\n]*)$/);
    $pre = sprintf('%*s',$post,"");
    my $c = join("\n", map { $_=~ s/^\s*\n//; $_=~ s/\s*\n\s*$//; $_ } @a);
    $c .= "\n" if (scalar(@a));
    return $c;
}
-- 
Ist Ihr Browser Vista-kompatibel? Jetzt die neuesten 
Browser-Versionen downloaden: http://www.gmx.net/de/go/browser

---------------------------------------------------------------------
To unsubscribe, e-mail: embperl-unsubscribe@perl.apache.org
For additional commands, e-mail: embperl-help@perl.apache.org