Catalyst-View-Template-Declare

 view release on metacpan or  search on metacpan

lib/Catalyst/View/Template/Declare.pm  view on Meta::CPAN

package Catalyst::View::Template::Declare;
use strict;
use warnings;
use base qw(Catalyst::View::Templated);
use Class::C3;
require Module::Pluggable::Object;

our $VERSION = '0.04';

sub COMPONENT {
    my $self  = shift;
    my $c     = shift;
    my $class = ref $self || $self;

    # find sub-templates
    my $mpo = Module::Pluggable::Object->new(require     => 0,
                                             search_path => $class,
                                            );

    # load sub-templates (and do a bit of magic niceness)
    my @extras = $mpo->plugins;
    foreach my $extra (@extras) {
        $c->log->info("Loading subtemplate $extra");

        # load module
        if (!eval "require $extra"){
            die "Couldn't include $extra: $@";
        }

        # make the templates a subclass of TD (required by TD)
        {
            no strict 'refs';
            push @{$extra. "::ISA"}, 'Template::Declare';
        }

    }

    # init Template::Declare
    Template::Declare->init(roots => [$class, @extras]);

    # init superclasses
    $self->next::method($c, @_);
}

sub _render {
    my ($self, $template) = (shift, shift);

    Template::Declare->new_buffer_frame;
    local *_ = $_[0];
    my $out = Template::Declare->show($template, $self->context, @_);
    Template::Declare->end_buffer_frame;

    $out =~ s/^\n+//g; # kill leading newlines
    return $out;
}

package c;
use PadWalker qw(peek_my);
our $AUTOLOAD;
sub AUTOLOAD {
    shift; # kill class

    # walk up the stack looking for the Catalyst context
    # in a lexical somewhere (evil, yes.)
    my $frames_up = 1;
    my $context;
    while($frames_up < 300 && !$context){
        ($context) =
          map { $$_ }
            grep {eval{$$_->isa('Catalyst')}}
              values %{peek_my($frames_up++)};
    }
    die "INTERNAL ERROR: No Catalyst context found!" if !$context;

    $AUTOLOAD =~ s/^c:://; # kill package c
    return $context->$AUTOLOAD(@_);
}

1;
__END__

=head1 NAME

Catalyst::View::Template::Declare - Use Template::Declare with Catalyst

=head1 VERSION

Version 0.02

=head1 SYNOPSIS

Create the view:

     myapp_create.pl view TD Template::Declare

Add templates in C<< MyApp::View::TD::<name> >>:

     package MyApp::View::TD::Test;
     use Template::Declare::Tags;

     template foo => sub { html {} };
     template bar => sub {   ...   };
     1;

Then use the templates from your application:

     $c->view('TD')->template('foo');
     $c->detach('View::TD');

The Catalyst context is passed as the second agument to the templates:

     template foo => sub {
         my ($self, $c) = @_;
         return 'This is the '. $c->action. ' action.';
     };

The Catalyst stash is passed as the third argument, but is also
available via the glocal C<$_> variable for the duration of the



( run in 1.767 second using v1.01-cache-2.11-cpan-39bf76dae61 )