package Typist::Template::Tags; use strict; use warnings; use Typist::Template::Context qw( pass_tokens_else ); use vars qw( $VERSION ); $VERSION = 0.34; my $PREFIX = Typist->instance->prefix; sub import { Typist::Template::Context->add_tag(SetVar => \&var_handler); Typist::Template::Context->add_tag(GetVar => \&var_handler); Typist::Template::Context->add_container_tag(SetVarBlock => \&var_handler); Typist::Template::Context->add_conditional_tag(If => \&conditional_handler); Typist::Template::Context->add_conditional_tag( Unless => \&conditional_handler); Typist::Template::Context->add_conditional_tag( IfOne => \&conditional_handler); Typist::Template::Context->add_conditional_tag( UnlessEmpty => \&conditional_handler); Typist::Template::Context->add_conditional_tag( UnlessZero => \&conditional_handler); Typist::Template::Context->add_container_tag(Else => \&pass_tokens_else) ; # right thing? Typist::Template::Context->add_container_tag(Include => \&include); Typist::Template::Context->add_container_tag(Ignore => sub { '' }); } sub var_handler { my ($ctx, $args, $cond) = @_; my $tag = $ctx->stash('tag'); return $ctx->error( Typist->translate( "You used a [_1] tag without any arguments.", "<$PREFIX$tag>" ) ) unless keys %$args && $args->{name}; if ($tag eq 'SetVar') { my $val = defined $args->{value} ? $args->{value} : ''; $ctx->var($args->{name}, $val); return ''; } elsif ($tag eq 'GetVar') { my $val = defined $ctx->var($args->{name}) ? $ctx->var($args->{name}) : $args->{default}; return $ctx->error("Uninitialized value in <$tag>.") unless defined $val; return $val; } elsif ($tag eq 'SetVarBlock') { my $builder = $ctx->stash('builder'); my $tokens = $ctx->stash('tokens'); defined(my $out = $builder->build($ctx, $tokens, $cond)) or return $ctx->error($builder->errstr); $ctx->var($args->{name}, $out); return ''; } } sub conditional_handler { my ($ctx, $args, $cond) = @_; my $tag = $ctx->stash('tag'); $ctx->error($PREFIX . "$tag requires a 'name' or 'tag' argument.") if defined $args->{name} || defined $args->{tag}; my $val; if (defined $args->{name}) { $val = $ctx->var($args->{name}) || ''; } else { $args->{tag} =~ s/^$PREFIX//; my $handler = $ctx->handler_for($args->{tag}); $ctx->stash('tag', $args->{tag}); if (defined($handler)) { my $value = $handler->($ctx, {%$args}); if (defined($value) && $value ne '') { # want to include "0" here $val = $ctx->pass_tokens($ctx, $args, $cond); } else { $val = $ctx->pass_tokens_else($ctx, undef, $cond); } } else { $val = $ctx->pass_tokens_else($ctx); } $ctx->unstash('tag'); } if ($tag eq 'Unless') { return !$val; } elsif ($tag eq 'UnlessEmpty') { return $val ne ''; } elsif ($tag eq 'UnlessZero') { return $val != 0; } elsif ($tag eq 'IfOne') { return $val == 1; } else { # If return $val; } } sub include { # file only. option to run through builder??? IncludeModule? my ($arg, $cond) = @_[1, 2]; my $file = $arg->{file}; require File::Spec; my @paths = ($file, map File::Spec::catfile($_, $file), Typist->instance->tmpl_path); my $path; for my $p (@paths) { $path = $p, last if -e $p && -r _; } return $_[0] ->error(Typist->translate("Can't find included file '[_1]'", $path)) unless $path; local *FH; open FH, $path or return $_[0]->error( Typist->translate( "Error opening included file '[_1]': [_2]", $path, $! ) ); my $c = ''; local $/; $c = ; close FH; $c; } 1; =head1 NAME Typist::Template::Tag - Standard template tags plugin =head1 TAGS NOTE: These tags will be prefixed with the value from C in the instance of L. By default this is 'MT' =over =item SetVar =item GetVar =item SetVarBlock =item If =item Unless =item IfOne =item UnlessEmpty =item UnlessZero =item Else =item Include =item Ignore =back =head1 TO DO Add How does this connect up with the stash or vars though? =end