1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
|
#============================================================= -*-Perl-*-
#
# Template::Plugins
#
# DESCRIPTION
# Plugin provider which handles the loading of plugin modules and
# instantiation of plugin objects.
#
# AUTHORS
# Andy Wardley <abw@kfs.org>
#
# COPYRIGHT
# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
#
# This module is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
#----------------------------------------------------------------------------
#
# $Id: Plugins.pm,v 2.71 2004/01/30 19:32:28 abw Exp $
#
#============================================================================
package Template::Plugins;
require 5.004;
use strict;
use base qw( Template::Base );
use vars qw( $VERSION $DEBUG $STD_PLUGINS );
use Template::Constants;
$VERSION = sprintf("%d.%02d", q$Revision: 2.71 $ =~ /(\d+)\.(\d+)/);
$STD_PLUGINS = {
'autoformat' => 'Template::Plugin::Autoformat',
'cgi' => 'Template::Plugin::CGI',
'datafile' => 'Template::Plugin::Datafile',
'date' => 'Template::Plugin::Date',
'debug' => 'Template::Plugin::Debug',
'directory' => 'Template::Plugin::Directory',
'dbi' => 'Template::Plugin::DBI',
'dumper' => 'Template::Plugin::Dumper',
'file' => 'Template::Plugin::File',
'format' => 'Template::Plugin::Format',
'html' => 'Template::Plugin::HTML',
'image' => 'Template::Plugin::Image',
'iterator' => 'Template::Plugin::Iterator',
'pod' => 'Template::Plugin::Pod',
'table' => 'Template::Plugin::Table',
'url' => 'Template::Plugin::URL',
'view' => 'Template::Plugin::View',
'wrap' => 'Template::Plugin::Wrap',
'xmlstyle' => 'Template::Plugin::XML::Style',
};
#========================================================================
# -- PUBLIC METHODS --
#========================================================================
#------------------------------------------------------------------------
# fetch($name, \@args, $context)
#
# General purpose method for requesting instantiation of a plugin
# object. The name of the plugin is passed as the first parameter.
# The internal FACTORY lookup table is consulted to retrieve the
# appropriate factory object or class name. If undefined, the _load()
# method is called to attempt to load the module and return a factory
# class/object which is then cached for subsequent use. A reference
# to the calling context should be passed as the third parameter.
# This is passed to the _load() class method. The new() method is
# then called against the factory class name or prototype object to
# instantiate a new plugin object, passing any arguments specified by
# list reference as the second parameter. e.g. where $factory is the
# class name 'MyClass', the new() method is called as a class method,
# $factory->new(...), equivalent to MyClass->new(...) . Where
# $factory is a prototype object, the new() method is called as an
# object method, $myobject->new(...). This latter approach allows
# plugins to act as Singletons, cache shared data, etc.
#
# Returns a reference to a plugin, (undef, STATUS_DECLINE) to decline
# the request or ($error, STATUS_ERROR) on error.
#------------------------------------------------------------------------
sub fetch {
my ($self, $name, $args, $context) = @_;
my ($factory, $plugin, $error);
$self->debug("fetch($name, ",
defined $args ? ('[ ', join(', ', @$args), ' ]') : '<no args>', ', ',
defined $context ? $context : '<no context>',
')') if $self->{ DEBUG };
# NOTE:
# the $context ref gets passed as the first parameter to all regular
# plugins, but not to those loaded via LOAD_PERL; to hack around
# this until we have a better implementation, we pass the $args
# reference to _load() and let it unshift the first args in the
# LOAD_PERL case
$args ||= [ ];
unshift @$args, $context;
$factory = $self->{ FACTORY }->{ $name } ||= do {
($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 ($error = $@) {
return $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ($error, Template::Constants::STATUS_ERROR);
}
return $plugin;
}
#========================================================================
# -- PRIVATE METHODS --
#========================================================================
#------------------------------------------------------------------------
# _init(\%config)
#
# Private initialisation method.
#------------------------------------------------------------------------
sub _init {
my ($self, $params) = @_;
my ($pbase, $plugins, $factory) =
@$params{ qw( PLUGIN_BASE PLUGINS PLUGIN_FACTORY ) };
$plugins ||= { };
if (ref $pbase ne 'ARRAY') {
$pbase = $pbase ? [ $pbase ] : [ ];
}
push(@$pbase, 'Template::Plugin');
$self->{ PLUGIN_BASE } = $pbase;
$self->{ PLUGINS } = { %$STD_PLUGINS, %$plugins };
$self->{ TOLERANT } = $params->{ TOLERANT } || 0;
$self->{ LOAD_PERL } = $params->{ LOAD_PERL } || 0;
$self->{ FACTORY } = $factory || { };
$self->{ DEBUG } = ( $params->{ DEBUG } || 0 )
& Template::Constants::DEBUG_PLUGINS;
return $self;
}
#------------------------------------------------------------------------
# _load($name, $context)
#
# Private method which attempts to load a plugin module and determine the
# correct factory name or object by calling the load() class method in
# the loaded module.
#------------------------------------------------------------------------
sub _load {
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 $self->{ DEBUG };
$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)")
if $self->{ DEBUG };
$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 };
$factory = eval { $pkg->load($context) };
$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 = '';
}
}
if ($factory) {
$self->debug("$name => $factory") if $self->{ DEBUG };
return $factory;
}
elsif ($error) {
return $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ($error, Template::Constants::STATUS_ERROR);
}
else {
return (undef, Template::Constants::STATUS_DECLINED);
}
}
#------------------------------------------------------------------------
# _dump()
#
# Debug method which constructs and returns text representing the current
# state of the object.
#------------------------------------------------------------------------
sub _dump {
my $self = shift;
my $output = "[Template::Plugins] {\n";
my $format = " %-16s => %s\n";
my $key;
foreach $key (qw( TOLERANT LOAD_PERL )) {
$output .= sprintf($format, $key, $self->{ $key });
}
local $" = ', ';
my $fkeys = join(", ", keys %{$self->{ FACTORY }});
my $plugins = $self->{ PLUGINS };
$plugins = join('', map {
sprintf(" $format", $_, $plugins->{ $_ });
} keys %$plugins);
$plugins = "{\n$plugins }";
$output .= sprintf($format, 'PLUGIN_BASE', "[ @{ $self->{ PLUGIN_BASE } } ]");
$output .= sprintf($format, 'PLUGINS', $plugins);
$output .= sprintf($format, 'FACTORY', $fkeys);
$output .= '}';
return $output;
}
1;
__END__
#------------------------------------------------------------------------
# IMPORTANT NOTE
# This documentation is generated automatically from source
# templates. Any changes you make here may be lost.
#
# The 'docsrc' documentation source bundle is available for download
# from http://www.template-toolkit.org/docs.html and contains all
# the source templates, XML files, scripts, etc., from which the
# documentation for the Template Toolkit is built.
#------------------------------------------------------------------------
=head1 NAME
Template::Plugins - Plugin provider module
=head1 SYNOPSIS
use Template::Plugins;
$plugin_provider = Template::Plugins->new(\%options);
($plugin, $error) = $plugin_provider->fetch($name, @args);
=head1 DESCRIPTION
The Template::Plugins module defines a provider class which can be used
to load and instantiate Template Toolkit plugin modules.
=head1 METHODS
=head2 new(\%params)
Constructor method which instantiates and returns a reference to a
Template::Plugins object. A reference to a hash array of configuration
items may be passed as a parameter. These are described below.
Note that the Template.pm front-end module creates a Template::Plugins
provider, passing all configuration items. Thus, the examples shown
below in the form:
$plugprov = Template::Plugins->new({
PLUGIN_BASE => 'MyTemplate::Plugin',
LOAD_PERL => 1,
...
});
can also be used via the Template module as:
$ttengine = Template->new({
PLUGIN_BASE => 'MyTemplate::Plugin',
LOAD_PERL => 1,
...
});
as well as the more explicit form of:
$plugprov = Template::Plugins->new({
PLUGIN_BASE => 'MyTemplate::Plugin',
LOAD_PERL => 1,
...
});
$ttengine = Template->new({
LOAD_PLUGINS => [ $plugprov ],
});
=head2 fetch($name, @args)
Called to request that a plugin of a given name be provided. The relevant
module is first loaded (if necessary) and the load() class method called
to return the factory class name (usually the same package name) or a
factory object (a prototype). The new() method is then called as a
class or object method against the factory, passing all remaining
parameters.
Returns a reference to a new plugin object or ($error, STATUS_ERROR)
on error. May also return (undef, STATUS_DECLINED) to decline to
serve the request. If TOLERANT is set then all errors will be
returned as declines.
=head1 CONFIGURATION OPTIONS
The following list details the configuration options that can be provided
to the Template::Plugins new() constructor.
=over 4
=item PLUGINS
The PLUGINS options can be used to provide a reference to a hash array
that maps plugin names to Perl module names. A number of standard
plugins are defined (e.g. 'table', 'cgi', 'dbi', etc.) which map to
their corresponding Template::Plugin::* counterparts. These can be
redefined by values in the PLUGINS hash.
my $plugins = Template::Plugins->new({
PLUGINS => {
cgi => 'MyOrg::Template::Plugin::CGI',
foo => 'MyOrg::Template::Plugin::Foo',
bar => 'MyOrg::Template::Plugin::Bar',
},
});
The USE directive is used to create plugin objects and does so by
calling the plugin() method on the current Template::Context object.
If the plugin name is defined in the PLUGINS hash then the
corresponding Perl module is loaded via require(). The context then
calls the load() class method which should return the class name
(default and general case) or a prototype object against which the
new() method can be called to instantiate individual plugin objects.
If the plugin name is not defined in the PLUGINS hash then the PLUGIN_BASE
and/or LOAD_PERL options come into effect.
=item PLUGIN_BASE
If a plugin is not defined in the PLUGINS hash then the PLUGIN_BASE is used
to attempt to construct a correct Perl module name which can be successfully
loaded.
The PLUGIN_BASE can be specified as a single value or as a reference
to an array of multiple values. The default PLUGIN_BASE value,
'Template::Plugin', is always added the the end of the PLUGIN_BASE
list (a single value is first converted to a list). Each value should
contain a Perl package name to which the requested plugin name is
appended.
example 1:
my $plugins = Template::Plugins->new({
PLUGIN_BASE => 'MyOrg::Template::Plugin',
});
[% USE Foo %] # => MyOrg::Template::Plugin::Foo
or Template::Plugin::Foo
example 2:
my $plugins = Template::Plugins->new({
PLUGIN_BASE => [ 'MyOrg::Template::Plugin',
'YourOrg::Template::Plugin' ],
});
[% USE Foo %] # => MyOrg::Template::Plugin::Foo
or YourOrg::Template::Plugin::Foo
or Template::Plugin::Foo
=item LOAD_PERL
If a plugin cannot be loaded using the PLUGINS or PLUGIN_BASE
approaches then the provider can make a final attempt to load the
module without prepending any prefix to the module path. This allows
regular Perl modules (i.e. those that don't reside in the
Template::Plugin or some other such namespace) to be loaded and used
as plugins.
By default, the LOAD_PERL option is set to 0 and no attempt will be made
to load any Perl modules that aren't named explicitly in the PLUGINS
hash or reside in a package as named by one of the PLUGIN_BASE
components.
Plugins loaded using the PLUGINS or PLUGIN_BASE receive a reference to
the current context object as the first argument to the new()
constructor. Modules loaded using LOAD_PERL are assumed to not
conform to the plugin interface. They must provide a new() class
method for instantiating objects but it will not receive a reference
to the context as the first argument. Plugin modules should provide a
load() class method (or inherit the default one from the
Template::Plugin base class) which is called the first time the plugin
is loaded. Regular Perl modules need not. In all other respects,
regular Perl objects and Template Toolkit plugins are identical.
If a particular Perl module does not conform to the common, but not
unilateral, new() constructor convention then a simple plugin wrapper
can be written to interface to it.
=item TOLERANT
The TOLERANT flag is used by the various Template Toolkit provider
modules (Template::Provider, Template::Plugins, Template::Filters) to
control their behaviour when errors are encountered. By default, any
errors are reported as such, with the request for the particular
resource (template, plugin, filter) being denied and an exception
raised. When the TOLERANT flag is set to any true values, errors will
be silently ignored and the provider will instead return
STATUS_DECLINED. This allows a subsequent provider to take
responsibility for providing the resource, rather than failing the
request outright. If all providers decline to service the request,
either through tolerated failure or a genuine disinclination to
comply, then a 'E<lt>resourceE<gt> not found' exception is raised.
=item DEBUG
The DEBUG option can be used to enable debugging messages from the
Template::Plugins module by setting it to include the DEBUG_PLUGINS
value.
use Template::Constants qw( :debug );
my $template = Template->new({
DEBUG => DEBUG_FILTERS | DEBUG_PLUGINS,
});
=back
=head1 TEMPLATE TOOLKIT PLUGINS
The following plugin modules are distributed with the Template
Toolkit. Some of the plugins interface to external modules (detailed
below) which should be downloaded from any CPAN site and installed
before using the plugin.
=head2 Autoformat
The Autoformat plugin is an interface to Damian Conway's Text::Autoformat
Perl module which provides advanced text wrapping and formatting. See
L<Template::Plugin::Autoformat> and L<Text::Autoformat> for further
details.
[% USE autoformat(left=10, right=20) %]
[% autoformat(mytext) %] # call autoformat sub
[% mytext FILTER autoformat %] # or use autoformat filter
The Text::Autoformat module is available from CPAN:
http://www.cpan.org/modules/by-module/Text/
=head2 CGI
The CGI plugin is a wrapper around Lincoln Stein's
E<lt>lstein@genome.wi.mit.eduE<gt> CGI.pm module. The plugin is
distributed with the Template Toolkit (see L<Template::Plugin::CGI>)
and the CGI module itself is distributed with recent versions Perl,
or is available from CPAN.
[% USE CGI %]
[% CGI.param('param_name') %]
[% CGI.start_form %]
[% CGI.popup_menu( Name => 'color',
Values => [ 'Green', 'Brown' ] ) %]
[% CGI.end_form %]
=head2 Datafile
Provides an interface to data stored in a plain text file in a simple
delimited format. The first line in the file specifies field names
which should be delimiter by any non-word character sequence.
Subsequent lines define data using the same delimiter as int he first
line. Blank lines and comments (lines starting '#') are ignored. See
L<Template::Plugin::Datafile> for further details.
/tmp/mydata:
# define names for each field
id : email : name : tel
# here's the data
fred : fred@here.com : Fred Smith : 555-1234
bill : bill@here.com : Bill White : 555-5678
example:
[% USE userlist = datafile('/tmp/mydata') %]
[% FOREACH user = userlist %]
[% user.name %] ([% user.id %])
[% END %]
=head2 Date
The Date plugin provides an easy way to generate formatted time and date
strings by delegating to the POSIX strftime() routine. See
L<Template::Plugin::Date> and L<POSIX> for further details.
[% USE date %]
[% date.format %] # current time/date
File last modified: [% date.format(template.modtime) %]
=head2 Directory
The Directory plugin provides a simple interface to a directory and
the files within it. See L<Template::Plugin::Directory> for further
details.
[% USE dir = Directory('/tmp') %]
[% FOREACH file = dir.files %]
# all the plain files in the directory
[% END %]
[% FOREACH file = dir.dirs %]
# all the sub-directories
[% 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 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
L<Template::Plugin::Dumper> and L<Data::Dumper> for futher details.
[% USE dumper(indent=0, pad="<br>") %]
[% dumper.dump(myvar, yourvar) %]
=head2 File
The File plugin provides a general abstraction for files and can be
used to fetch information about specific files within a filesystem.
See L<Template::Plugin::File> for further details.
[% USE File('/tmp/foo.html') %]
[% File.name %] # foo.html
[% File.dir %] # /tmp
[% File.mtime %] # modification time
=head2 Filter
This module implements a base class plugin which can be subclassed
to easily create your own modules that define and install new filters.
package MyOrg::Template::Plugin::MyFilter;
use Template::Plugin::Filter;
use base qw( Template::Plugin::Filter );
sub filter {
my ($self, $text) = @_;
# ...mungify $text...
return $text;
}
# now load it...
[% USE MyFilter %]
# ...and use the returned object as a filter
[% FILTER $MyFilter %]
...
[% END %]
See L<Template::Plugin::Filter> for further details.
=head2 Format
The Format plugin provides a simple way to format text according to a
printf()-like format. See L<Template::Plugin::Format> for further
details.
[% USE bold = format('<b>%s</b>') %]
[% bold('Hello') %]
=head2 GD::Image, GD::Polygon, GD::Constants
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.
=head2 HTML
The HTML plugin is very new and 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).
[% USE HTML %]
[% HTML.escape("if (a < b && c > d) ..." %]
[% HTML.attributes(border => 1, cellpadding => 2) %]
[% HTML.element(table => { border => 1, cellpadding => 2 }) %]
See L<Template::Plugin::HTML> for further details.
=head2 Iterator
The Iterator plugin provides a way to create a Template::Iterator
object to iterate over a data set. An iterator is created
automatically by the FOREACH directive and is aliased to the 'loop'
variable. This plugin allows an iterator to be explicitly created
with a given name, or the default plugin name, 'iterator'. See
L<Template::Plugin::Iterator> for further details.
[% USE iterator(list, args) %]
[% FOREACH item = iterator %]
[% '<ul>' IF iterator.first %]
<li>[% item %]
[% '</ul>' IF iterator.last %]
[% END %]
=head2 Pod
This plugin provides an interface to the L<Pod::POM|Pod::POM> module
which parses POD documents into an internal object model which can
then be traversed and presented through the Template Toolkit.
[% USE Pod(podfile) %]
[% FOREACH head1 = Pod.head1;
FOREACH head2 = head1/head2;
...
END;
END
%]
=head2 String
The String plugin implements an object-oriented interface for
manipulating strings. See L<Template::Plugin::String> for further
details.
[% USE String 'Hello' %]
[% String.append(' World') %]
[% msg = String.new('Another string') %]
[% msg.replace('string', 'text') %]
The string "[% msg %]" is [% msg.length %] characters long.
=head2 Table
The Table plugin allows you to format a list of data items into a
virtual table by specifying a fixed number of rows or columns, with
an optional overlap. See L<Template::Plugin::Table> for further
details.
[% USE table(list, rows=10, overlap=1) %]
[% FOREACH item = table.col(3) %]
[% item %]
[% END %]
=head2 URL
The URL plugin provides a simple way of contructing URLs from a base
part and a variable set of parameters. See L<Template::Plugin::URL>
for further details.
[% USE mycgi = url('/cgi-bin/bar.pl', debug=1) %]
[% mycgi %]
# ==> /cgi/bin/bar.pl?debug=1
[% mycgi(mode='submit') %]
# ==> /cgi/bin/bar.pl?mode=submit&debug=1
=head2 Wrap
The Wrap plugin uses the Text::Wrap module by David Muir Sharnoff
E<lt>muir@idiom.comE<gt> (with help from Tim Pierce and many many others)
to provide simple paragraph formatting. See L<Template::Plugin::Wrap>
and L<Text::Wrap> for further details.
[% USE wrap %]
[% wrap(mytext, 40, '* ', ' ') %] # use wrap sub
[% mytext FILTER wrap(40) -%] # or wrap FILTER
The Text::Wrap module is available from CPAN:
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
transformations of XML text.
[% USE xmlstyle
table = {
attributes = {
border = 0
cellpadding = 4
cellspacing = 1
}
}
%]
[% FILTER xmlstyle %]
<table>
<tr>
<td>Foo</td> <td>Bar</td> <td>Baz</td>
</tr>
</table>
[% 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:
http://www.cpan.org/modules/by-module/XML/
=head1 BUGS / ISSUES
=over 4
=item *
It might be worthwhile being able to distinguish between absolute
module names and those which should be applied relative to PLUGIN_BASE
directories. For example, use 'MyNamespace::MyModule' to denote
absolute module names (e.g. LOAD_PERL), and 'MyNamespace.MyModule' to
denote relative to PLUGIN_BASE.
=back
=head1 AUTHOR
Andy Wardley E<lt>abw@andywardley.comE<gt>
L<http://www.andywardley.com/|http://www.andywardley.com/>
=head1 VERSION
2.71, distributed as part of the
Template Toolkit version 2.14, released on 04 October 2004.
=head1 COPYRIGHT
Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved.
Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=head1 SEE ALSO
L<Template|Template>, L<Template::Plugin|Template::Plugin>, L<Template::Context|Template::Context>
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:
|