[Templates-cvs] cvs commit: TT3/lib/Template Compilers.pm

cvs@template-toolkit.org cvs@template-toolkit.org
Fri, 26 Mar 2004 10:53:56 +0000


cvs         04/03/26 10:53:56

  Added:       lib/Template Compilers.pm
  Log:
  * added Template::Compilers module for loading compilers
  
  Revision  Changes    Path
  1.1                  TT3/lib/Template/Compilers.pm
  
  Index: Compilers.pm
  ===================================================================
  #========================================================================
  #
  # Template::Compilers
  #
  # DESCRIPTION
  #   Factory module for loading and instantiating compilers on demand.
  # 
  # AUTHOR
  #   Andy Wardley <abw@wardley.org>
  #
  # COPYRIGHT
  #   Copyright (C) 1996-2004 Andy Wardley.  All Rights Reserved.
  #   Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
  #   Copyright (C) 2004 Fotango Ltd.
  #
  #   This module is free software; you can redistribute it and/or
  #   modify it under the same terms as Perl itself.
  #
  # REVISION
  #   $Id: Compilers.pm,v 1.1 2004/03/26 10:53:56 abw Exp $
  #
  #========================================================================
  
  package Template::Compilers;
  
  use strict;
  use warnings;
  use Template::Utils;
  use Template::Base;
  use base qw( Template::Base );
  use vars qw( $VERSION $DEBUG $ERROR $THROW $UTILS $COMPILERS );
  
  $VERSION   = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
  $DEBUG     = 0 unless defined $DEBUG;
  $ERROR     = '';
  $THROW     = 'compiler';
  $UTILS     = 'Template::Utils';
  $COMPILERS = {
      tt2     => 'Template::TT2::Compiler',
      tt3     => 'Template::Compiler',
      default => 'Template::TT2::Compiler',
  };
  
  
  sub init {
      my ($self, $config) = @_;
      my $class = ref $self || $self;
  
      # merge $COMPILERS class hash with config
      my $classcomp = do {
          no strict 'refs';
          ${"$class\::COMPILERS"} || { };
      };
      $self->{ compilers } = {
          %$classcomp, 
          %$config,
      };
      $self->{ loaded  } = { };
  
      return $self;
  }
  
  
  sub get {
      my ($self, $name) = (shift, shift);
  
      $self->debug("get($name)\n") if ref $self ? $self->{ DEBUG } : $DEBUG;
  
      my $compilers = ref $self ? $self->{ compilers } : do {
          no strict 'refs';
          ${"$self\::COMPILERS"} || { };
      };
      my $compiler = $compilers->{ $name }
          || return $self->decline("$name compiler not found");
  
      # looks like we've already got a compiler object
      return $compiler
          if ref($compiler) && UNIVERSAL::can($compiler, 'compile');
  
      # load module
      $UTILS->load_module($compiler) 
          || return $self->error($UTILS->error())
              unless ref $self && $self->{ loaded }->{ $compiler }++;
  
      # otherwise it's a class name
      return $compiler->new(@_)
          || $self->error($compiler->error());
  }
  
  
  1;
  
  __END__
  
  =head1 NAME
  
  Template::Compilers - factory for creating template compiler modules
  
  =head1 SYNOPSIS
  
      use Template::Compilers;
  
      # class method
      my $tt2c = Template::Compilers->get('tt2')
          || die Template::Compilers->error();
  
      # passing arguments
      my $tt2c = Template::Compilers->get('tt2' => { generator => $gen })
          || die Template::Compilers->error();
  
      # object method
      my $comps = Template::Compilers->new();
      my $tt3c  = $comps->get('tt3');
      my $tt3c  = $comps->get('tt3' => { generator => $gen });
  
      # defining custom compilers
      my $comps = Template::Compilers->new({
          tt4 => 'Template::TT4::Compiler',
      });
      my $tt4c  = $comps->get('tt4');
      my $tt4c  = $comps->get('tt4' => { generator => $gen });
      
  
  =head1 DESCRIPTION
  
  This module implements a factory for loading Template::Compiler modules
  and instantiating them.  It can be added to a Template::Component as a
  C<compilers> item, either by class name or object reference.  This first
  example shows the use of the Template::Compilers class name.
  
      use Template::Compilers;
  
      my $component = Template::Componet->new({
          compilers => 'Template::Compilers',
      });
  
  When we subsequently ask the component for a particular compiler, the
  Template::Compilers module will load it and instantiate an object for us.
  
      my $tt3comp = $component->compiler('tt3')
          || die $component->error();
  
  Any additional arguments passed are forwarded to the compiler's new()
  constructor method.
  
      my $tt3comp = $component->compiler('tt3', generator => $mygen)
          || die $component->error();
  
  The next example shows how a Template::Compilers object is used.  This
  approach allows us to define any additional compilers that we might
  want to use.
  
      my $compilers = Template::Compilers->new({
          # override default tt3 compiler
          tt3 = 'My::Own::Template::TT3::Compiler',
          # add new tt4 compiler
          tt4 = 'Template::TT4::Compiler',
      });
  
      my $component = Template::Component->new({
          compilers => $compilers,
      });
  
      my $tt3comp = $componet->compiler('tt3')
          || die $component->error();
  
      my $tt4comp = $componet->compiler('tt4')
          || die $component->error();
  
  New compilers can also be defined as existing objects.
  
      use Template::TT4::Compiler;   # no it doesn't exist... yet!
  
      my $tt4 = Template::TT4::Compiler->new();
  
      my $compilers = Template::Compilers->new({
          tt4 = $tt4,
      });
  
  In this case, the same compiler object is returned each time.
  
  =head1 AUTHOR
  
  Andy Wardley  E<lt>abw@wardley.orgE<gt>
  
  =head1 VERSION
  
  $Revision: 1.1 $
  
  =head1 COPYRIGHT
  
    Copyright (C) 1996-2004 Andy Wardley.  All Rights Reserved.
    Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
    Copyright (C) 2004 Fotango Ltd.
  
  This module is free software; you can redistribute it and/or
  modify it under the same terms as Perl itself.
  
  =cut
  
  # Local Variables:
  # mode: perl
  # perl-indent-level: 4
  # indent-tabs-mode: nil
  # End:
  #
  # vim: expandtab shiftwidth=4: