[Templates-cvs] cvs commit: Template2/lib/Template Plugins.pm

cvs@template-toolkit.org cvs@template-toolkit.org


cvs         06/01/30 09:57:29

  Modified:    lib/Template Plugins.pm
  Log:
  * applied a variation of Josh's patch to make standard plugin names case
    insensitive and to provide a way to prevent Template::Plugin from being
    added to the TEMPLATE_BASE
  
  Revision  Changes    Path
  2.72      +99 -274   Template2/lib/Template/Plugins.pm
  
  Index: Plugins.pm
  ===================================================================
  RCS file: /template-toolkit/Template2/lib/Template/Plugins.pm,v
  retrieving revision 2.71
  retrieving revision 2.72
  diff -u -r2.71 -r2.72
  --- Plugins.pm	2004/01/30 19:32:28	2.71
  +++ Plugins.pm	2006/01/30 09:57:28	2.72
  @@ -18,22 +18,21 @@
   #
   #----------------------------------------------------------------------------
   #
  -# $Id: Plugins.pm,v 2.71 2004/01/30 19:32:28 abw Exp $
  +# $Id: Plugins.pm,v 2.72 2006/01/30 09:57:28 abw Exp $
   #
   #============================================================================
   
   package Template::Plugins;
   
  -require 5.004;
  -
   use strict;
  -use base qw( Template::Base );
  -use vars qw( $VERSION $DEBUG $STD_PLUGINS );
  +use warnings;
  +use base 'Template::Base';
   use Template::Constants;
  -
  -$VERSION = sprintf("%d.%02d", q$Revision: 2.71 $ =~ /(\d+)\.(\d+)/);
   
  -$STD_PLUGINS   = {
  +our $VERSION = sprintf("%d.%02d", q$Revision: 2.72 $ =~ /(\d+)\.(\d+)/);
  +our $DEBUG   = 0 unless defined $DEBUG;
  +our $PLUGIN_BASE = 'Template::Plugin';
  +our $STD_PLUGINS = {
       'autoformat' => 'Template::Plugin::Autoformat',
       'cgi'        => 'Template::Plugin::CGI',
       'datafile'   => 'Template::Plugin::Datafile',
  @@ -104,25 +103,25 @@
       unshift @$args, $context;
   
       $factory = $self->{ FACTORY }->{ $name } ||= do {
  -	($factory, $error) = $self->_load($name, $context);
  -	return ($factory, $error) if $error;			## RETURN
  -	$factory;
  +        ($factory, $error) = $self->_load($name, $context);
  +        return ($factory, $error) if $error;			## RETURN
  +        $factory;
       };
   
       # call the new() method on the factory object or class name
       eval {
  -	if (ref $factory eq 'CODE') {
  -	    defined( $plugin = &$factory(@$args) )
  -		|| die "$name plugin failed\n";
  -	}
  -	else {
  -	    defined( $plugin = $factory->new(@$args) )
  -		|| die "$name plugin failed: ", $factory->error(), "\n";
  -	}
  +        if (ref $factory eq 'CODE') {
  +            defined( $plugin = &$factory(@$args) )
  +                || die "$name plugin failed\n";
  +        }
  +        else {
  +            defined( $plugin = $factory->new(@$args) )
  +                || die "$name plugin failed: ", $factory->error(), "\n";
  +        }
       };
       if ($error = $@) {
   #	chomp $error;
  -	return $self->{ TOLERANT } 
  +        return $self->{ TOLERANT } 
   	       ? (undef,  Template::Constants::STATUS_DECLINED)
   	       : ($error, Template::Constants::STATUS_ERROR);
       }
  @@ -145,13 +144,22 @@
   sub _init {
       my ($self, $params) = @_;
       my ($pbase, $plugins, $factory) = 
  -	@$params{ qw( PLUGIN_BASE PLUGINS PLUGIN_FACTORY ) };
  +        @$params{ qw( PLUGIN_BASE PLUGINS PLUGIN_FACTORY ) };
   
       $plugins ||= { };
  -    if (ref $pbase ne 'ARRAY') {
  -	$pbase = $pbase ? [ $pbase ] : [ ];
  +
  +    # update PLUGIN_BASE to an array ref if necessary
  +    $pbase = [ ] unless defined $pbase;
  +    $pbase = [ $pbase ] unless ref($pbase) eq 'ARRAY';
  +
  +    # add $params->{ PLUGIN_DEFAULT } or $PLUGIN_BASE (Template::Plugin)
  +    if (exists $params->{ PLUGIN_DEFAULT }) {
  +        push(@$pbase, $params->{ PLUGIN_DEFAULT })
  +            if $params->{ PLUGIN_DEFAULT };
  +    }
  +    else {
  +        push(@$pbase, $PLUGIN_BASE);
       }
  -    push(@$pbase, 'Template::Plugin');
   
       $self->{ PLUGIN_BASE } = $pbase;
       $self->{ PLUGINS     } = { %$STD_PLUGINS, %$plugins };
  @@ -178,75 +186,75 @@
       my ($self, $name, $context) = @_;
       my ($factory, $module, $base, $pkg, $file, $ok, $error);
   
  -    if ($module = $self->{ PLUGINS }->{ $name }) {
  -	# plugin module name is explicitly stated in PLUGIN_NAME
  -	$pkg = $module;
  -	($file = $module) =~ s|::|/|g;
  -	$file =~ s|::|/|g;
  -	$self->debug("loading $module.pm (PLUGIN_NAME)")
  +    if ($module = $self->{ PLUGINS }->{ $name } || $self->{ PLUGINS }->{ lc $name }) {
  +        # plugin module name is explicitly stated in PLUGIN_NAME
  +        $pkg = $module;
  +        ($file = $module) =~ s|::|/|g;
  +        $file =~ s|::|/|g;
  +        $self->debug("loading $module.pm (PLUGIN_NAME)")
               if $self->{ DEBUG };
  -	$ok = eval { require "$file.pm" };
  -	$error = $@;
  +        $ok = eval { require "$file.pm" };
  +        $error = $@;
       }
       else {
  -	# try each of the PLUGIN_BASE values to build module name
  -	($module = $name) =~ s/\./::/g;
  -
  -	foreach $base (@{ $self->{ PLUGIN_BASE } }) {
  -	    $pkg = $base . '::' . $module;
  -	    ($file = $pkg) =~ s|::|/|g;
  -
  -	    $self->debug("loading $file.pm (PLUGIN_BASE)")
  +        # try each of the PLUGIN_BASE values to build module name
  +        ($module = $name) =~ s/\./::/g;
  +        
  +        foreach $base (@{ $self->{ PLUGIN_BASE } }) {
  +            $pkg = $base . '::' . $module;
  +            ($file = $pkg) =~ s|::|/|g;
  +            
  +            $self->debug("loading $file.pm (PLUGIN_BASE)")
                   if $self->{ DEBUG };
  -
  -	    $ok = eval { require "$file.pm" };
  -	    last unless $@;
  -	
  -	    $error .= "$@\n" 
  -		unless ($@ =~ /^Can\'t locate $file\.pm/);
  -	}
  +            
  +            $ok = eval { require "$file.pm" };
  +            last unless $@;
  +            
  +            $error .= "$@\n" 
  +                unless ($@ =~ /^Can\'t locate $file\.pm/);
  +        }
       }
  -
  +    
       if ($ok) {
  -	$self->debug("calling $pkg->load()") if $self->{ DEBUG };
  +        $self->debug("calling $pkg->load()") if $self->{ DEBUG };
   
   	$factory = eval { $pkg->load($context) };
  -	$error   = '';
  -	if ($@ || ! $factory) {
  -	    $error = $@ || 'load() returned a false value';
  -	}
  +        $error   = '';
  +        if ($@ || ! $factory) {
  +            $error = $@ || 'load() returned a false value';
  +        }
       }
       elsif ($self->{ LOAD_PERL }) {
  -	# fallback - is it a regular Perl module?
  -	($file = $module) =~ s|::|/|g;
  -	eval { require "$file.pm" };
  -	if ($@) {
  -	    $error = $@;
  -	}
  -	else {
  -	    # this is a regular Perl module so the new() constructor
  -	    # isn't expecting a $context reference as the first argument;
  -	    # so we construct a closure which removes it before calling
  -	    # $module->new(@_);
  -	    $factory = sub {
  -		shift;
  -		$module->new(@_);
  -	    };
  -	    $error   = '';
  -	}
  +        # fallback - is it a regular Perl module?
  +        ($file = $module) =~ s|::|/|g;
  +        eval { require "$file.pm" };
  +        if ($@) {
  +            $error = $@;
  +        }
  +        else {
  +            # this is a regular Perl module so the new() constructor
  +            # isn't expecting a $context reference as the first argument;
  +            # so we construct a closure which removes it before calling
  +            # $module->new(@_);
  +            $factory = sub {
  +                shift;
  +                $module->new(@_);
  +            };
  +            $error   = '';
  +        }
       }
  -
  +    
       if ($factory) {
  -	$self->debug("$name => $factory") if $self->{ DEBUG };
  -	return $factory;
  +        $self->debug("$name => $factory") if $self->{ DEBUG };
  +        return $factory;
       }
       elsif ($error) {
  -	return $self->{ TOLERANT } 
  +        return $self->{ TOLERANT } 
   	    ? (undef,  Template::Constants::STATUS_DECLINED) 
  -	    : ($error, Template::Constants::STATUS_ERROR);
  +            : ($error, Template::Constants::STATUS_ERROR);
       }
       else {
  -	return (undef, Template::Constants::STATUS_DECLINED);
  +        return (undef, Template::Constants::STATUS_DECLINED);
       }
   }
   
  @@ -265,14 +273,14 @@
       my $key;
   
       foreach $key (qw( TOLERANT LOAD_PERL )) {
  -	$output .= sprintf($format, $key, $self->{ $key });
  +        $output .= sprintf($format, $key, $self->{ $key });
       }
   
       local $" = ', ';
       my $fkeys = join(", ", keys %{$self->{ FACTORY }});
       my $plugins = $self->{ PLUGINS };
       $plugins = join('', map { 
  -	sprintf("    $format", $_, $plugins->{ $_ });
  +        sprintf("    $format", $_, $plugins->{ $_ });
       } keys %$plugins);
       $plugins = "{\n$plugins    }";
       
  @@ -605,22 +613,11 @@
       [% END %]
   
   =head2 DBI
  -
  -The DBI plugin, developed by Simon Matthews
  -E<lt>sam@knowledgepool.comE<gt>, brings the full power of Tim Bunce's
  -E<lt>Tim.Bunce@ig.co.ukE<gt> database interface module (DBI) to your
  -templates.  See L<Template::Plugin::DBI> and L<DBI> for further details.
   
  -    [% USE DBI('dbi:driver:database', 'user', 'pass') %]
  -
  -    [% FOREACH user = DBI.query( 'SELECT * FROM users' ) %]
  -       [% user.id %] [% user.name %]
  -    [% END %]
  +The DBI plugin is no longer distributed as part of the Template Toolkit
  +(as of version 2.15).  It is now available as a separate Template-Plugin-DBI 
  +distribution from CPAN.
   
  -The DBI and relevant DBD modules are available from CPAN:
  -
  -  http://www.cpan.org/modules/by-module/DBI/
  -
   =head2 Dumper
   
   The Dumper plugin provides an interface to the Data::Dumper module.  See
  @@ -677,129 +674,14 @@
       [% USE bold = format('<b>%s</b>') %]
       [% bold('Hello') %]
   
  -=head2 GD::Image, GD::Polygon, GD::Constants
  +=head2 GD
   
  -These plugins provide access to the GD graphics library via Lincoln
  -D. Stein's GD.pm interface.  These plugins allow PNG, JPEG and other
  -graphical formats to be generated.
  -
  -    [% FILTER null;
  -        USE im = GD.Image(100,100);
  -        # allocate some colors
  -        black = im.colorAllocate(0,   0, 0);
  -        red   = im.colorAllocate(255,0,  0);
  -        blue  = im.colorAllocate(0,  0,  255);
  -        # Draw a blue oval
  -        im.arc(50,50,95,75,0,360,blue);
  -        # And fill it with red
  -        im.fill(50,50,red);
  -        # Output image in PNG format
  -        im.png | stdout(1);
  -       END;
  -    -%]
  -
  -See L<Template::Plugin::GD::Image> for further details.
  -
  -=head2 GD::Text, GD::Text::Align, GD::Text::Wrap
  -
  -These plugins provide access to Martien Verbruggen's GD::Text,
  -GD::Text::Align and GD::Text::Wrap modules. These plugins allow the
  -layout, alignment and wrapping of text when drawing text in GD images.
  -
  -    [% FILTER null;
  -        USE gd  = GD.Image(200,400);
  -        USE gdc = GD.Constants;
  -        black = gd.colorAllocate(0,   0, 0);
  -        green = gd.colorAllocate(0, 255, 0);
  -        txt = "This is some long text. " | repeat(10);
  -        USE wrapbox = GD.Text.Wrap(gd,
  -         line_space  => 4,
  -         color       => green,
  -         text        => txt,
  -        );
  -        wrapbox.set_font(gdc.gdMediumBoldFont);
  -        wrapbox.set(align => 'center', width => 160);
  -        wrapbox.draw(20, 20);
  -        gd.png | stdout(1);
  -      END;
  -    -%]
  -
  -See L<Template::Plugin::GD::Text>, L<Template::Plugin::GD::Text::Align>
  -and L<Template::Plugin::GD::Text::Wrap> for further details.
  -
  -=head2 GD::Graph::lines, GD::Graph::bars, GD::Graph::points, GD::Graph::linespoin
  -ts, GD::Graph::area, GD::Graph::mixed, GD::Graph::pie
  -
  -These plugins provide access to Martien Verbruggen's GD::Graph module
  -that allows graphs, plots and charts to be created. These plugins allow
  -graphs, plots and charts to be generated in PNG, JPEG and other
  -graphical formats.
  -
  -    [% FILTER null;
  -        data = [
  -            ["1st","2nd","3rd","4th","5th","6th"],
  -            [    4,    2,    3,    4,    3,  3.5]
  -        ];
  -        USE my_graph = GD.Graph.pie(250, 200);
  -        my_graph.set(
  -                title => 'A Pie Chart',
  -                label => 'Label',
  -                axislabelclr => 'black',
  -                pie_height => 36,
  -                transparent => 0,
  -        );
  -        my_graph.plot(data).png | stdout(1);
  -      END;
  -    -%]
  -
  -See
  -L<Template::Plugin::GD::Graph::lines>,
  -L<Template::Plugin::GD::Graph::bars>,
  -L<Template::Plugin::GD::Graph::points>,
  -L<Template::Plugin::GD::Graph::linespoints>,
  -L<Template::Plugin::GD::Graph::area>,
  -L<Template::Plugin::GD::Graph::mixed>,
  -L<Template::Plugin::GD::Graph::pie>, and
  -L<GD::Graph>,
  -for more details.
  -
  -=head2 GD::Graph::bars3d, GD::Graph::lines3d, GD::Graph::pie3d
  -
  -These plugins provide access to Jeremy Wadsack's GD::Graph3d
  -module.  This allows 3D bar charts and 3D lines plots to
  -be generated.
  -
  -    [% FILTER null;
  -        data = [
  -            ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
  -            [    1,    2,    5,    6,    3,  1.5,    1,     3,     4],
  -        ];
  -        USE my_graph = GD.Graph.bars3d();
  -        my_graph.set(
  -            x_label         => 'X Label',
  -            y_label         => 'Y label',
  -            title           => 'A 3d Bar Chart',
  -            y_max_value     => 8,
  -            y_tick_number   => 8,
  -            y_label_skip    => 2,
  -            # shadows
  -            bar_spacing     => 8,
  -            shadow_depth    => 4,
  -            shadowclr       => 'dred',
  -            transparent     => 0,
  -        my_graph.plot(data).png | stdout(1);
  -      END;
  -    -%]
  -
  -See
  -L<Template::Plugin::GD::Graph::lines3d>,
  -L<Template::Plugin::GD::Graph::bars3d>, and
  -L<Template::Plugin::GD::Graph::pie3d>
  -for more details.
  +The GD plugins are no longer part of the core Template Toolkit distribution.
  +They are now available in a separate Template-GD distribution.
   
   =head2 HTML
   
  -The HTML plugin is very new and very basic, implementing a few useful
  +The HTML plugin is very basic, implementing a few useful
   methods for generating HTML.  It is likely to be extended in the future
   or integrated with a larger project to generate HTML elements in a generic
   way (as discussed recently on the mod_perl mailing list).
  @@ -899,54 +781,6 @@
   
       http://www.cpan.org/modules/by-module/Text/
   
  -=head2 XML::DOM
  -
  -The XML::DOM plugin gives access to the XML Document Object Module via
  -Clark Cooper E<lt>cooper@sch.ge.comE<gt> and Enno Derksen's 
  -E<lt>enno@att.comE<gt> XML::DOM module.  See L<Template::Plugin::XML::DOM> 
  -and L<XML::DOM> for further details.
  -
  -    [% USE dom = XML.DOM %]
  -    [% doc = dom.parse(filename) %]
  -
  -    [% FOREACH node = doc.getElementsByTagName('CODEBASE') %]
  -       * [% node.getAttribute('href') %]
  -    [% END %]
  -
  -The plugin requires the XML::DOM module, available from CPAN:
  -
  -    http://www.cpan.org/modules/by-module/XML/
  -
  -=head2 XML::RSS
  -
  -The XML::RSS plugin is a simple interface to Jonathan Eisenzopf's
  -E<lt>eisen@pobox.comE<gt> XML::RSS module.  A RSS (Rich Site Summary)
  -file is typically used to store short news 'headlines' describing
  -different links within a site.  This plugin allows you to parse RSS
  -files and format the contents accordingly using templates.  
  -See L<Template::Plugin::XML::RSS> and L<XML::RSS> for further details.
  -
  -    [% USE news = XML.RSS(filename) %]
  -   
  -    [% FOREACH item = news.items %]
  -       <a href="[% item.link %]">[% item.title %]</a>
  -    [% END %]
  -
  -The XML::RSS module is available from CPAN:
  -
  -    http://www.cpan.org/modules/by-module/XML/
  -
  -=head2 XML::Simple
  -
  -This plugin implements an interface to the L<XML::Simple|XML::Simple>
  -module.
  -
  -    [% USE xml = XML.Simple(xml_file_or_text) %]
  -
  -    [% xml.head.title %]
  -
  -See L<Template::Plugin::XML::Simple> for further details.
  -
   =head2 XML::Style
   
   This plugin defines a filter for performing simple stylesheet based 
  @@ -971,22 +805,13 @@
       [% END %]
   
   See L<Template::Plugin::XML::Style> for further details.
  -
  -=head2 XML::XPath
  -
  -The XML::XPath plugin provides an interface to Matt Sergeant's
  -E<lt>matt@sergeant.orgE<gt> XML::XPath module.  See 
  -L<Template::Plugin::XML::XPath> and L<XML::XPath> for further details.
  -
  -    [% USE xpath = XML.XPath(xmlfile) %]
  -    [% FOREACH page = xpath.findnodes('/html/body/page') %]
  -       [% page.getAttribute('title') %]
  -    [% END %]
   
  -The plugin requires the XML::XPath module, available from CPAN:
  +=head2 XML
   
  -    http://www.cpan.org/modules/by-module/XML/
  +The XML::DOM, XML::RSS, XML::Simple and XML::XPath plugins are no
  +longer distributed with the Template Toolkit as of version 2.15
   
  +They are now available in a separate Template-XML distribution.
   
   
   
  @@ -1015,8 +840,8 @@
   
   =head1 VERSION
   
  -2.70, distributed as part of the
  -Template Toolkit version 2.13, released on 30 January 2004.
  +2.71, distributed as part of the
  +Template Toolkit version 2.15, released on 27 January 2006.
   
   =head1 COPYRIGHT