Initial Commit
This commit is contained in:
155
database/perl/vendor/lib/Template/Plugin/Assert.pm
vendored
Normal file
155
database/perl/vendor/lib/Template/Plugin/Assert.pm
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Assert
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit plugin module which allows you to assert that
|
||||
# items fetches from the stash are defined.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2008 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Assert;
|
||||
use base 'Template::Plugin';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Template::Exception;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $MONAD = 'Template::Monad::Assert';
|
||||
our $EXCEPTION = 'Template::Exception';
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub load {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
my $stash = $context->stash;
|
||||
my $vmethod = sub {
|
||||
$MONAD->new($stash, shift);
|
||||
};
|
||||
|
||||
# define .assert vmethods for hash and list objects
|
||||
$context->define_vmethod( hash => assert => $vmethod );
|
||||
$context->define_vmethod( list => assert => $vmethod );
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, $context, @args) = @_;
|
||||
# create an assert plugin object which will handle simple variable
|
||||
# lookups.
|
||||
return bless { _CONTEXT => $context }, $class;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my ($self, @args) = @_;
|
||||
my $item = $AUTOLOAD;
|
||||
$item =~ s/.*:://;
|
||||
return if $item eq 'DESTROY';
|
||||
|
||||
# lookup the named values
|
||||
my $stash = $self->{ _CONTEXT }->stash;
|
||||
my $value = $stash->dotop($stash, $item, \@args);
|
||||
|
||||
if (! defined $value) {
|
||||
die $EXCEPTION->new( assert => "undefined value for $item" );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
package Template::Monad::Assert;
|
||||
|
||||
our $EXCEPTION = 'Template::Exception';
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub new {
|
||||
my ($class, $stash, $this) = @_;
|
||||
bless [$stash, $this], $class;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my ($self, @args) = @_;
|
||||
my ($stash, $this) = @$self;
|
||||
my $item = $AUTOLOAD;
|
||||
$item =~ s/.*:://;
|
||||
return if $item eq 'DESTROY';
|
||||
|
||||
my $value = $stash->dotop($stash, $item, \@args);
|
||||
|
||||
if (! defined $value) {
|
||||
die $EXCEPTION->new( assert => "undefined value for $item" );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Assert - trap undefined values
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE assert %]
|
||||
|
||||
# throws error if any undefined values are returned
|
||||
[% object.assert.method %]
|
||||
[% hash.assert.key %]
|
||||
[% list.assert.item %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin defines the C<assert> virtual method that can be used
|
||||
to automatically throw errors when undefined values are used.
|
||||
|
||||
For example, consider this dotop:
|
||||
|
||||
[% user.name %]
|
||||
|
||||
If C<user.name> is an undefined value then TT will silently ignore the
|
||||
fact and print nothing. If you C<USE> the C<assert> plugin then you
|
||||
can add the C<assert> vmethod between the C<user> and C<name> elements,
|
||||
like so:
|
||||
|
||||
[% user.assert.name %]
|
||||
|
||||
Now, if C<user.name> is an undefined value, an exception will be thrown:
|
||||
|
||||
assert error - undefined value for name
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2008 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
135
database/perl/vendor/lib/Template/Plugin/CGI.pm
vendored
Normal file
135
database/perl/vendor/lib/Template/Plugin/CGI.pm
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::CGI
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Simple Template Toolkit plugin interfacing to the CGI.pm module.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::CGI;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use CGI;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
CGI->new(@_);
|
||||
}
|
||||
|
||||
# monkeypatch CGI::params() method to Do The Right Thing in TT land
|
||||
|
||||
sub CGI::params {
|
||||
my $self = shift;
|
||||
local $" = ', ';
|
||||
|
||||
return $self->{ _TT_PARAMS } ||= do {
|
||||
# must call Vars() in a list context to receive
|
||||
# plain list of key/vals rather than a tied hash
|
||||
my $params = { $self->Vars() };
|
||||
|
||||
# convert any null separated values into lists
|
||||
@$params{ keys %$params } = map {
|
||||
/\0/ ? [ split /\0/ ] : $_
|
||||
} values %$params;
|
||||
|
||||
$params;
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::CGI - Interface to the CGI module
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE CGI %]
|
||||
[% CGI.param('parameter') %]
|
||||
|
||||
[% USE things = CGI %]
|
||||
[% things.param('name') %]
|
||||
|
||||
# see CGI docs for other methods provided by the CGI object
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a very simple Template Toolkit Plugin interface to the C<CGI> module.
|
||||
A C<CGI> object will be instantiated via the following directive:
|
||||
|
||||
[% USE CGI %]
|
||||
|
||||
C<CGI> methods may then be called as follows:
|
||||
|
||||
[% CGI.header %]
|
||||
[% CGI.param('parameter') %]
|
||||
|
||||
An alias can be used to provide an alternate name by which the object should
|
||||
be identified.
|
||||
|
||||
[% USE mycgi = CGI %]
|
||||
[% mycgi.start_form %]
|
||||
[% mycgi.popup_menu({ Name => 'Color'
|
||||
Values => [ 'Green' 'Black' 'Brown' ] }) %]
|
||||
|
||||
Parenthesised parameters to the C<USE> directive will be passed to the plugin
|
||||
constructor:
|
||||
|
||||
[% USE cgiprm = CGI('uid=abw&name=Andy+Wardley') %]
|
||||
[% cgiprm.param('uid') %]
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
In addition to all the methods supported by the C<CGI> module, this
|
||||
plugin defines the following.
|
||||
|
||||
=head2 params()
|
||||
|
||||
This method returns a reference to a hash of all the C<CGI> parameters.
|
||||
Any parameters that have multiple values will be returned as lists.
|
||||
|
||||
[% USE CGI('user=abw&item=foo&item=bar') %]
|
||||
[% CGI.params.user %] # abw
|
||||
[% CGI.params.item.join(', ') %] # foo, bar
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<CGI>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
170
database/perl/vendor/lib/Template/Plugin/Datafile.pm
vendored
Normal file
170
database/perl/vendor/lib/Template/Plugin/Datafile.pm
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Datafile
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit Plugin which reads a datafile and constructs a
|
||||
# list object containing hashes representing records in the file.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Datafile;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $filename, $params) = @_;
|
||||
my ($delim, $encoding, $line, @fields, @data, @results);
|
||||
my $self = [ ];
|
||||
local *FD;
|
||||
local $/ = "\n";
|
||||
|
||||
$params ||= { };
|
||||
$delim = $params->{'delim'} || ':';
|
||||
$delim = quotemeta($delim);
|
||||
$encoding = defined $params->{'encoding'} ? ':encoding('.$params->{'encoding'}.')' : '';
|
||||
|
||||
return $class->error("No filename specified")
|
||||
unless $filename;
|
||||
|
||||
open(FD, '<'.$encoding, $filename)
|
||||
|| return $class->error("$filename: $!");
|
||||
|
||||
# first line of file should contain field definitions
|
||||
while (! $line || $line =~ /^#/) {
|
||||
$line = <FD>;
|
||||
chomp $line;
|
||||
$line =~ s/\r$//;
|
||||
}
|
||||
|
||||
(@fields = split(/\s*$delim\s*/, $line))
|
||||
|| return $class->error("first line of file must contain field names");
|
||||
|
||||
# read each line of the file
|
||||
while (<FD>) {
|
||||
chomp;
|
||||
s/\r$//;
|
||||
|
||||
# ignore comments and blank lines
|
||||
next if /^#/ || /^\s*$/;
|
||||
|
||||
# split line into fields
|
||||
@data = split(/\s*$delim\s*/);
|
||||
|
||||
# create hash record to represent data
|
||||
my %record;
|
||||
@record{ @fields } = @data;
|
||||
|
||||
push(@$self, \%record);
|
||||
}
|
||||
|
||||
# return $self;
|
||||
bless $self, $class;
|
||||
}
|
||||
|
||||
|
||||
sub as_list {
|
||||
return $_[0];
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Datafile - Plugin to construct records from a simple data file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE mydata = datafile('/path/to/datafile') %]
|
||||
[% USE mydata = datafile('/path/to/datafile', delim = '|') %]
|
||||
[% USE mydata = datafile('/path/to/datafile', encoding = 'UTF-8') %]
|
||||
|
||||
[% FOREACH record = mydata %]
|
||||
[% record.this %] [% record.that %]
|
||||
[% END %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin provides a simple facility to construct a list of hash
|
||||
references, each of which represents a data record of known structure,
|
||||
from a data file.
|
||||
|
||||
[% USE datafile(filename) %]
|
||||
|
||||
A absolute filename must be specified (for this initial implementation at
|
||||
least - in a future version it might also use the C<INCLUDE_PATH>). An
|
||||
optional C<delim> parameter may also be provided to specify an alternate
|
||||
delimiter character.
|
||||
The optional C<encoding> parameter may be used to specify the input file
|
||||
encoding.
|
||||
|
||||
[% USE userlist = datafile('/path/to/file/users') %]
|
||||
[% USE things = datafile('items', delim = '|') %]
|
||||
|
||||
The format of the file is intentionally simple. The first line
|
||||
defines the field names, delimited by colons with optional surrounding
|
||||
whitespace. Subsequent lines then defines records containing data
|
||||
items, also delimited by colons. e.g.
|
||||
|
||||
id : name : email : tel
|
||||
abw : Andy Wardley : abw@tt2.org : 555-1234
|
||||
sam : Simon Matthews : sam@tt2.org : 555-9876
|
||||
|
||||
Each line is read, split into composite fields, and then used to
|
||||
initialise a hash array containing the field names as relevant keys.
|
||||
The plugin returns a blessed list reference containing the hash
|
||||
references in the order as defined in the file.
|
||||
|
||||
[% FOREACH user = userlist %]
|
||||
[% user.id %]: [% user.name %]
|
||||
[% END %]
|
||||
|
||||
The first line of the file B<must> contain the field definitions.
|
||||
After the first line, blank lines will be ignored, along with comment
|
||||
line which start with a 'C<#>'.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Should handle file names relative to C<INCLUDE_PATH>.
|
||||
Doesn't permit use of 'C<:>' in a field. Some escaping mechanism is required.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
378
database/perl/vendor/lib/Template/Plugin/Date.pm
vendored
Normal file
378
database/perl/vendor/lib/Template/Plugin/Date.pm
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Date
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Plugin to generate formatted date strings.
|
||||
#
|
||||
# AUTHORS
|
||||
# Thierry-Michel Barral <kktos@electron-libre.com>
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Thierry-Michel Barral, Andy Wardley.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Date;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
use POSIX ();
|
||||
|
||||
use Config ();
|
||||
|
||||
use constant HAS_SETLOCALE => $Config::Config{d_setlocale};
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $FORMAT = '%H:%M:%S %d-%b-%Y'; # default strftime() format
|
||||
our @LOCALE_SUFFIX = qw( .ISO8859-1 .ISO_8859-15 .US-ASCII .UTF-8 );
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new(\%options)
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $params) = @_;
|
||||
bless {
|
||||
$params ? %$params : ()
|
||||
}, $class;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# now()
|
||||
#
|
||||
# Call time() to return the current system time in seconds since the epoch.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub now {
|
||||
return time();
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# format()
|
||||
# format($time)
|
||||
# format($time, $format)
|
||||
# format($time, $format, $locale)
|
||||
# format($time, $format, $locale, $gmt_flag)
|
||||
# format(\%named_params);
|
||||
#
|
||||
# Returns a formatted time/date string for the specified time, $time,
|
||||
# (or the current system time if unspecified) using the $format, $locale,
|
||||
# and $gmt values specified as arguments or internal values set defined
|
||||
# at construction time). Specifying a Perl-true value for $gmt will
|
||||
# override the local time zone and force the output to be for GMT.
|
||||
# Any or all of the arguments may be specified as named parameters which
|
||||
# get passed as a hash array reference as the final argument.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
sub format {
|
||||
my $self = shift;
|
||||
my $params = ref($_[$#_]) eq 'HASH' ? pop(@_) : { };
|
||||
|
||||
my $time = shift(@_);
|
||||
$time = $params->{ time } || $self->{ time } || $self->now() if !defined $time;
|
||||
|
||||
my $format = @_ ? shift(@_)
|
||||
: ($params->{ format } || $self->{ format } || $FORMAT);
|
||||
my $locale = @_ ? shift(@_)
|
||||
: ($params->{ locale } || $self->{ locale });
|
||||
my $gmt = @_ ? shift(@_)
|
||||
: ($params->{ gmt } || $self->{ gmt });
|
||||
my $offset = @_ ? shift(@_)
|
||||
: ( $params->{ use_offset } || $self->{ use_offset });
|
||||
my (@date, $datestr);
|
||||
|
||||
if ($time =~ /^-?\d+$/) {
|
||||
# $time is now in seconds since epoch
|
||||
if ($gmt) {
|
||||
@date = (gmtime($time))[ 0 .. ( $offset ? 6 : 8 ) ];
|
||||
}
|
||||
else {
|
||||
@date = (localtime($time))[ 0 .. ( $offset ? 6 : 8 ) ];
|
||||
}
|
||||
}
|
||||
else {
|
||||
# if $time is numeric, then we assume it's seconds since the epoch
|
||||
# otherwise, we try to parse it as either a 'Y:M:D H:M:S' or a
|
||||
# 'H:M:S D:M:Y' string
|
||||
|
||||
my @parts = (split(/\D/, $time));
|
||||
|
||||
if (@parts >= 6) {
|
||||
if (length($parts[0]) == 4) {
|
||||
# year is first; assume 'Y:M:D H:M:S'
|
||||
@date = @parts[reverse 0..5];
|
||||
}
|
||||
else {
|
||||
# year is last; assume 'H:M:S D:M:Y'
|
||||
@date = @parts[2,1,0,3..5];
|
||||
}
|
||||
}
|
||||
|
||||
if (!@date) {
|
||||
return (undef, Template::Exception->new('date',
|
||||
"bad time/date string: " .
|
||||
"expects 'h:m:s d:m:y' got: '$time'"));
|
||||
}
|
||||
$date[4] -= 1; # correct month number 1-12 to range 0-11
|
||||
$date[5] -= 1900; # convert absolute year to years since 1900
|
||||
$time = &POSIX::mktime(@date);
|
||||
|
||||
if ($offset) {
|
||||
push @date, $gmt
|
||||
? (gmtime($time))[6..8] : (localtime($time))[6..8];
|
||||
}
|
||||
}
|
||||
|
||||
if ($locale) {
|
||||
# format the date in a specific locale, saving and subsequently
|
||||
# restoring the current locale.
|
||||
my $old_locale = HAS_SETLOCALE
|
||||
? &POSIX::setlocale(&POSIX::LC_ALL)
|
||||
: undef;
|
||||
|
||||
# some systems expect locales to have a particular suffix
|
||||
for my $suffix ('', @LOCALE_SUFFIX) {
|
||||
my $try_locale = $locale.$suffix;
|
||||
my $setlocale = HAS_SETLOCALE
|
||||
? &POSIX::setlocale(&POSIX::LC_ALL, $try_locale)
|
||||
: undef;
|
||||
if (defined $setlocale && $try_locale eq $setlocale) {
|
||||
$locale = $try_locale;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$datestr = &POSIX::strftime($format, @date);
|
||||
&POSIX::setlocale(&POSIX::LC_ALL, $old_locale) if HAS_SETLOCALE;
|
||||
}
|
||||
else {
|
||||
$datestr = &POSIX::strftime($format, @date);
|
||||
}
|
||||
|
||||
return $datestr;
|
||||
}
|
||||
|
||||
sub calc {
|
||||
my $self = shift;
|
||||
eval { require "Date/Calc.pm" };
|
||||
$self->throw("failed to load Date::Calc: $@") if $@;
|
||||
return Template::Plugin::Date::Calc->new('no context');
|
||||
}
|
||||
|
||||
sub manip {
|
||||
my $self = shift;
|
||||
eval { require "Date/Manip.pm" };
|
||||
$self->throw("failed to load Date::Manip: $@") if $@;
|
||||
return Template::Plugin::Date::Manip->new('no context');
|
||||
}
|
||||
|
||||
|
||||
sub throw {
|
||||
my $self = shift;
|
||||
die (Template::Exception->new('date', join(', ', @_)));
|
||||
}
|
||||
|
||||
|
||||
package Template::Plugin::Date::Calc;
|
||||
use base qw( Template::Plugin );
|
||||
our $AUTOLOAD;
|
||||
*throw = \&Template::Plugin::Date::throw;
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $method = $AUTOLOAD;
|
||||
|
||||
$method =~ s/.*:://;
|
||||
return if $method eq 'DESTROY';
|
||||
|
||||
my $sub = \&{"Date::Calc::$method"};
|
||||
$self->throw("no such Date::Calc method: $method")
|
||||
unless $sub;
|
||||
|
||||
&$sub(@_);
|
||||
}
|
||||
|
||||
package Template::Plugin::Date::Manip;
|
||||
use base qw( Template::Plugin );
|
||||
our $AUTOLOAD;
|
||||
*throw = \&Template::Plugin::Date::throw;
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $method = $AUTOLOAD;
|
||||
|
||||
$method =~ s/.*:://;
|
||||
return if $method eq 'DESTROY';
|
||||
|
||||
my $sub = \&{"Date::Manip::$method"};
|
||||
$self->throw("no such Date::Manip method: $method")
|
||||
unless $sub;
|
||||
|
||||
&$sub(@_);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Date - Plugin to generate formatted date strings
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE date %]
|
||||
|
||||
# use current time and default format
|
||||
[% date.format %]
|
||||
|
||||
# specify time as seconds since epoch
|
||||
# or as a 'h:m:s d-m-y' or 'y-m-d h:m:s' string
|
||||
[% date.format(960973980) %]
|
||||
[% date.format('4:20:36 21/12/2000') %]
|
||||
[% date.format('2000/12/21 4:20:36') %]
|
||||
|
||||
# specify format
|
||||
[% date.format(mytime, '%H:%M:%S') %]
|
||||
|
||||
# specify locale
|
||||
[% date.format(date.now, '%a %d %b %y', 'en_GB') %]
|
||||
|
||||
# named parameters
|
||||
[% date.format(mytime, format = '%H:%M:%S') %]
|
||||
[% date.format(locale = 'en_GB') %]
|
||||
[% date.format(time = date.now,
|
||||
format = '%H:%M:%S',
|
||||
locale = 'en_GB'
|
||||
use_offset = 1) %]
|
||||
|
||||
# specify default format to plugin
|
||||
[% USE date(format = '%H:%M:%S', locale = 'de_DE') %]
|
||||
|
||||
[% date.format %]
|
||||
...
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<Date> plugin provides an easy way to generate formatted time and date
|
||||
strings by delegating to the C<POSIX> C<strftime()> routine.
|
||||
|
||||
The plugin can be loaded via the familiar USE directive.
|
||||
|
||||
[% USE date %]
|
||||
|
||||
This creates a plugin object with the default name of 'C<date>'. An alternate
|
||||
name can be specified as such:
|
||||
|
||||
[% USE myname = date %]
|
||||
|
||||
The plugin provides the C<format()> method which accepts a time value, a
|
||||
format string and a locale name. All of these parameters are optional
|
||||
with the current system time, default format ('C<%H:%M:%S %d-%b-%Y>') and
|
||||
current locale being used respectively, if undefined. Default values
|
||||
for the time, format and/or locale may be specified as named parameters
|
||||
in the C<USE> directive.
|
||||
|
||||
[% USE date(format = '%a %d-%b-%Y', locale = 'fr_FR') %]
|
||||
|
||||
When called without any parameters, the C<format()> method returns a string
|
||||
representing the current system time, formatted by C<strftime()> according
|
||||
to the default format and for the default locale (which may not be the
|
||||
current one, if locale is set in the C<USE> directive).
|
||||
|
||||
[% date.format %]
|
||||
|
||||
The plugin allows a time/date to be specified as seconds since the epoch,
|
||||
as is returned by C<time()>.
|
||||
|
||||
File last modified: [% date.format(filemod_time) %]
|
||||
|
||||
The time/date can also be specified as a string of the form C<h:m:s d/m/y>
|
||||
or C<y/m/d h:m:s>. Any of the characters : / - or space may be used to
|
||||
delimit fields.
|
||||
|
||||
[% USE day = date(format => '%A', locale => 'en_GB') %]
|
||||
[% day.format('4:20:00 9-13-2000') %]
|
||||
|
||||
Output:
|
||||
|
||||
Tuesday
|
||||
|
||||
A format string can also be passed to the C<format()> method, and a locale
|
||||
specification may follow that.
|
||||
|
||||
[% date.format(filemod, '%d-%b-%Y') %]
|
||||
[% date.format(filemod, '%d-%b-%Y', 'en_GB') %]
|
||||
|
||||
A fourth parameter allows you to force output in GMT, in the case of
|
||||
seconds-since-the-epoch input:
|
||||
|
||||
[% date.format(filemod, '%d-%b-%Y', 'en_GB', 1) %]
|
||||
|
||||
Note that in this case, if the local time is not GMT, then also specifying
|
||||
'C<%Z>' (time zone) in the format parameter will lead to an extremely
|
||||
misleading result.
|
||||
|
||||
To maintain backwards compatibility, using the C<%z> placeholder in the format
|
||||
string (to output the UTC offset) currently requires the C<use_offset>
|
||||
parameter to be set to a true value. This can also be passed as the fifth
|
||||
parameter to format (but the former will probably be clearer).
|
||||
|
||||
Any or all of these parameters may be named. Positional parameters
|
||||
should always be in the order C<($time, $format, $locale)>.
|
||||
|
||||
[% date.format(format => '%H:%M:%S') %]
|
||||
[% date.format(time => filemod, format => '%H:%M:%S') %]
|
||||
[% date.format(mytime, format => '%H:%M:%S') %]
|
||||
[% date.format(mytime, format => '%H:%M:%S', locale => 'fr_FR') %]
|
||||
[% date.format(mytime, format => '%H:%M:%S', gmt => 1) %]
|
||||
...etc...
|
||||
|
||||
The C<now()> method returns the current system time in seconds since the
|
||||
epoch.
|
||||
|
||||
[% date.format(date.now, '%A') %]
|
||||
|
||||
The C<calc()> method can be used to create an interface to the C<Date::Calc>
|
||||
module (if installed on your system).
|
||||
|
||||
[% calc = date.calc %]
|
||||
[% calc.Monday_of_Week(22, 2001).join('/') %]
|
||||
|
||||
The C<manip()> method can be used to create an interface to the C<Date::Manip>
|
||||
module (if installed on your system).
|
||||
|
||||
[% manip = date.manip %]
|
||||
[% manip.UnixDate("Noon Yesterday","%Y %b %d %H:%M") %]
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Thierry-Michel Barral wrote the original plugin.
|
||||
|
||||
Andy Wardley provided some minor
|
||||
fixups/enhancements, a test script and documentation.
|
||||
|
||||
Mark D. Mills cloned C<Date::Manip> from the C<Date::Calc> sub-plugin.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2000-2007 Thierry-Michel Barral, Andy Wardley.
|
||||
|
||||
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::Plugin>, L<POSIX>
|
||||
|
||||
386
database/perl/vendor/lib/Template/Plugin/Directory.pm
vendored
Normal file
386
database/perl/vendor/lib/Template/Plugin/Directory.pm
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Directory
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin for encapsulating information about a file system directory.
|
||||
#
|
||||
# AUTHORS
|
||||
# Michael Stevens <michael@etla.org>, with some mutilations from
|
||||
# Andy Wardley <abw@wardley.org>.
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Michael Stevens, Andy Wardley.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Directory;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd;
|
||||
use File::Spec;
|
||||
use Template::Plugin::File;
|
||||
use base 'Template::Plugin::File';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new(\%config)
|
||||
#
|
||||
# Constructor method.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { };
|
||||
my ($class, $context, $path) = @_;
|
||||
|
||||
return $class->throw('no directory specified')
|
||||
unless defined $path and length $path;
|
||||
|
||||
my $self = $class->SUPER::new($context, $path, $config);
|
||||
my ($dir, @files, $name, $item, $abs, $rel, $check);
|
||||
$self->{ files } = [ ];
|
||||
$self->{ dirs } = [ ];
|
||||
$self->{ list } = [ ];
|
||||
$self->{ _dir } = { };
|
||||
|
||||
# don't read directory if 'nostat' or 'noscan' set
|
||||
return $self if $config->{ nostat } || $config->{ noscan };
|
||||
|
||||
$self->throw("$path: not a directory")
|
||||
unless $self->{ isdir };
|
||||
|
||||
$self->scan($config);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# scan(\%config)
|
||||
#
|
||||
# Scan directory for files and sub-directories.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub scan {
|
||||
my ($self, $config) = @_;
|
||||
$config ||= { };
|
||||
local *DH;
|
||||
my ($dir, @files, $name, $abs, $rel, $item);
|
||||
|
||||
# set 'noscan' in config if recurse isn't set, to ensure Directories
|
||||
# created don't try to scan deeper
|
||||
$config->{ noscan } = 1 unless $config->{ recurse };
|
||||
|
||||
$dir = $self->{ abs };
|
||||
opendir(DH, $dir) or return $self->throw("$dir: $!");
|
||||
|
||||
@files = readdir DH;
|
||||
closedir(DH)
|
||||
or return $self->throw("$dir close: $!");
|
||||
|
||||
my ($path, $files, $dirs, $list) = @$self{ qw( path files dirs list ) };
|
||||
@$files = @$dirs = @$list = ();
|
||||
|
||||
foreach $name (sort @files) {
|
||||
next if $name =~ /^\./;
|
||||
$abs = File::Spec->catfile($dir, $name);
|
||||
$rel = File::Spec->catfile($path, $name);
|
||||
|
||||
if (-d $abs) {
|
||||
$item = Template::Plugin::Directory->new(undef, $rel, $config);
|
||||
push(@$dirs, $item);
|
||||
}
|
||||
else {
|
||||
$item = Template::Plugin::File->new(undef, $rel, $config);
|
||||
push(@$files, $item);
|
||||
}
|
||||
push(@$list, $item);
|
||||
$self->{ _dir }->{ $name } = $item;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# file($filename)
|
||||
#
|
||||
# Fetch a named file from this directory.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub file {
|
||||
my ($self, $name) = @_;
|
||||
return $self->{ _dir }->{ $name };
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# present($view)
|
||||
#
|
||||
# Present self to a Template::View
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub present {
|
||||
my ($self, $view) = @_;
|
||||
$view->view_directory($self);
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# content($view)
|
||||
#
|
||||
# Present directory content to a Template::View.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub content {
|
||||
my ($self, $view) = @_;
|
||||
return $self->{ list } unless $view;
|
||||
my $output = '';
|
||||
foreach my $file (@{ $self->{ list } }) {
|
||||
$output .= $file->present($view);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# throw($msg)
|
||||
#
|
||||
# Throw a 'Directory' exception.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub throw {
|
||||
my ($self, $error) = @_;
|
||||
die (Template::Exception->new('Directory', $error));
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Directory - Plugin for generating directory listings
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE dir = Directory(dirpath) %]
|
||||
|
||||
# files returns list of regular files
|
||||
[% FOREACH file = dir.files %]
|
||||
[% file.name %] [% file.path %] ...
|
||||
[% END %]
|
||||
|
||||
# dirs returns list of sub-directories
|
||||
[% FOREACH subdir = dir.dirs %]
|
||||
[% subdir.name %] [% subdir.path %] ...
|
||||
[% END %]
|
||||
|
||||
# list returns both interleaved in order
|
||||
[% FOREACH item = dir.list %]
|
||||
[% IF item.isdir %]
|
||||
Directory: [% item.name %]
|
||||
[% ELSE %]
|
||||
File: [% item.name %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
# define a VIEW to display dirs/files
|
||||
[% VIEW myview %]
|
||||
[% BLOCK file %]
|
||||
File: [% item.name %]
|
||||
[% END %]
|
||||
|
||||
[% BLOCK directory %]
|
||||
Directory: [% item.name %]
|
||||
[% item.content(myview) | indent -%]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
# display directory content using view
|
||||
[% myview.print(dir) %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This Template Toolkit plugin provides a simple interface to directory
|
||||
listings. It is derived from the L<Template::Plugin::File> module and
|
||||
uses L<Template::Plugin::File> object instances to represent files within
|
||||
a directory. Sub-directories within a directory are represented by
|
||||
further C<Template::Plugin::Directory> instances.
|
||||
|
||||
The constructor expects a directory name as an argument.
|
||||
|
||||
[% USE dir = Directory('/tmp') %]
|
||||
|
||||
It then provides access to the files and sub-directories contained within
|
||||
the directory.
|
||||
|
||||
# regular files (not directories)
|
||||
[% FOREACH file IN dir.files %]
|
||||
[% file.name %]
|
||||
[% END %]
|
||||
|
||||
# directories only
|
||||
[% FOREACH file IN dir.dirs %]
|
||||
[% file.name %]
|
||||
[% END %]
|
||||
|
||||
# files and/or directories
|
||||
[% FOREACH file IN dir.list %]
|
||||
[% file.name %] ([% file.isdir ? 'directory' : 'file' %])
|
||||
[% END %]
|
||||
|
||||
The plugin constructor will throw a C<Directory> error if the specified
|
||||
path does not exist, is not a directory or fails to C<stat()> (see
|
||||
L<Template::Plugin::File>). Otherwise, it will scan the directory and
|
||||
create lists named 'C<files>' containing files, 'C<dirs>' containing
|
||||
directories and 'C<list>' containing both files and directories combined.
|
||||
The C<nostat> option can be set to disable all file/directory checks
|
||||
and directory scanning.
|
||||
|
||||
Each file in the directory will be represented by a
|
||||
L<Template::Plugin::File> object instance, and each directory by another
|
||||
C<Template::Plugin::Directory>. If the C<recurse> flag is set, then those
|
||||
directories will contain further nested entries, and so on. With the
|
||||
C<recurse> flag unset, as it is by default, then each is just a place
|
||||
marker for the directory and does not contain any further content
|
||||
unless its C<scan()> method is explicitly called. The C<isdir> flag can
|
||||
be tested against files and/or directories, returning true if the item
|
||||
is a directory or false if it is a regular file.
|
||||
|
||||
[% FOREACH file = dir.list %]
|
||||
[% IF file.isdir %]
|
||||
* Directory: [% file.name %]
|
||||
[% ELSE %]
|
||||
* File: [% file.name %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
This example shows how you might walk down a directory tree, displaying
|
||||
content as you go. With the recurse flag disabled, as is the default,
|
||||
we need to explicitly call the C<scan()> method on each directory, to force
|
||||
it to lookup files and further sub-directories contained within.
|
||||
|
||||
[% USE dir = Directory(dirpath) %]
|
||||
* [% dir.path %]
|
||||
[% INCLUDE showdir %]
|
||||
|
||||
[% BLOCK showdir -%]
|
||||
[% FOREACH file = dir.list -%]
|
||||
[% IF file.isdir -%]
|
||||
* [% file.name %]
|
||||
[% file.scan -%]
|
||||
[% INCLUDE showdir dir=file FILTER indent(4) -%]
|
||||
[% ELSE -%]
|
||||
- [% f.name %]
|
||||
[% END -%]
|
||||
[% END -%]
|
||||
[% END %]
|
||||
|
||||
This example is adapted (with some re-formatting for clarity) from
|
||||
a test in F<t/directry.t> which produces the following output:
|
||||
|
||||
* test/dir
|
||||
- file1
|
||||
- file2
|
||||
* sub_one
|
||||
- bar
|
||||
- foo
|
||||
* sub_two
|
||||
- waz.html
|
||||
- wiz.html
|
||||
- xyzfile
|
||||
|
||||
The C<recurse> flag can be set (disabled by default) to cause the
|
||||
constructor to automatically recurse down into all sub-directories,
|
||||
creating a new C<Template::Plugin::Directory> object for each one and
|
||||
filling it with any further content. In this case there is no need
|
||||
to explicitly call the C<scan()> method.
|
||||
|
||||
[% USE dir = Directory(dirpath, recurse=1) %]
|
||||
...
|
||||
|
||||
[% IF file.isdir -%]
|
||||
* [% file.name %]
|
||||
[% INCLUDE showdir dir=file FILTER indent(4) -%]
|
||||
[% ELSE -%]
|
||||
...
|
||||
|
||||
The directory plugin also provides support for views. A view can be defined as
|
||||
a C<VIEW ... END> block and should contain C<BLOCK> definitions for files
|
||||
('C<file>') and directories ('C<directory>').
|
||||
|
||||
[% VIEW myview %]
|
||||
[% BLOCK file %]
|
||||
- [% item.name %]
|
||||
[% END %]
|
||||
|
||||
[% BLOCK directory %]
|
||||
* [% item.name %]
|
||||
[% item.content(myview) FILTER indent %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
The view C<print()> method can then be called, passing the
|
||||
C<Directory> object as an argument.
|
||||
|
||||
[% USE dir = Directory(dirpath, recurse=1) %]
|
||||
[% myview.print(dir) %]
|
||||
|
||||
When a directory is presented to a view, either as C<[% myview.print(dir) %]>
|
||||
or C<[% dir.present(view) %]>, then the C<directory> C<BLOCK> within the
|
||||
C<myview> C<VIEW> is processed. The C<item> variable will be set to alias the
|
||||
C<Directory> object.
|
||||
|
||||
[% BLOCK directory %]
|
||||
* [% item.name %]
|
||||
[% item.content(myview) FILTER indent %]
|
||||
[% END %]
|
||||
|
||||
In this example, the directory name is first printed and the content(view)
|
||||
method is then called to present each item within the directory to the view.
|
||||
Further directories will be mapped to the C<directory> block, and files will be
|
||||
mapped to the C<file> block.
|
||||
|
||||
With the recurse option disabled, as it is by default, the C<directory>
|
||||
block should explicitly call a C<scan()> on each directory.
|
||||
|
||||
[% VIEW myview %]
|
||||
[% BLOCK file %]
|
||||
- [% item.name %]
|
||||
[% END %]
|
||||
|
||||
[% BLOCK directory %]
|
||||
* [% item.name %]
|
||||
[% item.scan %]
|
||||
[% item.content(myview) FILTER indent %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[% USE dir = Directory(dirpath) %]
|
||||
[% myview.print(dir) %]
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Michael Stevens wrote the original Directory plugin on which this is based.
|
||||
Andy Wardley split it into separate L<File|Template::Plugin::File> and
|
||||
L<Directory|Template::Plugin::Directory> plugins, added some extra code and
|
||||
documentation for C<VIEW> support, and made a few other minor tweaks.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2000-2007 Michael Stevens, Andy Wardley.
|
||||
|
||||
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::Plugin>, L<Template::Plugin::File>, L<Template::View>
|
||||
|
||||
152
database/perl/vendor/lib/Template/Plugin/Dumper.pm
vendored
Normal file
152
database/perl/vendor/lib/Template/Plugin/Dumper.pm
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
#==============================================================================
|
||||
#
|
||||
# Template::Plugin::Dumper
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# A Template Plugin to provide a Template Interface to Data::Dumper
|
||||
#
|
||||
# AUTHOR
|
||||
# Simon Matthews <sam@tt2.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000 Simon Matthews. All Rights Reserved
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#==============================================================================
|
||||
|
||||
package Template::Plugin::Dumper;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Data::Dumper;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $DEBUG = 0 unless defined $DEBUG;
|
||||
our @DUMPER_ARGS = qw( Indent Pad Varname Purity Useqq Terse Freezer
|
||||
Toaster Deepcopy Quotekeys Bless Maxdepth Sortkeys );
|
||||
our $AUTOLOAD;
|
||||
|
||||
#==============================================================================
|
||||
# ----- CLASS METHODS -----
|
||||
#==============================================================================
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \@params)
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $params) = @_;
|
||||
my ($key, $val);
|
||||
$params ||= { };
|
||||
|
||||
|
||||
foreach my $arg (@DUMPER_ARGS) {
|
||||
no strict 'refs';
|
||||
if (defined ($val = $params->{ lc $arg })
|
||||
or defined ($val = $params->{ $arg })) {
|
||||
${"Data\::Dumper\::$arg"} = $val;
|
||||
}
|
||||
}
|
||||
|
||||
bless {
|
||||
_CONTEXT => $context,
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub dump {
|
||||
my $self = shift;
|
||||
my $content = Dumper @_;
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
sub dump_html {
|
||||
my $self = shift;
|
||||
my $content = Dumper @_;
|
||||
for ($content) {
|
||||
s/&/&/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
s/\n/<br>\n/g;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Dumper - Plugin interface to Data::Dumper
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE Dumper %]
|
||||
|
||||
[% Dumper.dump(variable) %]
|
||||
[% Dumper.dump_html(variable) %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a very simple Template Toolkit Plugin Interface to the L<Data::Dumper>
|
||||
module. A C<Dumper> object will be instantiated via the following directive:
|
||||
|
||||
[% USE Dumper %]
|
||||
|
||||
As a standard plugin, you can also specify its name in lower case:
|
||||
|
||||
[% USE dumper %]
|
||||
|
||||
The C<Data::Dumper> C<Pad>, C<Indent> and C<Varname> options are supported
|
||||
as constructor arguments to affect the output generated. See L<Data::Dumper>
|
||||
for further details.
|
||||
|
||||
[% USE dumper(Indent=0, Pad="<br>") %]
|
||||
|
||||
These options can also be specified in lower case.
|
||||
|
||||
[% USE dumper(indent=0, pad="<br>") %]
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
There are two methods supported by the C<Dumper> object. Each will
|
||||
output into the template the contents of the variables passed to the
|
||||
object method.
|
||||
|
||||
=head2 dump()
|
||||
|
||||
Generates a raw text dump of the data structure(s) passed
|
||||
|
||||
[% USE Dumper %]
|
||||
[% Dumper.dump(myvar) %]
|
||||
[% Dumper.dump(myvar, yourvar) %]
|
||||
|
||||
=head2 dump_html()
|
||||
|
||||
Generates a dump of the data structures, as per L<dump()>, but with the
|
||||
characters E<lt>, E<gt> and E<amp> converted to their equivalent HTML
|
||||
entities and newlines converted to E<lt>brE<gt>.
|
||||
|
||||
[% USE Dumper %]
|
||||
[% Dumper.dump_html(myvar) %]
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Simon Matthews E<lt>sam@tt2.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2000 Simon Matthews. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Data::Dumper>
|
||||
|
||||
391
database/perl/vendor/lib/Template/Plugin/File.pm
vendored
Normal file
391
database/perl/vendor/lib/Template/Plugin/File.pm
vendored
Normal file
@@ -0,0 +1,391 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::File
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin for encapsulating information about a system file.
|
||||
#
|
||||
# AUTHOR
|
||||
# Originally written by Michael Stevens <michael@etla.org> as the
|
||||
# Directory plugin, then mutilated by Andy Wardley <abw@kfs.org>
|
||||
# into separate File and Directory plugins, with some additional
|
||||
# code for working with views, etc.
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright 2000-2007 Michael Stevens, Andy Wardley.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::File;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd;
|
||||
use File::Spec;
|
||||
use File::Basename;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
our @STAT_KEYS = qw( dev ino mode nlink uid gid rdev size
|
||||
atime mtime ctime blksize blocks );
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, $file, \%config)
|
||||
#
|
||||
# Create a new File object. Takes the pathname of the file as
|
||||
# the argument following the context and an optional
|
||||
# hash reference of configuration parameters.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { };
|
||||
my ($class, $context, $path) = @_;
|
||||
my ($root, $home, @stat, $abs);
|
||||
|
||||
return $class->throw('no file specified')
|
||||
unless defined $path and length $path;
|
||||
|
||||
# path, dir, name, root, home
|
||||
|
||||
if (File::Spec->file_name_is_absolute($path)) {
|
||||
$root = '';
|
||||
}
|
||||
elsif (($root = $config->{ root })) {
|
||||
# strip any trailing '/' from root
|
||||
$root =~ s[/$][];
|
||||
}
|
||||
else {
|
||||
$root = '';
|
||||
}
|
||||
|
||||
my ($name, $dir, $ext) = fileparse($path, '\.\w+');
|
||||
# fixup various items
|
||||
$dir =~ s[/$][];
|
||||
$dir = '' if $dir eq '.';
|
||||
$name = $name . $ext;
|
||||
$ext =~ s/^\.//g;
|
||||
|
||||
my @fields = File::Spec->splitdir($dir);
|
||||
shift @fields if @fields && ! length $fields[0];
|
||||
$home = join('/', ('..') x @fields);
|
||||
$abs = File::Spec->catfile($root ? $root : (), $path);
|
||||
|
||||
my $self = {
|
||||
path => $path,
|
||||
name => $name,
|
||||
root => $root,
|
||||
home => $home,
|
||||
dir => $dir,
|
||||
ext => $ext,
|
||||
abs => $abs,
|
||||
user => '',
|
||||
group => '',
|
||||
isdir => '',
|
||||
stat => defined $config->{ stat }
|
||||
? $config->{ stat }
|
||||
: ! $config->{ nostat },
|
||||
map { ($_ => '') } @STAT_KEYS,
|
||||
};
|
||||
|
||||
if ($self->{ stat }) {
|
||||
(@stat = stat( $abs ))
|
||||
|| return $class->throw("$abs: $!");
|
||||
|
||||
@$self{ @STAT_KEYS } = @stat;
|
||||
|
||||
unless ($config->{ noid }) {
|
||||
$self->{ user } = eval { getpwuid( $self->{ uid }) || $self->{ uid } };
|
||||
$self->{ group } = eval { getgrgid( $self->{ gid }) || $self->{ gid } };
|
||||
}
|
||||
$self->{ isdir } = -d $abs;
|
||||
}
|
||||
|
||||
bless $self, $class;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# rel($file)
|
||||
#
|
||||
# Generate a relative filename for some other file relative to this one.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub rel {
|
||||
my ($self, $path) = @_;
|
||||
$path = $path->{ path } if ref $path eq ref $self; # assumes same root
|
||||
return $path if $path =~ m[^/];
|
||||
return $path unless $self->{ home };
|
||||
return $self->{ home } . '/' . $path;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# present($view)
|
||||
#
|
||||
# Present self to a Template::View.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub present {
|
||||
my ($self, $view) = @_;
|
||||
$view->view_file($self);
|
||||
}
|
||||
|
||||
|
||||
sub throw {
|
||||
my ($self, $error) = @_;
|
||||
die (Template::Exception->new('File', $error));
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::File - Plugin providing information about files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE File(filepath) %]
|
||||
[% File.path %] # full path
|
||||
[% File.name %] # filename
|
||||
[% File.dir %] # directory
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin provides an abstraction of a file. It can be used to
|
||||
fetch details about files from the file system, or to represent abstract
|
||||
files (e.g. when creating an index page) that may or may not exist on
|
||||
a file system.
|
||||
|
||||
A file name or path should be specified as a constructor argument. e.g.
|
||||
|
||||
[% USE File('foo.html') %]
|
||||
[% USE File('foo/bar/baz.html') %]
|
||||
[% USE File('/foo/bar/baz.html') %]
|
||||
|
||||
The file should exist on the current file system (unless C<nostat>
|
||||
option set, see below) as an absolute file when specified with as
|
||||
leading 'C</>' as per 'C</foo/bar/baz.html>', or otherwise as one relative
|
||||
to the current working directory. The constructor performs a C<stat()>
|
||||
on the file and makes the 13 elements returned available as the plugin
|
||||
items:
|
||||
|
||||
dev ino mode nlink uid gid rdev size
|
||||
atime mtime ctime blksize blocks
|
||||
|
||||
e.g.
|
||||
|
||||
[% USE File('/foo/bar/baz.html') %]
|
||||
|
||||
[% File.mtime %]
|
||||
[% File.mode %]
|
||||
...
|
||||
|
||||
In addition, the C<user> and C<group> items are set to contain the user
|
||||
and group names as returned by calls to C<getpwuid()> and C<getgrgid()> for
|
||||
the file C<uid> and C<gid> elements, respectively. On Win32 platforms
|
||||
on which C<getpwuid()> and C<getgrid()> are not available, these values are
|
||||
undefined.
|
||||
|
||||
[% USE File('/tmp/foo.html') %]
|
||||
[% File.uid %] # e.g. 500
|
||||
[% File.user %] # e.g. abw
|
||||
|
||||
This user/group lookup can be disabled by setting the C<noid> option.
|
||||
|
||||
[% USE File('/tmp/foo.html', noid=1) %]
|
||||
[% File.uid %] # e.g. 500
|
||||
[% File.user %] # nothing
|
||||
|
||||
The C<isdir> flag will be set if the file is a directory.
|
||||
|
||||
[% USE File('/tmp') %]
|
||||
[% File.isdir %] # 1
|
||||
|
||||
If the C<stat()> on the file fails (e.g. file doesn't exists, bad
|
||||
permission, etc) then the constructor will throw a C<File> exception.
|
||||
This can be caught within a C<TRY...CATCH> block.
|
||||
|
||||
[% TRY %]
|
||||
[% USE File('/tmp/myfile') %]
|
||||
File exists!
|
||||
[% CATCH File %]
|
||||
File error: [% error.info %]
|
||||
[% END %]
|
||||
|
||||
Note the capitalisation of the exception type, 'C<File>', to indicate an
|
||||
error thrown by the C<File> plugin, to distinguish it from a regular
|
||||
C<file> exception thrown by the Template Toolkit.
|
||||
|
||||
Note that the C<File> plugin can also be referenced by the lower case
|
||||
name 'C<file>'. However, exceptions are always thrown of the C<File>
|
||||
type, regardless of the capitalisation of the plugin named used.
|
||||
|
||||
[% USE file('foo.html') %]
|
||||
[% file.mtime %]
|
||||
|
||||
As with any other Template Toolkit plugin, an alternate name can be
|
||||
specified for the object created.
|
||||
|
||||
[% USE foo = file('foo.html') %]
|
||||
[% foo.mtime %]
|
||||
|
||||
The C<nostat> option can be specified to prevent the plugin constructor
|
||||
from performing a C<stat()> on the file specified. In this case, the
|
||||
file does not have to exist in the file system, no attempt will be made
|
||||
to verify that it does, and no error will be thrown if it doesn't.
|
||||
The entries for the items usually returned by C<stat()> will be set
|
||||
empty.
|
||||
|
||||
[% USE file('/some/where/over/the/rainbow.html', nostat=1)
|
||||
[% file.mtime %] # nothing
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
All C<File> plugins, regardless of the C<nostat> option, have set a number
|
||||
of items relating to the original path specified.
|
||||
|
||||
=head2 path
|
||||
|
||||
The full, original file path specified to the constructor.
|
||||
|
||||
[% USE file('/foo/bar.html') %]
|
||||
[% file.path %] # /foo/bar.html
|
||||
|
||||
=head2 name
|
||||
|
||||
The name of the file without any leading directories.
|
||||
|
||||
[% USE file('/foo/bar.html') %]
|
||||
[% file.name %] # bar.html
|
||||
|
||||
=head2 dir
|
||||
|
||||
The directory element of the path with the filename removed.
|
||||
|
||||
[% USE file('/foo/bar.html') %]
|
||||
[% file.name %] # /foo
|
||||
|
||||
=head2 ext
|
||||
|
||||
The file extension, if any, appearing at the end of the path following
|
||||
a 'C<.>' (not included in the extension).
|
||||
|
||||
[% USE file('/foo/bar.html') %]
|
||||
[% file.ext %] # html
|
||||
|
||||
=head2 home
|
||||
|
||||
This contains a string of the form 'C<../..>' to represent the upward path
|
||||
from a file to its root directory.
|
||||
|
||||
[% USE file('bar.html') %]
|
||||
[% file.home %] # nothing
|
||||
|
||||
[% USE file('foo/bar.html') %]
|
||||
[% file.home %] # ..
|
||||
|
||||
[% USE file('foo/bar/baz.html') %]
|
||||
[% file.home %] # ../..
|
||||
|
||||
=head2 root
|
||||
|
||||
The C<root> item can be specified as a constructor argument, indicating
|
||||
a root directory in which the named file resides. This is otherwise
|
||||
set empty.
|
||||
|
||||
[% USE file('foo/bar.html', root='/tmp') %]
|
||||
[% file.root %] # /tmp
|
||||
|
||||
=head2 abs
|
||||
|
||||
This returns the absolute file path by constructing a path from the
|
||||
C<root> and C<path> options.
|
||||
|
||||
[% USE file('foo/bar.html', root='/tmp') %]
|
||||
[% file.path %] # foo/bar.html
|
||||
[% file.root %] # /tmp
|
||||
[% file.abs %] # /tmp/foo/bar.html
|
||||
|
||||
=head2 rel(path)
|
||||
|
||||
This returns a relative path from the current file to another path specified
|
||||
as an argument. It is constructed by appending the path to the 'C<home>'
|
||||
item.
|
||||
|
||||
[% USE file('foo/bar/baz.html') %]
|
||||
[% file.rel('wiz/waz.html') %] # ../../wiz/waz.html
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
[% USE file('/foo/bar/baz.html') %]
|
||||
|
||||
[% file.path %] # /foo/bar/baz.html
|
||||
[% file.dir %] # /foo/bar
|
||||
[% file.name %] # baz.html
|
||||
[% file.home %] # ../..
|
||||
[% file.root %] # ''
|
||||
[% file.abs %] # /foo/bar/baz.html
|
||||
[% file.ext %] # html
|
||||
[% file.mtime %] # 987654321
|
||||
[% file.atime %] # 987654321
|
||||
[% file.uid %] # 500
|
||||
[% file.user %] # abw
|
||||
|
||||
[% USE file('foo.html') %]
|
||||
|
||||
[% file.path %] # foo.html
|
||||
[% file.dir %] # ''
|
||||
[% file.name %] # foo.html
|
||||
[% file.root %] # ''
|
||||
[% file.home %] # ''
|
||||
[% file.abs %] # foo.html
|
||||
|
||||
[% USE file('foo/bar/baz.html') %]
|
||||
|
||||
[% file.path %] # foo/bar/baz.html
|
||||
[% file.dir %] # foo/bar
|
||||
[% file.name %] # baz.html
|
||||
[% file.root %] # ''
|
||||
[% file.home %] # ../..
|
||||
[% file.abs %] # foo/bar/baz.html
|
||||
|
||||
[% USE file('foo/bar/baz.html', root='/tmp') %]
|
||||
|
||||
[% file.path %] # foo/bar/baz.html
|
||||
[% file.dir %] # foo/bar
|
||||
[% file.name %] # baz.html
|
||||
[% file.root %] # /tmp
|
||||
[% file.home %] # ../..
|
||||
[% file.abs %] # /tmp/foo/bar/baz.html
|
||||
|
||||
# calculate other file paths relative to this file and its root
|
||||
[% USE file('foo/bar/baz.html', root => '/tmp/tt2') %]
|
||||
|
||||
[% file.path('baz/qux.html') %] # ../../baz/qux.html
|
||||
[% file.dir('wiz/woz.html') %] # ../../wiz/woz.html
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Michael Stevens wrote the original C<Directory> plugin on which this is based.
|
||||
Andy Wardley split it into separate C<File> and C<Directory> plugins, added
|
||||
some extra code and documentation for C<VIEW> support, and made a few other
|
||||
minor tweaks.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2000-2007 Michael Stevens, Andy Wardley.
|
||||
|
||||
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::Plugin>, L<Template::Plugin::Directory>, L<Template::View>
|
||||
|
||||
406
database/perl/vendor/lib/Template/Plugin/Filter.pm
vendored
Normal file
406
database/perl/vendor/lib/Template/Plugin/Filter.pm
vendored
Normal file
@@ -0,0 +1,406 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Filter
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit module implementing a base class plugin
|
||||
# object which acts like a filter and can be used with the
|
||||
# FILTER directive.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2001-2019 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Filter;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Scalar::Util 'weaken', 'isweak';
|
||||
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $DYNAMIC = 0 unless defined $DYNAMIC;
|
||||
|
||||
|
||||
sub new {
|
||||
my ($class, $context, @args) = @_;
|
||||
my $config = @args && ref $args[-1] eq 'HASH' ? pop(@args) : { };
|
||||
|
||||
# look for $DYNAMIC
|
||||
my $dynamic;
|
||||
{
|
||||
no strict 'refs';
|
||||
$dynamic = ${"$class\::DYNAMIC"};
|
||||
}
|
||||
$dynamic = $DYNAMIC unless defined $dynamic;
|
||||
|
||||
my $self = bless {
|
||||
_CONTEXT => $context,
|
||||
_DYNAMIC => $dynamic,
|
||||
_ARGS => \@args,
|
||||
_CONFIG => $config,
|
||||
}, $class;
|
||||
|
||||
return $self->init($config)
|
||||
|| $class->error($self->error());
|
||||
}
|
||||
|
||||
|
||||
sub init {
|
||||
my ($self, $config) = @_;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub factory {
|
||||
my $self = shift;
|
||||
my $this = $self;
|
||||
|
||||
# avoid a memory leak
|
||||
weaken( $this->{_CONTEXT} ) if ref $this->{_CONTEXT}
|
||||
&& !isweak $this->{_CONTEXT};
|
||||
|
||||
if ($self->{ _DYNAMIC }) {
|
||||
return [ sub {
|
||||
my ($context, @args) = @_;
|
||||
my $config = ref $args[-1] eq 'HASH' ? pop(@args) : { };
|
||||
|
||||
return sub {
|
||||
$this->filter(shift, \@args, $config);
|
||||
};
|
||||
}, 1 ];
|
||||
}
|
||||
else {
|
||||
return sub {
|
||||
$this->filter(shift);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
sub filter {
|
||||
my ($self, $text, $args, $config) = @_;
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
sub merge_config {
|
||||
my ($self, $newcfg) = @_;
|
||||
my $owncfg = $self->{ _CONFIG };
|
||||
return $owncfg unless $newcfg;
|
||||
return { %$owncfg, %$newcfg };
|
||||
}
|
||||
|
||||
|
||||
sub merge_args {
|
||||
my ($self, $newargs) = @_;
|
||||
my $ownargs = $self->{ _ARGS };
|
||||
return $ownargs unless $newargs;
|
||||
return [ @$ownargs, @$newargs ];
|
||||
}
|
||||
|
||||
|
||||
sub install_filter {
|
||||
my ($self, $name) = @_;
|
||||
$self->{ _CONTEXT }->define_filter( $name => $self->factory );
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Filter - Base class for plugin filters
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
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 %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module implements a base class for plugin filters. It hides
|
||||
the underlying complexity involved in creating and using filters
|
||||
that get defined and made available by loading a plugin.
|
||||
|
||||
To use the module, simply create your own plugin module that is
|
||||
inherited from the C<Template::Plugin::Filter> class.
|
||||
|
||||
package MyOrg::Template::Plugin::MyFilter;
|
||||
|
||||
use Template::Plugin::Filter;
|
||||
use base qw( Template::Plugin::Filter );
|
||||
|
||||
Then simply define your C<filter()> method. When called, you get
|
||||
passed a reference to your plugin object (C<$self>) and the text
|
||||
to be filtered.
|
||||
|
||||
sub filter {
|
||||
my ($self, $text) = @_;
|
||||
|
||||
# ...mungify $text...
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
To use your custom plugin, you have to make sure that the Template
|
||||
Toolkit knows about your plugin namespace.
|
||||
|
||||
my $tt2 = Template->new({
|
||||
PLUGIN_BASE => 'MyOrg::Template::Plugin',
|
||||
});
|
||||
|
||||
Or for individual plugins you can do it like this:
|
||||
|
||||
my $tt2 = Template->new({
|
||||
PLUGINS => {
|
||||
MyFilter => 'MyOrg::Template::Plugin::MyFilter',
|
||||
},
|
||||
});
|
||||
|
||||
Then you C<USE> your plugin in the normal way.
|
||||
|
||||
[% USE MyFilter %]
|
||||
|
||||
The object returned is stored in the variable of the same name,
|
||||
'C<MyFilter>'. When you come to use it as a C<FILTER>, you should add
|
||||
a dollar prefix. This indicates that you want to use the filter
|
||||
stored in the variable 'C<MyFilter>' rather than the filter named
|
||||
'C<MyFilter>', which is an entirely different thing (see later for
|
||||
information on defining filters by name).
|
||||
|
||||
[% FILTER $MyFilter %]
|
||||
...text to be filtered...
|
||||
[% END %]
|
||||
|
||||
You can, of course, assign it to a different variable.
|
||||
|
||||
[% USE blat = MyFilter %]
|
||||
|
||||
[% FILTER $blat %]
|
||||
...text to be filtered...
|
||||
[% END %]
|
||||
|
||||
Any configuration parameters passed to the plugin constructor from the
|
||||
C<USE> directive are stored internally in the object for inspection by
|
||||
the C<filter()> method (or indeed any other method). Positional
|
||||
arguments are stored as a reference to a list in the C<_ARGS> item while
|
||||
named configuration parameters are stored as a reference to a hash
|
||||
array in the C<_CONFIG> item.
|
||||
|
||||
For example, loading a plugin as shown here:
|
||||
|
||||
[% USE blat = MyFilter 'foo' 'bar' baz = 'blam' %]
|
||||
|
||||
would allow the C<filter()> method to do something like this:
|
||||
|
||||
sub filter {
|
||||
my ($self, $text) = @_;
|
||||
|
||||
my $args = $self->{ _ARGS }; # [ 'foo', 'bar' ]
|
||||
my $conf = $self->{ _CONFIG }; # { baz => 'blam' }
|
||||
|
||||
# ...munge $text...
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
By default, plugins derived from this module will create static
|
||||
filters. A static filter is created once when the plugin gets
|
||||
loaded via the C<USE> directive and re-used for all subsequent
|
||||
C<FILTER> operations. That means that any argument specified with
|
||||
the C<FILTER> directive are ignored.
|
||||
|
||||
Dynamic filters, on the other hand, are re-created each time
|
||||
they are used by a C<FILTER> directive. This allows them to act
|
||||
on any parameters passed from the C<FILTER> directive and modify
|
||||
their behaviour accordingly.
|
||||
|
||||
There are two ways to create a dynamic filter. The first is to
|
||||
define a C<$DYNAMIC> class variable set to a true value.
|
||||
|
||||
package MyOrg::Template::Plugin::MyFilter;
|
||||
use base 'Template::Plugin::Filter';
|
||||
our $DYNAMIC = 1;
|
||||
|
||||
The other way is to set the internal C<_DYNAMIC> value within the C<init()>
|
||||
method which gets called by the C<new()> constructor.
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
$self->{ _DYNAMIC } = 1;
|
||||
return $self;
|
||||
}
|
||||
|
||||
When this is set to a true value, the plugin will automatically
|
||||
create a dynamic filter. The outcome is that the C<filter()> method
|
||||
will now also get passed a reference to an array of positional
|
||||
arguments and a reference to a hash array of named parameters.
|
||||
|
||||
So, using a plugin filter like this:
|
||||
|
||||
[% FILTER $blat 'foo' 'bar' baz = 'blam' %]
|
||||
|
||||
would allow the C<filter()> method to work like this:
|
||||
|
||||
sub filter {
|
||||
my ($self, $text, $args, $conf) = @_;
|
||||
|
||||
# $args = [ 'foo', 'bar' ]
|
||||
# $conf = { baz => 'blam' }
|
||||
}
|
||||
|
||||
In this case can pass parameters to both the USE and FILTER directives,
|
||||
so your filter() method should probably take that into account.
|
||||
|
||||
[% USE MyFilter 'foo' wiz => 'waz' %]
|
||||
|
||||
[% FILTER $MyFilter 'bar' biz => 'baz' %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
You can use the C<merge_args()> and C<merge_config()> methods to do a quick
|
||||
and easy job of merging the local (e.g. C<FILTER>) parameters with the
|
||||
internal (e.g. C<USE>) values and returning new sets of conglomerated
|
||||
data.
|
||||
|
||||
sub filter {
|
||||
my ($self, $text, $args, $conf) = @_;
|
||||
|
||||
$args = $self->merge_args($args);
|
||||
$conf = $self->merge_config($conf);
|
||||
|
||||
# $args = [ 'foo', 'bar' ]
|
||||
# $conf = { wiz => 'waz', biz => 'baz' }
|
||||
...
|
||||
}
|
||||
|
||||
You can also have your plugin install itself as a named filter by
|
||||
calling the C<install_filter()> method from the C<init()> method. You
|
||||
should provide a name for the filter, something that you might
|
||||
like to make a configuration option.
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
my $name = $self->{ _CONFIG }->{ name } || 'myfilter';
|
||||
$self->install_filter($name);
|
||||
return $self;
|
||||
}
|
||||
|
||||
This allows the plugin filter to be used as follows:
|
||||
|
||||
[% USE MyFilter %]
|
||||
|
||||
[% FILTER myfilter %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
or
|
||||
|
||||
[% USE MyFilter name = 'swipe' %]
|
||||
|
||||
[% FILTER swipe %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
Alternately, you can allow a filter name to be specified as the
|
||||
first positional argument.
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
my $name = $self->{ _ARGS }->[0] || 'myfilter';
|
||||
$self->install_filter($name);
|
||||
return $self;
|
||||
}
|
||||
|
||||
[% USE MyFilter 'swipe' %]
|
||||
|
||||
[% FILTER swipe %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
Here's a complete example of a plugin filter module.
|
||||
|
||||
package My::Template::Plugin::Change;
|
||||
use Template::Plugin::Filter;
|
||||
use base qw( Template::Plugin::Filter );
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
|
||||
$self->{ _DYNAMIC } = 1;
|
||||
|
||||
# first arg can specify filter name
|
||||
$self->install_filter($self->{ _ARGS }->[0] || 'change');
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub filter {
|
||||
my ($self, $text, $args, $config) = @_;
|
||||
|
||||
$config = $self->merge_config($config);
|
||||
my $regex = join('|', keys %$config);
|
||||
|
||||
$text =~ s/($regex)/$config->{ $1 }/ge;
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2020 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Template::Filters>, L<Template::Manual::Filters>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
93
database/perl/vendor/lib/Template/Plugin/Format.pm
vendored
Normal file
93
database/perl/vendor/lib/Template/Plugin/Format.pm
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Format
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Simple Template Toolkit Plugin which creates formatting functions.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Format;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $format) = @_;;
|
||||
return defined $format
|
||||
? make_formatter($format)
|
||||
: \&make_formatter;
|
||||
}
|
||||
|
||||
|
||||
sub make_formatter {
|
||||
my $format = shift;
|
||||
$format = '%s' unless defined $format;
|
||||
return sub {
|
||||
my @args = @_;
|
||||
push(@args, '') unless @args;
|
||||
return sprintf($format, @args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Format - Plugin to create formatting functions
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE format %]
|
||||
[% commented = format('# %s') %]
|
||||
[% commented('The cat sat on the mat') %]
|
||||
|
||||
[% USE bold = format('<b>%s</b>') %]
|
||||
[% bold('Hello') %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The format plugin constructs sub-routines which format text according to
|
||||
a C<printf()>-like format string.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
251
database/perl/vendor/lib/Template/Plugin/HTML.pm
vendored
Normal file
251
database/perl/vendor/lib/Template/Plugin/HTML.pm
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::HTML
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit plugin providing useful functionality for generating
|
||||
# HTML.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::HTML;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
sub new {
|
||||
my ($class, $context, @args) = @_;
|
||||
my $hash = ref $args[-1] eq 'HASH' ? pop @args : { };
|
||||
bless {
|
||||
_SORTED => $hash->{ sorted } || 0,
|
||||
attributes => $hash->{ attributes } || $hash->{ attrs } || { },
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub element {
|
||||
my ($self, $name, $attr) = @_;
|
||||
($name, $attr) = %$name if ref $name eq 'HASH';
|
||||
return '' unless defined $name and length $name;
|
||||
$attr = $self->attributes($attr);
|
||||
$attr = " $attr" if $attr;
|
||||
return "<$name$attr>";
|
||||
}
|
||||
|
||||
sub closed_element {
|
||||
my ($self, $name, $attr) = @_;
|
||||
($name, $attr) = %$name if ref $name eq 'HASH';
|
||||
return '' unless defined $name and length $name;
|
||||
$attr = $self->attributes( $attr );
|
||||
$attr = " $attr" if $attr;
|
||||
return "<$name$attr />";
|
||||
}
|
||||
|
||||
sub attributes {
|
||||
my ($self, $hash) = @_;
|
||||
$hash ||= $self->{ attributes };
|
||||
return '' unless ref $hash eq 'HASH';
|
||||
|
||||
my @keys = keys %$hash;
|
||||
@keys = sort @keys if $self->{ _SORTED };
|
||||
|
||||
join(' ', map {
|
||||
"$_=\"" . $self->escape( $hash->{ $_ } ) . '"';
|
||||
} @keys);
|
||||
}
|
||||
|
||||
sub add_attributes {
|
||||
my ($self, $attr) = @_;
|
||||
return unless ref $attr eq 'HASH';
|
||||
|
||||
my $cur = $self->{ attributes };
|
||||
|
||||
for (keys %{$attr}) {
|
||||
$cur->{$_} = exists $cur->{$_}
|
||||
? $cur->{$_} . " $attr->{$_}"
|
||||
: $attr->{$_};
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*add_attribute = \&add_attributes;
|
||||
*add = \&add_attributes;
|
||||
|
||||
|
||||
sub replace_attributes {
|
||||
my ($self, $attr) = @_;
|
||||
return unless ref $attr eq 'HASH';
|
||||
|
||||
my $cur = $self->{ attributes };
|
||||
|
||||
for (keys %{$attr}) {
|
||||
$cur->{$_} = $attr->{$_};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
*replace_attribute = \&replace_attributes;
|
||||
*replace = \&replace_attributes;
|
||||
|
||||
sub clear_attributes {
|
||||
my $self = shift;
|
||||
$self->{ attributes } = { };
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sub escape {
|
||||
my ($self, $text) = @_;
|
||||
for ($text) {
|
||||
s/&/&/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
s/"/"/g;
|
||||
}
|
||||
$text;
|
||||
}
|
||||
|
||||
sub url {
|
||||
my ($self, $text) = @_;
|
||||
return undef unless defined $text;
|
||||
$text =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::HTML - Plugin to create HTML elements
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE HTML %]
|
||||
|
||||
[% HTML.escape("if (a < b && c > d) ..." %]
|
||||
|
||||
[% HTML.element(table => { border => 1, cellpadding => 2 }) %]
|
||||
|
||||
[% HTML.attributes(border => 1, cellpadding => 2) %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<HTML> plugin is a very basic plugin, implementing a few useful
|
||||
methods for generating HTML.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 escape(text)
|
||||
|
||||
Returns the source text with any HTML reserved characters such as
|
||||
C<E<lt>>, C<E<gt>>, etc., correctly escaped to their entity equivalents.
|
||||
|
||||
=head2 attributes(hash)
|
||||
|
||||
Returns the elements of the hash array passed by reference correctly
|
||||
formatted (e.g. values quoted and correctly escaped) as attributes for
|
||||
an HTML element.
|
||||
|
||||
=head2 add_attribute(attributes)
|
||||
|
||||
This provides a way to incrementally add attributes to the object.
|
||||
The values passed in are stored in the object. Calling
|
||||
L<element> with just a tag or L<attributes> without an parameters
|
||||
will used the saved attributes.
|
||||
|
||||
USE tag = HTML;
|
||||
tag.add_attributes( { class => 'navbar' } );
|
||||
tag.add_attributes( { id => 'foo' } );
|
||||
tag.add_attributes( { class => 'active' } );
|
||||
|
||||
tag.element( 'li' ); # <li class="navbar active" id="foo">
|
||||
|
||||
This method has two aliases: add_attribute() and add().
|
||||
|
||||
=head2 replace_attribute(attributes)
|
||||
|
||||
This will replace an attribute value instead of add to existing.
|
||||
|
||||
|
||||
USE tag = HTML;
|
||||
tag.add_attributes( { class => 'navbar' } );
|
||||
tag.add_attributes( { id => 'foo' } );
|
||||
tag.replace_attributes( { class => 'active' } );
|
||||
|
||||
tag.element( 'li' ); # <li class="active" id="foo">
|
||||
|
||||
This method has two aliases: replace_attribute() and replace().
|
||||
|
||||
=head2 clear_attributes
|
||||
|
||||
Clears any saved attributes
|
||||
|
||||
=head2 element(type, attributes)
|
||||
|
||||
Generates an HTML element of the specified type and with the attributes
|
||||
provided as an optional hash array reference as the second argument or
|
||||
as named arguments.
|
||||
|
||||
[% HTML.element(table => { border => 1, cellpadding => 2 }) %]
|
||||
[% HTML.element('table', border=1, cellpadding=2) %]
|
||||
[% HTML.element(table => attribs) %]
|
||||
|
||||
=head1 DEBUGGING
|
||||
|
||||
The HTML plugin accepts a C<sorted> option as a constructor argument
|
||||
which, when set to any true value, causes the attributes generated by
|
||||
the C<attributes()> method (either directly or via C<element()>) to be
|
||||
returned in sorted order. Order of attributes isn't important in
|
||||
HTML, but this is provided mainly for the purposes of debugging where
|
||||
it is useful to have attributes generated in a deterministic order
|
||||
rather than whatever order the hash happened to feel like returning
|
||||
the keys in.
|
||||
|
||||
[% USE HTML(sorted=1) %]
|
||||
[% HTML.element( foo => { charlie => 1, bravo => 2, alpha => 3 } ) %]
|
||||
|
||||
generates:
|
||||
|
||||
<foo alpha="3" bravo="2" charlie="1">
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
436
database/perl/vendor/lib/Template/Plugin/Image.pm
vendored
Normal file
436
database/perl/vendor/lib/Template/Plugin/Image.pm
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Image
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin for encapsulating information about an image.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Image;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Template::Exception;
|
||||
use File::Spec;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $AUTOLOAD;
|
||||
|
||||
BEGIN {
|
||||
if (eval { require Image::Info; }) {
|
||||
*img_info = \&Image::Info::image_info;
|
||||
}
|
||||
elsif (eval { require Image::Size; }) {
|
||||
*img_info = sub {
|
||||
my $file = shift;
|
||||
my @stuff = Image::Size::imgsize($file);
|
||||
return { "width" => $stuff[0],
|
||||
"height" => $stuff[1],
|
||||
"error" =>
|
||||
# imgsize returns either a three letter file type
|
||||
# or an error message as third value
|
||||
(defined($stuff[2]) && length($stuff[2]) > 3
|
||||
? $stuff[2]
|
||||
: undef),
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
die(Template::Exception->new("image",
|
||||
"Couldn't load Image::Info or Image::Size: $@"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, $name, \%config)
|
||||
#
|
||||
# Create a new Image object. Takes the pathname of the file as
|
||||
# the argument following the context and an optional
|
||||
# hash reference of configuration parameters.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { };
|
||||
my ($class, $context, $name) = @_;
|
||||
my ($root, $file, $type);
|
||||
|
||||
# name can be a positional or named argument
|
||||
$name = $config->{ name } unless defined $name;
|
||||
|
||||
return $class->throw('no image file specified')
|
||||
unless defined $name and length $name;
|
||||
|
||||
# name can be specified as an absolute path or relative
|
||||
# to a root directory
|
||||
|
||||
if ($root = $config->{ root }) {
|
||||
$file = File::Spec->catfile($root, $name);
|
||||
}
|
||||
else {
|
||||
$file = defined $config->{file} ? $config->{file} : $name;
|
||||
}
|
||||
|
||||
# Make a note of whether we are using Image::Size or
|
||||
# Image::Info -- at least for the test suite
|
||||
$type = $INC{"Image/Size.pm"} ? "Image::Size" : "Image::Info";
|
||||
|
||||
# set a default (empty) alt attribute for tag()
|
||||
$config->{ alt } = '' unless defined $config->{ alt };
|
||||
|
||||
# do we want to check to see if file exists?
|
||||
bless {
|
||||
%$config,
|
||||
name => $name,
|
||||
file => $file,
|
||||
root => $root,
|
||||
type => $type,
|
||||
}, $class;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# init()
|
||||
#
|
||||
# Calls image_info on $self->{ file }
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub init {
|
||||
my $self = shift;
|
||||
return $self if $self->{ size };
|
||||
|
||||
my $image = img_info($self->{ file });
|
||||
return $self->throw($image->{ error }) if defined $image->{ error };
|
||||
|
||||
@$self{ keys %$image } = values %$image;
|
||||
$self->{ size } = [ $image->{ width }, $image->{ height } ];
|
||||
|
||||
$self->{ modtime } = (stat $self->{ file })[10];
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# attr()
|
||||
#
|
||||
# Return the width and height as HTML/XML attributes.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub attr {
|
||||
my $self = shift;
|
||||
my $size = $self->size();
|
||||
return "width=\"$size->[0]\" height=\"$size->[1]\"";
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# modtime()
|
||||
#
|
||||
# Return last modification time as a time_t:
|
||||
#
|
||||
# [% date.format(image.modtime, "%Y/%m/%d") %]
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub modtime {
|
||||
my $self = shift;
|
||||
$self->init;
|
||||
return $self->{ modtime };
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# tag(\%options)
|
||||
#
|
||||
# Return an XHTML img tag.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub tag {
|
||||
my $self = shift;
|
||||
my $options = ref $_[0] eq 'HASH' ? shift : { @_ };
|
||||
|
||||
my $tag = '<img src="' . $self->name() . '" ' . $self->attr();
|
||||
|
||||
# XHTML spec says that the alt attribute is mandatory, so who
|
||||
# are we to argue?
|
||||
|
||||
$options->{ alt } = $self->{ alt }
|
||||
unless defined $options->{ alt };
|
||||
|
||||
if (%$options) {
|
||||
for my $key (sort keys %$options) {
|
||||
my $escaped = escape( $options->{$key} );
|
||||
$tag .= qq[ $key="$escaped"];
|
||||
}
|
||||
}
|
||||
|
||||
$tag .= ' />';
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
sub escape {
|
||||
my ($text) = @_;
|
||||
for ($text) {
|
||||
s/&/&/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
s/"/"/g;
|
||||
}
|
||||
$text;
|
||||
}
|
||||
|
||||
sub throw {
|
||||
my ($self, $error) = @_;
|
||||
die (Template::Exception->new('Image', $error));
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
(my $a = $AUTOLOAD) =~ s/.*:://;
|
||||
|
||||
$self->init;
|
||||
return $self->{ $a };
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Image - Plugin access to image sizes
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE Image(filename) %]
|
||||
[% Image.width %]
|
||||
[% Image.height %]
|
||||
[% Image.size.join(', ') %]
|
||||
[% Image.attr %]
|
||||
[% Image.tag %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin provides an interface to the L<Image::Info> or L<Image::Size>
|
||||
modules for determining the size of image files.
|
||||
|
||||
You can specify the plugin name as either 'C<Image>' or 'C<image>'. The
|
||||
plugin object created will then have the same name. The file name of
|
||||
the image should be specified as a positional or named argument.
|
||||
|
||||
[% # all these are valid, take your pick %]
|
||||
[% USE Image('foo.gif') %]
|
||||
[% USE image('bar.gif') %]
|
||||
[% USE Image 'ping.gif' %]
|
||||
[% USE image(name='baz.gif') %]
|
||||
[% USE Image name='pong.gif' %]
|
||||
|
||||
A C<root> parameter can be used to specify the location of the image file:
|
||||
|
||||
[% USE Image(root='/path/to/root', name='images/home.png') %]
|
||||
# image path: /path/to/root/images/home.png
|
||||
# img src: images/home.png
|
||||
|
||||
In cases where the image path and image url do not match up, specify the
|
||||
file name directly:
|
||||
|
||||
[% USE Image(file='/path/to/home.png', name='/images/home.png') %]
|
||||
|
||||
The C<alt> parameter can be used to specify an alternate name for the
|
||||
image, for use in constructing an XHTML element (see the C<tag()> method
|
||||
below).
|
||||
|
||||
[% USE Image('home.png', alt="Home") %]
|
||||
|
||||
You can also provide an alternate name for an C<Image> plugin object.
|
||||
|
||||
[% USE img1 = image 'foo.gif' %]
|
||||
[% USE img2 = image 'bar.gif' %]
|
||||
|
||||
The C<name> method returns the image file name.
|
||||
|
||||
[% img1.name %] # foo.gif
|
||||
|
||||
The C<width> and C<height> methods return the width and height of the
|
||||
image, respectively. The C<size> method returns a reference to a 2
|
||||
element list containing the width and height.
|
||||
|
||||
[% USE image 'foo.gif' %]
|
||||
width: [% image.width %]
|
||||
height: [% image.height %]
|
||||
size: [% image.size.join(', ') %]
|
||||
|
||||
The C<modtime> method returns the modification time of the file in question,
|
||||
suitable for use with the L<Date|Template::Plugin::Date> plugin, for example:
|
||||
|
||||
[% USE image 'foo.gif' %]
|
||||
[% USE date %]
|
||||
[% date.format(image.modtime, "%B, %e %Y") %]
|
||||
|
||||
The C<attr> method returns the height and width as HTML/XML attributes.
|
||||
|
||||
[% USE image 'foo.gif' %]
|
||||
[% image.attr %]
|
||||
|
||||
Typical output:
|
||||
|
||||
width="60" height="20"
|
||||
|
||||
The C<tag> method returns a complete XHTML tag referencing the image.
|
||||
|
||||
[% USE image 'foo.gif' %]
|
||||
[% image.tag %]
|
||||
|
||||
Typical output:
|
||||
|
||||
<img src="foo.gif" width="60" height="20" alt="" />
|
||||
|
||||
You can provide any additional attributes that should be added to the
|
||||
XHTML tag.
|
||||
|
||||
[% USE image 'foo.gif' %]
|
||||
[% image.tag(class="logo" alt="Logo") %]
|
||||
|
||||
Typical output:
|
||||
|
||||
<img src="foo.gif" width="60" height="20" alt="Logo" class="logo" />
|
||||
|
||||
Note that the C<alt> attribute is mandatory in a strict XHTML C<img>
|
||||
element (even if it's empty) so it is always added even if you don't
|
||||
explicitly provide a value for it. You can do so as an argument to
|
||||
the C<tag> method, as shown in the previous example, or as an argument
|
||||
|
||||
[% USE image('foo.gif', alt='Logo') %]
|
||||
|
||||
=head1 CATCHING ERRORS
|
||||
|
||||
If the image file cannot be found then the above methods will throw an
|
||||
C<Image> error. You can enclose calls to these methods in a
|
||||
C<TRY...CATCH> block to catch any potential errors.
|
||||
|
||||
[% TRY;
|
||||
image.width;
|
||||
CATCH;
|
||||
error; # print error
|
||||
END
|
||||
%]
|
||||
|
||||
=head1 USING Image::Info
|
||||
|
||||
At run time, the plugin tries to load L<Image::Info> in preference to
|
||||
L<Image::Size>. If L<Image::Info> is found, then some additional methods are
|
||||
available, in addition to C<size>, C<width>, C<height>, C<attr>, and C<tag>.
|
||||
These additional methods are named after the elements that L<Image::Info>
|
||||
retrieves from the image itself. The types of methods available depend on the
|
||||
type of image (see L<Image::Info> for more details). These additional methods
|
||||
will always include the following:
|
||||
|
||||
=head2 file_media_type
|
||||
|
||||
This is the MIME type that is appropriate for the given file format.
|
||||
The corresponding value is a string like: "C<image/png>" or "C<image/jpeg>".
|
||||
|
||||
=head2 file_ext
|
||||
|
||||
The is the suggested file name extension for a file of the given
|
||||
file format. The value is a 3 letter, lowercase string like
|
||||
"C<png>", "C<jpg>".
|
||||
|
||||
=head2 color_type
|
||||
|
||||
The value is a short string describing what kind of values the pixels
|
||||
encode. The value can be one of the following:
|
||||
|
||||
Gray
|
||||
GrayA
|
||||
RGB
|
||||
RGBA
|
||||
CMYK
|
||||
YCbCr
|
||||
CIELab
|
||||
|
||||
These names can also be prefixed by "C<Indexed->" if the image is
|
||||
composed of indexes into a palette. Of these, only "C<Indexed-RGB>" is
|
||||
likely to occur.
|
||||
|
||||
(It is similar to the TIFF field PhotometricInterpretation, but this
|
||||
name was found to be too long, so we used the PNG inspired term
|
||||
instead.)
|
||||
|
||||
=head2 resolution
|
||||
|
||||
The value of this field normally gives the physical size of the image
|
||||
on screen or paper. When the unit specifier is missing then this field
|
||||
denotes the squareness of pixels in the image.
|
||||
|
||||
The syntax of this field is:
|
||||
|
||||
<res> <unit>
|
||||
<xres> "/" <yres> <unit>
|
||||
<xres> "/" <yres>
|
||||
|
||||
The C<E<lt>resE<gt>>, C<E<lt>xresE<gt>> and C<E<lt>yresE<gt>> fields are
|
||||
numbers. The C<E<lt>unitE<gt>> is a string like C<dpi>, C<dpm> or
|
||||
C<dpcm> (denoting "dots per inch/cm/meter).
|
||||
|
||||
=head2 SamplesPerPixel
|
||||
|
||||
This says how many channels there are in the image. For some image
|
||||
formats this number might be higher than the number implied from the
|
||||
C<color_type>.
|
||||
|
||||
=head2 BitsPerSample
|
||||
|
||||
This says how many bits are used to encode each of samples. The value
|
||||
is a reference to an array containing numbers. The number of elements
|
||||
in the array should be the same as C<SamplesPerPixel>.
|
||||
|
||||
=head2 Comment
|
||||
|
||||
Textual comments found in the file. The value is a reference to an
|
||||
array if there are multiple comments found.
|
||||
|
||||
=head2 Interlace
|
||||
|
||||
If the image is interlaced, then this returns the interlace type.
|
||||
|
||||
=head2 Compression
|
||||
|
||||
This returns the name of the compression algorithm is used.
|
||||
|
||||
=head2 Gamma
|
||||
|
||||
A number indicating the gamma curve of the image (e.g. 2.2)
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Image::Info>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
88
database/perl/vendor/lib/Template/Plugin/Iterator.pm
vendored
Normal file
88
database/perl/vendor/lib/Template/Plugin/Iterator.pm
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Iterator
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Plugin to create a Template::Iterator from a list of items and optional
|
||||
# configuration parameters.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Iterator;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Template::Iterator;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \@data, \%args)
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
Template::Iterator->new(@_);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Iterator - Plugin to create iterators (Template::Iterator)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE iterator(list, args) %]
|
||||
|
||||
[% FOREACH item = iterator %]
|
||||
[% '<ul>' IF iterator.first %]
|
||||
<li>[% item %]
|
||||
[% '</ul>' IF iterator.last %]
|
||||
[% END %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The iterator plugin provides a way to create a L<Template::Iterator> object
|
||||
to iterate over a data set. An iterator is implicitly automatically by the
|
||||
L<FOREACH> directive. This plugin allows the iterator to be explicitly created
|
||||
with a given name.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Template::Iterator>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
242
database/perl/vendor/lib/Template/Plugin/Math.pm
vendored
Normal file
242
database/perl/vendor/lib/Template/Plugin/Math.pm
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Math
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin implementing numerous mathematical functions.
|
||||
#
|
||||
# AUTHORS
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2002-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Math;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $AUTOLOAD;
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \%config)
|
||||
#
|
||||
# This constructor method creates a simple, empty object to act as a
|
||||
# receiver for future object calls. No doubt there are many interesting
|
||||
# configuration options that might be passed, but I'll leave that for
|
||||
# someone more knowledgable in these areas to contribute...
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $config) = @_;
|
||||
$config ||= { };
|
||||
|
||||
bless {
|
||||
%$config,
|
||||
}, $class;
|
||||
}
|
||||
|
||||
sub abs { shift; CORE::abs($_[0]); }
|
||||
sub atan2 { shift; CORE::atan2($_[0], $_[1]); } # prototyped (ugg)
|
||||
sub cos { shift; CORE::cos($_[0]); }
|
||||
sub exp { shift; CORE::exp($_[0]); }
|
||||
sub hex { shift; CORE::hex($_[0]); }
|
||||
sub int { shift; CORE::int($_[0]); }
|
||||
sub log { shift; CORE::log($_[0]); }
|
||||
sub oct { shift; CORE::oct($_[0]); }
|
||||
sub rand { shift; @_ ? CORE::rand($_[0]) : CORE::rand(); }
|
||||
sub sin { shift; CORE::sin($_[0]); }
|
||||
sub sqrt { shift; CORE::sqrt($_[0]); }
|
||||
sub srand { shift; @_ ? CORE::srand($_[0]) : CORE::srand(); }
|
||||
|
||||
# Use the Math::TrulyRandom module
|
||||
# XXX This is *sloooooooowwwwwwww*
|
||||
sub truly_random {
|
||||
eval { require Math::TrulyRandom; }
|
||||
or die(Template::Exception->new("plugin",
|
||||
"Can't load Math::TrulyRandom"));
|
||||
return Math::TrulyRandom::truly_random_value();
|
||||
}
|
||||
|
||||
eval {
|
||||
require Math::Trig;
|
||||
no strict qw(refs);
|
||||
for my $trig_func (@Math::Trig::EXPORT) {
|
||||
my $sub = Math::Trig->can($trig_func);
|
||||
*{$trig_func} = sub { shift; &$sub(@_) };
|
||||
}
|
||||
};
|
||||
|
||||
# To catch errors from a missing Math::Trig
|
||||
sub AUTOLOAD { return; }
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Math - Plugin providing mathematical functions
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE Math %]
|
||||
|
||||
[% Math.sqrt(9) %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Math plugin provides numerous mathematical functions for use
|
||||
within templates.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
C<Template::Plugin::Math> makes available the following functions from
|
||||
the Perl core:
|
||||
|
||||
=over 4
|
||||
|
||||
=item abs
|
||||
|
||||
=item atan2
|
||||
|
||||
=item cos
|
||||
|
||||
=item exp
|
||||
|
||||
=item hex
|
||||
|
||||
=item int
|
||||
|
||||
=item log
|
||||
|
||||
=item oct
|
||||
|
||||
=item rand
|
||||
|
||||
=item sin
|
||||
|
||||
=item sqrt
|
||||
|
||||
=item srand
|
||||
|
||||
=back
|
||||
|
||||
In addition, if the L<Math::Trig> module can be loaded, the following
|
||||
functions are also available:
|
||||
|
||||
=over 4
|
||||
|
||||
=item pi
|
||||
|
||||
=item tan
|
||||
|
||||
=item csc
|
||||
|
||||
=item cosec
|
||||
|
||||
=item sec
|
||||
|
||||
=item cot
|
||||
|
||||
=item cotan
|
||||
|
||||
=item asin
|
||||
|
||||
=item acos
|
||||
|
||||
=item atan
|
||||
|
||||
=item acsc
|
||||
|
||||
=item acosec
|
||||
|
||||
=item asec
|
||||
|
||||
=item acot
|
||||
|
||||
=item acotan
|
||||
|
||||
=item sinh
|
||||
|
||||
=item cosh
|
||||
|
||||
=item tanh
|
||||
|
||||
=item csch
|
||||
|
||||
=item cosech
|
||||
|
||||
=item sech
|
||||
|
||||
=item coth
|
||||
|
||||
=item cotanh
|
||||
|
||||
=item asinh
|
||||
|
||||
=item acosh
|
||||
|
||||
=item atanh
|
||||
|
||||
=item acsch
|
||||
|
||||
=item acosech
|
||||
|
||||
=item asech
|
||||
|
||||
=item acoth
|
||||
|
||||
=item acotanh
|
||||
|
||||
=item rad2deg
|
||||
|
||||
=item rad2grad
|
||||
|
||||
=item deg2rad
|
||||
|
||||
=item deg2grad
|
||||
|
||||
=item grad2rad
|
||||
|
||||
=item grad2deg
|
||||
|
||||
=back
|
||||
|
||||
If the L<Math::TrulyRandom> module is available, and you've got the time
|
||||
to wait, the C<truly_random_number> method is available:
|
||||
|
||||
[% Math.truly_random_number %]
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
87
database/perl/vendor/lib/Template/Plugin/Pod.pm
vendored
Normal file
87
database/perl/vendor/lib/Template/Plugin/Pod.pm
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
#==============================================================================
|
||||
#
|
||||
# Template::Plugin::Pod
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Pod parser and object model.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Pod;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Pod::POM;
|
||||
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \%config)
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
|
||||
Pod::POM->new(@_);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Pod - Plugin interface to Pod::POM (Pod Object Model)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE Pod(podfile) %]
|
||||
|
||||
[% FOREACH head1 = Pod.head1;
|
||||
FOREACH head2 = head1/head2;
|
||||
...
|
||||
END;
|
||||
END
|
||||
%]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin is an interface to the L<Pod::POM> module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Pod::POM>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
137
database/perl/vendor/lib/Template/Plugin/Procedural.pm
vendored
Normal file
137
database/perl/vendor/lib/Template/Plugin/Procedural.pm
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
#==============================================================================
|
||||
#
|
||||
# Template::Plugin::Procedural
|
||||
#
|
||||
# DESCRIPTION
|
||||
# A Template Plugin to provide a Template Interface to Data::Dumper
|
||||
#
|
||||
# AUTHOR
|
||||
# Mark Fowler <mark@twoshortplanks.com>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2002 Mark Fowler. All Rights Reserved
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#==============================================================================
|
||||
|
||||
package Template::Plugin::Procedural;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $DEBUG = 0 unless defined $DEBUG;
|
||||
our $AUTOLOAD;
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# load
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub load {
|
||||
my ($class, $context) = @_;
|
||||
|
||||
# create a proxy namespace that will be used for objects
|
||||
my $proxy = "Template::Plugin::" . $class;
|
||||
|
||||
# okay, in our proxy create the autoload routine that will
|
||||
# call the right method in the real class
|
||||
no strict "refs";
|
||||
unless( defined( *{ $proxy . "::AUTOLOAD" } ) ) {
|
||||
*{ $proxy . "::AUTOLOAD" } = sub {
|
||||
# work out what the method is called
|
||||
$AUTOLOAD =~ s!^.*::!!;
|
||||
|
||||
print STDERR "Calling '$AUTOLOAD' in '$class'\n"
|
||||
if $DEBUG;
|
||||
|
||||
# look up the sub for that method (but in a OO way)
|
||||
my $uboat = $class->can($AUTOLOAD);
|
||||
|
||||
# if it existed call it as a subroutine, not as a method
|
||||
if ($uboat) {
|
||||
shift @_;
|
||||
return $uboat->(@_);
|
||||
}
|
||||
|
||||
print STDERR "Eeek, no such method '$AUTOLOAD'\n"
|
||||
if $DEBUG;
|
||||
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
# create a simple new method that simply returns a blessed
|
||||
# scalar as the object.
|
||||
unless( defined( *{ $proxy . "::new" } ) ) {
|
||||
*{ $proxy . "::new" } = sub {
|
||||
my $this;
|
||||
return bless \$this, $_[0];
|
||||
};
|
||||
}
|
||||
|
||||
return $proxy;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Procedural - Base class for procedural plugins
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package Template::Plugin::LWPSimple;
|
||||
use base qw(Template::Plugin::Procedural);
|
||||
use LWP::Simple; # exports 'get'
|
||||
1;
|
||||
|
||||
[% USE LWPSimple %]
|
||||
[% LWPSimple.get("http://www.tt2.org/") %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<Template::Plugin::Procedural> is a base class for Template Toolkit
|
||||
plugins that causes defined subroutines to be called directly rather
|
||||
than as a method. Essentially this means that subroutines will not
|
||||
receive the class name or object as its first argument.
|
||||
|
||||
This is most useful when creating plugins for modules that normally
|
||||
work by exporting subroutines that do not expect such additional
|
||||
arguments.
|
||||
|
||||
Despite the fact that subroutines will not be called in an OO manner,
|
||||
inheritance still function as normal. A class that uses
|
||||
C<Template::Plugin::Procedural> can be subclassed and both subroutines
|
||||
defined in the subclass and subroutines defined in the original class
|
||||
will be available to the Template Toolkit and will be called without
|
||||
the class/object argument.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mark Fowler E<lt>mark@twoshortplanks.comE<gt> L<http://www.twoshortplanks.com>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2002 Mark Fowler E<lt>mark@twoshortplanks.comE<gt>
|
||||
|
||||
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>, L<Template::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
163
database/perl/vendor/lib/Template/Plugin/Scalar.pm
vendored
Normal file
163
database/perl/vendor/lib/Template/Plugin/Scalar.pm
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Scalar
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit plugin module which allows you to call object methods
|
||||
# in scalar context.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2008 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Scalar;
|
||||
use base 'Template::Plugin';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Template::Exception;
|
||||
use Scalar::Util qw();
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $MONAD = 'Template::Monad::Scalar';
|
||||
our $EXCEPTION = 'Template::Exception';
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub load {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
|
||||
# define .scalar vmethods for hash and list objects
|
||||
$context->define_vmethod( hash => scalar => \&scalar_monad );
|
||||
$context->define_vmethod( list => scalar => \&scalar_monad );
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
sub scalar_monad {
|
||||
# create a .scalar monad which wraps the hash- or list-based object
|
||||
# and delegates any method calls back to it, calling them in scalar
|
||||
# context, e.g. foo.scalar.bar becomes $MONAD->new($foo)->bar and
|
||||
# the monad calls $foo->bar in scalar context
|
||||
$MONAD->new(shift);
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ($class, $context, @args) = @_;
|
||||
# create a scalar plugin object which will lookup a variable subroutine
|
||||
# and call it. e.g. scalar.foo results in a call to foo() in scalar context
|
||||
my $self = bless {
|
||||
_CONTEXT => $context,
|
||||
}, $class;
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $item = $AUTOLOAD;
|
||||
$item =~ s/.*:://;
|
||||
return if $item eq 'DESTROY';
|
||||
|
||||
# lookup the named values
|
||||
my $stash = $self->{ _CONTEXT }->stash;
|
||||
my $value = $stash->{ $item };
|
||||
|
||||
if (! defined $value) {
|
||||
die $EXCEPTION->new( scalar => "undefined value for scalar call: $item" );
|
||||
}
|
||||
elsif (ref $value eq 'CODE') {
|
||||
$value = $value->(@_);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
package Template::Monad::Scalar;
|
||||
|
||||
our $EXCEPTION = 'Template::Exception';
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub new {
|
||||
my ($class, $this) = @_;
|
||||
bless \$this, $class;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $this = $$self;
|
||||
my $item = $AUTOLOAD;
|
||||
$item =~ s/.*:://;
|
||||
return if $item eq 'DESTROY';
|
||||
|
||||
my $method;
|
||||
if (Scalar::Util::blessed($this)) {
|
||||
# lookup the method...
|
||||
$method = $this->can($item);
|
||||
}
|
||||
else {
|
||||
die $EXCEPTION->new( scalar => "invalid object method: $item" );
|
||||
}
|
||||
|
||||
# ...and call it in scalar context
|
||||
my $result = $method->($this, @_);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Scalar - call object methods in scalar context
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE scalar %]
|
||||
|
||||
# TT2 calls object methods in array context by default
|
||||
[% object.method %]
|
||||
|
||||
# force it to use scalar context
|
||||
[% object.scalar.method %]
|
||||
|
||||
# also works with subroutine references
|
||||
[% scalar.my_sub_ref %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Template Toolkit calls user-defined subroutines and object methods
|
||||
using Perl's array context by default. This plugin module provides a way
|
||||
for you to call subroutines and methods in scalar context.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2008 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
761
database/perl/vendor/lib/Template/Plugin/String.pm
vendored
Normal file
761
database/perl/vendor/lib/Template/Plugin/String.pm
vendored
Normal file
@@ -0,0 +1,761 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::String
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit plugin to implement a basic String object.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2001-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::String;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Template::Exception;
|
||||
|
||||
use overload q|""| => "text",
|
||||
fallback => 1;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $ERROR = '';
|
||||
|
||||
*centre = \*center;
|
||||
*append = \*push;
|
||||
*prepend = \*unshift;
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, @args) = @_;
|
||||
my $context = ref $class ? undef : shift(@args);
|
||||
my $config = @args && ref $args[-1] eq 'HASH' ? pop(@args) : { };
|
||||
|
||||
$class = ref($class) || $class;
|
||||
|
||||
my $text = defined $config->{ text }
|
||||
? $config->{ text }
|
||||
: (@args ? shift(@args) : '');
|
||||
|
||||
# print STDERR "text: [$text]\n";
|
||||
# print STDERR "class: [$class]\n";
|
||||
|
||||
my $self = bless {
|
||||
text => $text,
|
||||
filters => [ ],
|
||||
_CONTEXT => $context,
|
||||
}, $class;
|
||||
|
||||
my $filter = $config->{ filter } || $config->{ filters };
|
||||
|
||||
# install any output filters specified as 'filter' or 'filters' option
|
||||
$self->output_filter($filter)
|
||||
if $filter;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub text {
|
||||
my $self = shift;
|
||||
return $self->{ text } unless @{ $self->{ filters } };
|
||||
|
||||
my $text = $self->{ text };
|
||||
my $context = $self->{ _CONTEXT };
|
||||
|
||||
foreach my $dispatch (@{ $self->{ filters } }) {
|
||||
my ($name, $args) = @$dispatch;
|
||||
my $code = $context->filter($name, $args)
|
||||
|| $self->throw($context->error());
|
||||
$text = &$code($text);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
sub copy {
|
||||
my $self = shift;
|
||||
$self->new($self->{ text });
|
||||
}
|
||||
|
||||
|
||||
sub throw {
|
||||
my $self = shift;
|
||||
|
||||
die (Template::Exception->new('String', join('', @_)));
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# output_filter($filter)
|
||||
#
|
||||
# Install automatic output filter(s) for the string. $filter can a list:
|
||||
# [ 'name1', 'name2' => [ ..args.. ], name4 => { ..args.. } ] or a hash
|
||||
# { name1 => '', name2 => [ args ], name3 => { args } }
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub output_filter {
|
||||
my ($self, $filter) = @_;
|
||||
my ($name, $args, $dispatch);
|
||||
my $filters = $self->{ filters };
|
||||
my $count = 0;
|
||||
|
||||
if (ref $filter eq 'HASH') {
|
||||
$filter = [ %$filter ];
|
||||
}
|
||||
elsif (ref $filter ne 'ARRAY') {
|
||||
$filter = [ split(/\s*\W+\s*/, $filter) ];
|
||||
}
|
||||
|
||||
while (@$filter) {
|
||||
$name = shift @$filter;
|
||||
|
||||
# args may follow as a reference (or empty string, e.g. { foo => '' }
|
||||
if (@$filter && (ref($filter->[0]) || ! length $filter->[0])) {
|
||||
$args = shift @$filter;
|
||||
if ($args) {
|
||||
$args = [ $args ] unless ref $args eq 'ARRAY';
|
||||
}
|
||||
else {
|
||||
$args = [ ];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$args = [ ];
|
||||
}
|
||||
|
||||
# $self->DEBUG("adding output filter $name(@$args)\n");
|
||||
|
||||
push(@$filters, [ $name, $args ]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub push {
|
||||
my $self = shift;
|
||||
$self->{ text } .= join('', @_);
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub unshift {
|
||||
my $self = shift;
|
||||
$self->{ text } = join('', @_) . $self->{ text };
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub pop {
|
||||
my $self = shift;
|
||||
my $strip = shift || return $self;
|
||||
$self->{ text } =~ s/$strip$//;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub shift {
|
||||
my $self = shift;
|
||||
my $strip = shift || return $self;
|
||||
$self->{ text } =~ s/^$strip//;
|
||||
return $self;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub center {
|
||||
my ($self, $width) = @_;
|
||||
my $text = $self->{ text };
|
||||
my $len = length $text;
|
||||
$width ||= 0;
|
||||
|
||||
if ($len < $width) {
|
||||
my $lpad = int(($width - $len) / 2);
|
||||
my $rpad = $width - $len - $lpad;
|
||||
$self->{ text } = (' ' x $lpad) . $self->{ text } . (' ' x $rpad);
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub left {
|
||||
my ($self, $width) = @_;
|
||||
my $len = length $self->{ text };
|
||||
$width ||= 0;
|
||||
|
||||
$self->{ text } .= (' ' x ($width - $len))
|
||||
if $width > $len;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub right {
|
||||
my ($self, $width) = @_;
|
||||
my $len = length $self->{ text };
|
||||
$width ||= 0;
|
||||
|
||||
$self->{ text } = (' ' x ($width - $len)) . $self->{ text }
|
||||
if $width > $len;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub format {
|
||||
my ($self, $format) = @_;
|
||||
$format = '%s' unless defined $format;
|
||||
$self->{ text } = sprintf($format, $self->{ text });
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub filter {
|
||||
my ($self, $name, @args) = @_;
|
||||
|
||||
my $context = $self->{ _CONTEXT };
|
||||
|
||||
my $code = $context->filter($name, \@args)
|
||||
|| $self->throw($context->error());
|
||||
return &$code($self->{ text });
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub upper {
|
||||
my $self = CORE::shift;
|
||||
$self->{ text } = uc $self->{ text };
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub lower {
|
||||
my $self = CORE::shift;
|
||||
$self->{ text } = lc $self->{ text };
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub capital {
|
||||
my $self = CORE::shift;
|
||||
$self->{ text } =~ s/^(.)/\U$1/;
|
||||
return $self;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub chop {
|
||||
my $self = CORE::shift;
|
||||
chop $self->{ text };
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub chomp {
|
||||
my $self = CORE::shift;
|
||||
chomp $self->{ text };
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub trim {
|
||||
my $self = CORE::shift;
|
||||
for ($self->{ text }) {
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub collapse {
|
||||
my $self = CORE::shift;
|
||||
for ($self->{ text }) {
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
s/\s+/ /g
|
||||
}
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub length {
|
||||
my $self = CORE::shift;
|
||||
return length $self->{ text };
|
||||
}
|
||||
|
||||
|
||||
sub truncate {
|
||||
my ($self, $length, $suffix) = @_;
|
||||
return $self unless defined $length;
|
||||
$suffix ||= '';
|
||||
return $self if CORE::length $self->{ text } <= $length;
|
||||
$self->{ text } = CORE::substr($self->{ text }, 0,
|
||||
$length - CORE::length($suffix)) . $suffix;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub substr {
|
||||
my ($self, $offset, $length, $replacement) = @_;
|
||||
$offset ||= 0;
|
||||
|
||||
if(defined $length) {
|
||||
if (defined $replacement) {
|
||||
my $removed = CORE::substr( $self->{text}, $offset, $length );
|
||||
CORE::substr( $self->{text}, $offset, $length ) = $replacement;
|
||||
return $removed;
|
||||
}
|
||||
else {
|
||||
return CORE::substr( $self->{text}, $offset, $length );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return CORE::substr( $self->{text}, $offset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub repeat {
|
||||
my ($self, $n) = @_;
|
||||
return $self unless defined $n;
|
||||
$self->{ text } = $self->{ text } x $n;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub replace {
|
||||
my ($self, $search, $replace) = @_;
|
||||
return $self unless defined $search;
|
||||
$replace = '' unless defined $replace;
|
||||
$self->{ text } =~ s/$search/$replace/g;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub remove {
|
||||
my ($self, $search) = @_;
|
||||
$search = '' unless defined $search;
|
||||
$self->{ text } =~ s/$search//g;
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub split {
|
||||
my $self = CORE::shift;
|
||||
my $split = CORE::shift;
|
||||
my $limit = CORE::shift || 0;
|
||||
$split = '\s+' unless defined $split;
|
||||
return [ split($split, $self->{ text }, $limit) ];
|
||||
}
|
||||
|
||||
|
||||
sub search {
|
||||
my ($self, $pattern) = @_;
|
||||
return $self->{ text } =~ /$pattern/;
|
||||
}
|
||||
|
||||
|
||||
sub equals {
|
||||
my ($self, $comparison) = @_;
|
||||
return $self->{ text } eq $comparison;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::String - Object oriented interface for string manipulation
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# create String objects via USE directive
|
||||
[% USE String %]
|
||||
[% USE String 'initial text' %]
|
||||
[% USE String text => 'initial text' %]
|
||||
|
||||
# or from an existing String via new()
|
||||
[% newstring = String.new %]
|
||||
[% newstring = String.new('newstring text') %]
|
||||
[% newstring = String.new( text => 'newstring text' ) %]
|
||||
|
||||
# or from an existing String via copy()
|
||||
[% newstring = String.copy %]
|
||||
|
||||
# append text to string
|
||||
[% String.append('text to append') %]
|
||||
|
||||
# format left, right or center/centre padded
|
||||
[% String.left(20) %]
|
||||
[% String.right(20) %]
|
||||
[% String.center(20) %] # American spelling
|
||||
[% String.centre(20) %] # European spelling
|
||||
|
||||
# and various other methods...
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module implements a C<String> class for doing stringy things to
|
||||
text in an object-oriented way.
|
||||
|
||||
You can create a C<String> object via the C<USE> directive, adding any
|
||||
initial text value as an argument or as the named parameter C<text>.
|
||||
|
||||
[% USE String %]
|
||||
[% USE String 'initial text' %]
|
||||
[% USE String text='initial text' %]
|
||||
|
||||
The object created will be referenced as C<String> by default, but you
|
||||
can provide a different variable name for the object to be assigned
|
||||
to:
|
||||
|
||||
[% USE greeting = String 'Hello World' %]
|
||||
|
||||
Once you've got a C<String> object, you can use it as a prototype to
|
||||
create other C<String> objects with the C<new()> method.
|
||||
|
||||
[% USE String %]
|
||||
[% greeting = String.new('Hello World') %]
|
||||
|
||||
The C<new()> method also accepts an initial text string as an argument
|
||||
or the named parameter C<text>.
|
||||
|
||||
[% greeting = String.new( text => 'Hello World' ) %]
|
||||
|
||||
You can also call C<copy()> to create a new C<String> as a copy of the
|
||||
original.
|
||||
|
||||
[% greet2 = greeting.copy %]
|
||||
|
||||
The C<String> object has a C<text()> method to return the content of the
|
||||
string.
|
||||
|
||||
[% greeting.text %]
|
||||
|
||||
However, it is sufficient to simply print the string and let the
|
||||
overloaded stringification operator call the C<text()> method
|
||||
automatically for you.
|
||||
|
||||
[% greeting %]
|
||||
|
||||
Thus, you can treat C<String> objects pretty much like any regular piece
|
||||
of text, interpolating it into other strings, for example:
|
||||
|
||||
[% msg = "It printed '$greeting' and then dumped core\n" %]
|
||||
|
||||
You also have the benefit of numerous other methods for manipulating
|
||||
the string.
|
||||
|
||||
[% msg.append("PS Don't eat the yellow snow") %]
|
||||
|
||||
Note that all methods operate on and mutate the contents of the string
|
||||
itself. If you want to operate on a copy of the string then simply
|
||||
take a copy first:
|
||||
|
||||
[% msg.copy.append("PS Don't eat the yellow snow") %]
|
||||
|
||||
These methods return a reference to the C<String> object itself. This
|
||||
allows you to chain multiple methods together.
|
||||
|
||||
[% msg.copy.append('foo').right(72) %]
|
||||
|
||||
It also means that in the above examples, the C<String> is returned which
|
||||
causes the C<text()> method to be called, which results in the new value of
|
||||
the string being printed. To suppress printing of the string, you can
|
||||
use the C<CALL> directive.
|
||||
|
||||
[% foo = String.new('foo') %]
|
||||
|
||||
[% foo.append('bar') %] # prints "foobar"
|
||||
|
||||
[% CALL foo.append('bar') %] # nothing
|
||||
|
||||
=head1 CONSTRUCTOR METHODS
|
||||
|
||||
These methods are used to create new C<String> objects.
|
||||
|
||||
=head2 new()
|
||||
|
||||
Creates a new string using an initial value passed as a positional
|
||||
argument or the named parameter C<text>.
|
||||
|
||||
[% USE String %]
|
||||
[% msg = String.new('Hello World') %]
|
||||
[% msg = String.new( text => 'Hello World' ) %]
|
||||
|
||||
=head2 copy()
|
||||
|
||||
Creates a new C<String> object which contains a copy of the original string.
|
||||
|
||||
[% msg2 = msg.copy %]
|
||||
|
||||
=head1 INSPECTOR METHODS
|
||||
|
||||
These methods are used to examine the string.
|
||||
|
||||
=head2 text()
|
||||
|
||||
Returns the internal text value of the string. The stringification
|
||||
operator is overloaded to call this method. Thus the following are
|
||||
equivalent:
|
||||
|
||||
[% msg.text %]
|
||||
[% msg %]
|
||||
|
||||
=head2 length()
|
||||
|
||||
Returns the length of the string.
|
||||
|
||||
[% USE String("foo") %]
|
||||
[% String.length %] # => 3
|
||||
|
||||
=head2 search($pattern)
|
||||
|
||||
Searches the string for the regular expression specified in C<$pattern>
|
||||
returning true if found or false otherwise.
|
||||
|
||||
[% item = String.new('foo bar baz wiz waz woz') %]
|
||||
[% item.search('wiz') ? 'WIZZY! :-)' : 'not wizzy :-(' %]
|
||||
|
||||
=head2 split($pattern, $limit)
|
||||
|
||||
Splits the string based on the delimiter C<$pattern> and optional C<$limit>.
|
||||
Delegates to Perl's internal C<split()> so the parameters are exactly the same.
|
||||
|
||||
[% FOREACH item.split %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
[% FOREACH item.split('baz|waz') %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
=head1 MUTATOR METHODS
|
||||
|
||||
These methods modify the internal value of the string. For example:
|
||||
|
||||
[% USE str=String('foobar') %]
|
||||
[% str.append('.html') %] # str => 'foobar.html'
|
||||
|
||||
The value of C<str> is now 'C<foobar.html>'. If you don't want
|
||||
to modify the string then simply take a copy first.
|
||||
|
||||
[% str.copy.append('.html') %]
|
||||
|
||||
These methods all return a reference to the C<String> object itself. This
|
||||
has two important benefits. The first is that when used as above, the
|
||||
C<String> object 'C<str>' returned by the C<append()> method will be stringified
|
||||
with a call to its C<text()> method. This will return the newly modified
|
||||
string content. In other words, a directive like:
|
||||
|
||||
[% str.append('.html') %]
|
||||
|
||||
will update the string and also print the new value. If you just want
|
||||
to update the string but not print the new value then use C<CALL>.
|
||||
|
||||
[% CALL str.append('.html') %]
|
||||
|
||||
The other benefit of these methods returning a reference to the C<String>
|
||||
is that you can chain as many different method calls together as you
|
||||
like. For example:
|
||||
|
||||
[% String.append('.html').trim.format(href) %]
|
||||
|
||||
Here are the methods:
|
||||
|
||||
=head2 push($suffix, ...) / append($suffix, ...)
|
||||
|
||||
Appends all arguments to the end of the string. The
|
||||
C<append()> method is provided as an alias for C<push()>.
|
||||
|
||||
[% msg.push('foo', 'bar') %]
|
||||
[% msg.append('foo', 'bar') %]
|
||||
|
||||
=head2 pop($suffix)
|
||||
|
||||
Removes the suffix passed as an argument from the end of the String.
|
||||
|
||||
[% USE String 'foo bar' %]
|
||||
[% String.pop(' bar') %] # => 'foo'
|
||||
|
||||
=head2 unshift($prefix, ...) / prepend($prefix, ...)
|
||||
|
||||
Prepends all arguments to the beginning of the string. The
|
||||
C<prepend()> method is provided as an alias for C<unshift()>.
|
||||
|
||||
[% msg.unshift('foo ', 'bar ') %]
|
||||
[% msg.prepend('foo ', 'bar ') %]
|
||||
|
||||
=head2 shift($prefix)
|
||||
|
||||
Removes the prefix passed as an argument from the start of the String.
|
||||
|
||||
[% USE String 'foo bar' %]
|
||||
[% String.shift('foo ') %] # => 'bar'
|
||||
|
||||
=head2 left($pad)
|
||||
|
||||
If the length of the string is less than C<$pad> then the string is left
|
||||
formatted and padded with spaces to C<$pad> length.
|
||||
|
||||
[% msg.left(20) %]
|
||||
|
||||
=head2 right($pad)
|
||||
|
||||
As per L<left()> but right padding the C<String> to a length of C<$pad>.
|
||||
|
||||
[% msg.right(20) %]
|
||||
|
||||
=head2 center($pad) / centre($pad)
|
||||
|
||||
As per L<left()> and L<right()> but formatting the C<String> to be centered within
|
||||
a space padded string of length C<$pad>. The C<centre()> method is provided as
|
||||
an alias for C<center()>.
|
||||
|
||||
[% msg.center(20) %] # American spelling
|
||||
[% msg.centre(20) %] # European spelling
|
||||
|
||||
=head2 format($format)
|
||||
|
||||
Apply a format in the style of C<sprintf()> to the string.
|
||||
|
||||
[% USE String("world") %]
|
||||
[% String.format("Hello %s\n") %] # => "Hello World\n"
|
||||
|
||||
=head2 upper()
|
||||
|
||||
Converts the string to upper case.
|
||||
|
||||
[% USE String("foo") %]
|
||||
[% String.upper %] # => 'FOO'
|
||||
|
||||
=head2 lower()
|
||||
|
||||
Converts the string to lower case
|
||||
|
||||
[% USE String("FOO") %]
|
||||
[% String.lower %] # => 'foo'
|
||||
|
||||
=head2 capital()
|
||||
|
||||
Converts the first character of the string to upper case.
|
||||
|
||||
[% USE String("foo") %]
|
||||
[% String.capital %] # => 'Foo'
|
||||
|
||||
The remainder of the string is left untouched. To force the string to
|
||||
be all lower case with only the first letter capitalised, you can do
|
||||
something like this:
|
||||
|
||||
[% USE String("FOO") %]
|
||||
[% String.lower.capital %] # => 'Foo'
|
||||
|
||||
=head2 chop()
|
||||
|
||||
Removes the last character from the string.
|
||||
|
||||
[% USE String("foop") %]
|
||||
[% String.chop %] # => 'foo'
|
||||
|
||||
=head2 chomp()
|
||||
|
||||
Removes the trailing newline from the string.
|
||||
|
||||
[% USE String("foo\n") %]
|
||||
[% String.chomp %] # => 'foo'
|
||||
|
||||
=head2 trim()
|
||||
|
||||
Removes all leading and trailing whitespace from the string
|
||||
|
||||
[% USE String(" foo \n\n ") %]
|
||||
[% String.trim %] # => 'foo'
|
||||
|
||||
=head2 collapse()
|
||||
|
||||
Removes all leading and trailing whitespace and collapses any sequences
|
||||
of multiple whitespace to a single space.
|
||||
|
||||
[% USE String(" \n\r \t foo \n \n bar \n") %]
|
||||
[% String.collapse %] # => "foo bar"
|
||||
|
||||
=head2 truncate($length, $suffix)
|
||||
|
||||
Truncates the string to C<$length> characters.
|
||||
|
||||
[% USE String('long string') %]
|
||||
[% String.truncate(4) %] # => 'long'
|
||||
|
||||
If C<$suffix> is specified then it will be appended to the truncated
|
||||
string. In this case, the string will be further shortened by the
|
||||
length of the suffix to ensure that the newly constructed string
|
||||
complete with suffix is exactly C<$length> characters long.
|
||||
|
||||
[% USE msg = String('Hello World') %]
|
||||
[% msg.truncate(8, '...') %] # => 'Hello...'
|
||||
|
||||
=head2 replace($search, $replace)
|
||||
|
||||
Replaces all occurrences of C<$search> in the string with C<$replace>.
|
||||
|
||||
[% USE String('foo bar foo baz') %]
|
||||
[% String.replace('foo', 'wiz') %] # => 'wiz bar wiz baz'
|
||||
|
||||
=head2 remove($search)
|
||||
|
||||
Remove all occurrences of C<$search> in the string.
|
||||
|
||||
[% USE String('foo bar foo baz') %]
|
||||
[% String.remove('foo ') %] # => 'bar baz'
|
||||
|
||||
=head2 repeat($count)
|
||||
|
||||
Repeats the string C<$count> times.
|
||||
|
||||
[% USE String('foo ') %]
|
||||
[% String.repeat(3) %] # => 'foo foo foo '
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
441
database/perl/vendor/lib/Template/Plugin/Table.pm
vendored
Normal file
441
database/perl/vendor/lib/Template/Plugin/Table.pm
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Table
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin to order a linear data set into a virtual 2-dimensional table
|
||||
# from which row and column permutations can be fetched.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Table;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Scalar::Util 'blessed';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $AUTOLOAD;
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \@data, \%args)
|
||||
#
|
||||
# This constructor method initialises the object to iterate through
|
||||
# the data set passed by reference to a list as the first parameter.
|
||||
# It calculates the shape of the permutation table based on the ROWS
|
||||
# or COLS parameters specified in the $args hash reference. The
|
||||
# OVERLAP parameter may be provided to specify the number of common
|
||||
# items that should be shared between subsequent columns.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $data, $params) = @_;
|
||||
my ($size, $rows, $cols, $coloff, $overlap, $error);
|
||||
|
||||
# if the data item is a reference to a Template::Iterator object,
|
||||
# or subclass thereof, we call its get_all() method to extract all
|
||||
# the data it contains
|
||||
if (blessed($data) && $data->isa('Template::Iterator')) {
|
||||
($data, $error) = $data->get_all();
|
||||
return $class->error("iterator failed to provide data for table: ",
|
||||
$error)
|
||||
if $error;
|
||||
}
|
||||
|
||||
return $class->error('invalid table data, expecting a list')
|
||||
unless ref $data eq 'ARRAY';
|
||||
|
||||
$params ||= { };
|
||||
return $class->error('invalid table parameters, expecting a hash')
|
||||
unless ref $params eq 'HASH';
|
||||
|
||||
# ensure keys are folded to upper case
|
||||
@$params{ map { uc } keys %$params } = values %$params;
|
||||
|
||||
$size = scalar @$data;
|
||||
$overlap = $params->{ OVERLAP } || 0;
|
||||
|
||||
# calculate number of columns based on a specified number of rows
|
||||
if ($rows = $params->{ ROWS }) {
|
||||
if ($size < $rows) {
|
||||
$rows = $size; # pad?
|
||||
$cols = 1;
|
||||
$coloff = 0;
|
||||
}
|
||||
else {
|
||||
$coloff = $rows - $overlap;
|
||||
$cols = int ($size / $coloff)
|
||||
+ ($size % $coloff > $overlap ? 1 : 0)
|
||||
}
|
||||
}
|
||||
# calculate number of rows based on a specified number of columns
|
||||
elsif ($cols = $params->{ COLS }) {
|
||||
if ($size < $cols) {
|
||||
$cols = $size;
|
||||
$rows = 1;
|
||||
$coloff = 1;
|
||||
}
|
||||
else {
|
||||
$coloff = int ($size / $cols)
|
||||
+ ($size % $cols > $overlap ? 1 : 0);
|
||||
$rows = $coloff + $overlap;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$rows = $size;
|
||||
$cols = 1;
|
||||
$coloff = 0;
|
||||
}
|
||||
|
||||
bless {
|
||||
_DATA => $data,
|
||||
_SIZE => $size,
|
||||
_NROWS => $rows,
|
||||
_NCOLS => $cols,
|
||||
_COLOFF => $coloff,
|
||||
_OVERLAP => $overlap,
|
||||
_PAD => defined $params->{ PAD } ? $params->{ PAD } : 1,
|
||||
}, $class;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# row($n)
|
||||
#
|
||||
# Returns a reference to a list containing the items in the row whose
|
||||
# number is specified by parameter. If the row number is undefined,
|
||||
# it calls rows() to return a list of all rows.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub row {
|
||||
my ($self, $row) = @_;
|
||||
my ($data, $cols, $offset, $size, $pad)
|
||||
= @$self{ qw( _DATA _NCOLS _COLOFF _SIZE _PAD) };
|
||||
my @set;
|
||||
|
||||
# return all rows if row number not specified
|
||||
return $self->rows()
|
||||
unless defined $row;
|
||||
|
||||
return () if $row >= $self->{ _NROWS } || $row < 0;
|
||||
|
||||
my $index = $row;
|
||||
|
||||
for (my $c = 0; $c < $cols; $c++) {
|
||||
push(@set, $index < $size
|
||||
? $data->[$index]
|
||||
: ($pad ? undef : ()));
|
||||
$index += $offset;
|
||||
}
|
||||
return \@set;
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# col($n)
|
||||
#
|
||||
# Returns a reference to a list containing the items in the column whose
|
||||
# number is specified by parameter. If the column number is undefined,
|
||||
# it calls cols() to return a list of all columns.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub col {
|
||||
my ($self, $col) = @_;
|
||||
my ($data, $size) = @$self{ qw( _DATA _SIZE ) };
|
||||
my ($start, $end);
|
||||
my $blanks = 0;
|
||||
|
||||
# return all cols if row number not specified
|
||||
return $self->cols()
|
||||
unless defined $col;
|
||||
|
||||
return () if $col >= $self->{ _NCOLS } || $col < 0;
|
||||
|
||||
$start = $self->{ _COLOFF } * $col;
|
||||
$end = $start + $self->{ _NROWS } - 1;
|
||||
$end = $start if $end < $start;
|
||||
if ($end >= $size) {
|
||||
$blanks = ($end - $size) + 1;
|
||||
$end = $size - 1;
|
||||
}
|
||||
return () if $start >= $size;
|
||||
return [ @$data[$start..$end],
|
||||
$self->{ _PAD } ? ((undef) x $blanks) : () ];
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# rows()
|
||||
#
|
||||
# Returns all rows as a reference to a list of rows.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub rows {
|
||||
my $self = shift;
|
||||
return [ map { $self->row($_) } (0..$self->{ _NROWS }-1) ];
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# cols()
|
||||
#
|
||||
# Returns all rows as a reference to a list of rows.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub cols {
|
||||
my $self = shift;
|
||||
return [ map { $self->col($_) } (0..$self->{ _NCOLS }-1) ];
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# AUTOLOAD
|
||||
#
|
||||
# Provides read access to various internal data members.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my $item = $AUTOLOAD;
|
||||
$item =~ s/.*:://;
|
||||
return if $item eq 'DESTROY';
|
||||
|
||||
if ($item =~ /^(?:data|size|nrows|ncols|overlap|pad)$/) {
|
||||
return $self->{ $item };
|
||||
}
|
||||
else {
|
||||
return (undef, "no such table method: $item");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Table - Plugin to present data in a table
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE table(list, rows=n, cols=n, overlap=n, pad=0) %]
|
||||
|
||||
[% FOREACH item IN table.row(n) %]
|
||||
[% item %]
|
||||
[% END %]
|
||||
|
||||
[% FOREACH item IN table.col(n) %]
|
||||
[% item %]
|
||||
[% END %]
|
||||
|
||||
[% FOREACH row IN table.rows %]
|
||||
[% FOREACH item IN row %]
|
||||
[% item %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[% FOREACH col IN table.cols %]
|
||||
[% col.first %] - [% col.last %] ([% col.size %] entries)
|
||||
[% END %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<Table> plugin allows you to format a list of data items into a
|
||||
virtual table. When you create a C<Table> plugin via the C<USE> directive,
|
||||
simply pass a list reference as the first parameter and then specify
|
||||
a fixed number of rows or columns.
|
||||
|
||||
[% USE Table(list, rows=5) %]
|
||||
[% USE table(list, cols=5) %]
|
||||
|
||||
The C<Table> plugin name can also be specified in lower case as shown
|
||||
in the second example above. You can also specify an alternative variable
|
||||
name for the plugin as per regular Template Toolkit syntax.
|
||||
|
||||
[% USE mydata = table(list, rows=5) %]
|
||||
|
||||
The plugin then presents a table based view on the data set. The data
|
||||
isn't actually reorganised in any way but is available via the C<row()>,
|
||||
C<col()>, C<rows()> and C<cols()> as if formatted into a simple two dimensional
|
||||
table of C<n> rows x C<n> columns.
|
||||
|
||||
So if we had a sample C<alphabet> list contained the letters 'C<a>' to 'C<z>',
|
||||
the above C<USE> directives would create plugins that represented the following
|
||||
views of the alphabet.
|
||||
|
||||
[% USE table(alphabet, ... %]
|
||||
|
||||
rows=5 cols=5
|
||||
a f k p u z a g m s y
|
||||
b g l q v b h n t z
|
||||
c h m r w c i o u
|
||||
d i n s x d j p v
|
||||
e j o t y e k q w
|
||||
f l r x
|
||||
|
||||
We can request a particular row or column using the C<row()> and C<col()>
|
||||
methods.
|
||||
|
||||
[% USE table(alphabet, rows=5) %]
|
||||
[% FOREACH item = table.row(0) %]
|
||||
# [% item %] set to each of [ a f k p u z ] in turn
|
||||
[% END %]
|
||||
|
||||
[% FOREACH item = table.col(2) %]
|
||||
# [% item %] set to each of [ m n o p q r ] in turn
|
||||
[% END %]
|
||||
|
||||
Data in rows is returned from left to right, columns from top to
|
||||
bottom. The first row/column is 0. By default, rows or columns that
|
||||
contain empty values will be padded with the undefined value to fill
|
||||
it to the same size as all other rows or columns.
|
||||
|
||||
For example, the last row (row 4) in the first example would contain the
|
||||
values C<[ e j o t y undef ]>. The Template Toolkit will safely accept these
|
||||
undefined values and print a empty string. You can also use the IF directive
|
||||
to test if the value is set.
|
||||
|
||||
[% FOREACH item = table.row(4) %]
|
||||
[% IF item %]
|
||||
Item: [% item %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
You can explicitly disable the C<pad> option when creating the plugin to
|
||||
returned shortened rows/columns where the data is empty.
|
||||
|
||||
[% USE table(alphabet, cols=5, pad=0) %]
|
||||
[% FOREACH item = table.col(4) %]
|
||||
# [% item %] set to each of 'y z'
|
||||
[% END %]
|
||||
|
||||
The C<rows()> method returns all rows/columns in the table as a reference
|
||||
to a list of rows (themselves list references). The C<row()> methods
|
||||
when called without any arguments calls C<rows()> to return all rows in
|
||||
the table.
|
||||
|
||||
Ditto for C<cols()> and C<col()>.
|
||||
|
||||
[% USE table(alphabet, cols=5) %]
|
||||
[% FOREACH row = table.rows %]
|
||||
[% FOREACH item = row %]
|
||||
[% item %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
The Template Toolkit provides the C<first>, C<last> and C<size> virtual
|
||||
methods that can be called on list references to return the first/last entry
|
||||
or the number of entries in a list. The following example shows how we might
|
||||
use this to provide an alphabetical index split into 3 even parts.
|
||||
|
||||
[% USE table(alphabet, cols=3, pad=0) %]
|
||||
[% FOREACH group = table.col %]
|
||||
[ [% group.first %] - [% group.last %] ([% group.size %] letters) ]
|
||||
[% END %]
|
||||
|
||||
This produces the following output:
|
||||
|
||||
[ a - i (9 letters) ]
|
||||
[ j - r (9 letters) ]
|
||||
[ s - z (8 letters) ]
|
||||
|
||||
We can also use the general purpose C<join> virtual method which joins
|
||||
the items of the list using the connecting string specified.
|
||||
|
||||
[% USE table(alphabet, cols=5) %]
|
||||
[% FOREACH row = table.rows %]
|
||||
[% row.join(' - ') %]
|
||||
[% END %]
|
||||
|
||||
Data in the table is ordered downwards rather than across but can easily
|
||||
be transformed on output. For example, to format our data in 5 columns
|
||||
with data ordered across rather than down, we specify C<rows=5> to order
|
||||
the data as such:
|
||||
|
||||
a f . .
|
||||
b g .
|
||||
c h
|
||||
d i
|
||||
e j
|
||||
|
||||
and then iterate down through each column (a-e, f-j, etc.) printing
|
||||
the data across.
|
||||
|
||||
a b c d e
|
||||
f g h i j
|
||||
. .
|
||||
.
|
||||
|
||||
Example code to do so would be much like the following:
|
||||
|
||||
[% USE table(alphabet, rows=3) %]
|
||||
[% FOREACH cols = table.cols %]
|
||||
[% FOREACH item = cols %]
|
||||
[% item %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
Output:
|
||||
|
||||
a b c
|
||||
d e f
|
||||
g h i
|
||||
j . .
|
||||
.
|
||||
|
||||
In addition to a list reference, the C<Table> plugin constructor may be passed
|
||||
a reference to a L<Template::Iterator> object or subclass thereof. The
|
||||
L<Template::Iterator> L<get_all()|Template::Iterator#get_all()> method is
|
||||
first called on the iterator to return all remaining items. These are then
|
||||
available via the usual Table interface.
|
||||
|
||||
[% USE DBI(dsn,user,pass) -%]
|
||||
|
||||
# query() returns an iterator
|
||||
[% results = DBI.query('SELECT * FROM alphabet ORDER BY letter') %]
|
||||
|
||||
# pass into Table plugin
|
||||
[% USE table(results, rows=8 overlap=1 pad=0) -%]
|
||||
|
||||
[% FOREACH row = table.cols -%]
|
||||
[% row.first.letter %] - [% row.last.letter %]:
|
||||
[% row.join(', ') %]
|
||||
[% END %]
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
204
database/perl/vendor/lib/Template/Plugin/URL.pm
vendored
Normal file
204
database/perl/vendor/lib/Template/Plugin/URL.pm
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::URL
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Template Toolkit Plugin for constructing URL's from a base stem
|
||||
# and adaptable parameters.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::URL;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
our $JOINT = '&';
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, $baseurl, \%url_params)
|
||||
#
|
||||
# Constructor method which returns a sub-routine closure for constructing
|
||||
# complex URL's from a base part and hash of additional parameters.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $base, $args) = @_;
|
||||
$args ||= { };
|
||||
|
||||
return sub {
|
||||
my $newbase = shift unless ref $_[0] eq 'HASH';
|
||||
my $newargs = shift || { };
|
||||
my $combo = { %$args, %$newargs };
|
||||
my $urlargs = join($JOINT,
|
||||
map { args($_, $combo->{ $_ }) }
|
||||
grep { defined $combo->{ $_ } && length $combo->{ $_ } }
|
||||
sort keys %$combo);
|
||||
|
||||
my $query = $newbase || $base || '';
|
||||
$query .= '?' if length $query && length $urlargs;
|
||||
$query .= $urlargs if length $urlargs;
|
||||
|
||||
return $query
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub args {
|
||||
my ($key, $val) = @_;
|
||||
$key = escape($key);
|
||||
|
||||
return map {
|
||||
"$key=" . escape($_);
|
||||
} ref $val eq 'ARRAY' ? @$val : $val;
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# escape($url)
|
||||
#
|
||||
# URL-encode data. Borrowed with minor modifications from CGI.pm.
|
||||
# Kudos to Lincold Stein.
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub escape {
|
||||
my $toencode = shift;
|
||||
return undef unless defined($toencode);
|
||||
utf8::encode($toencode);
|
||||
$toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
|
||||
return $toencode;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::URL - Plugin to construct complex URLs
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE url('/cgi-bin/foo.pl') %]
|
||||
|
||||
[% url(debug = 1, id = 123) %]
|
||||
# ==> /cgi/bin/foo.pl?debug=1&id=123
|
||||
|
||||
[% USE mycgi = url('/cgi-bin/bar.pl', mode='browse', debug=1) %]
|
||||
|
||||
[% mycgi %]
|
||||
# ==> /cgi/bin/bar.pl?mode=browse&debug=1
|
||||
|
||||
[% mycgi(mode='submit') %]
|
||||
# ==> /cgi/bin/bar.pl?mode=submit&debug=1
|
||||
|
||||
[% mycgi(debug='d2 p0', id='D4-2k[4]') %]
|
||||
# ==> /cgi-bin/bar.pl?mode=browse&debug=d2%20p0&id=D4-2k%5B4%5D
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<URL> plugin can be used to construct complex URLs from a base stem
|
||||
and a hash array of additional query parameters.
|
||||
|
||||
The constructor should be passed a base URL and optionally, a hash array
|
||||
reference of default parameters and values. Used from with a template,
|
||||
it would look something like the following:
|
||||
|
||||
[% USE url('http://www.somewhere.com/cgi-bin/foo.pl') %]
|
||||
[% USE url('/cgi-bin/bar.pl', mode='browse') %]
|
||||
[% USE url('/cgi-bin/baz.pl', mode='browse', debug=1) %]
|
||||
|
||||
When the plugin is then called without any arguments, the default base
|
||||
and parameters are returned as a formatted query string.
|
||||
|
||||
[% url %]
|
||||
|
||||
For the above three examples, these will produce the following outputs:
|
||||
|
||||
http://www.somewhere.com/cgi-bin/foo.pl
|
||||
/cgi-bin/bar.pl?mode=browse
|
||||
/cgi-bin/baz.pl?mode=browse&debug=1
|
||||
|
||||
Note that additional parameters are separated by 'C<&>' rather than
|
||||
simply 'C<&>'. This is the correct behaviour for HTML pages but is,
|
||||
unfortunately, incorrect when creating URLs that do not need to be
|
||||
encoded safely for HTML. This is likely to be corrected in a future
|
||||
version of the plugin (most probably with TT3). In the mean time, you
|
||||
can set C<$Template::Plugin::URL::JOINT> to C<&> to get the correct
|
||||
behaviour.
|
||||
|
||||
Additional parameters may be also be specified to the URL:
|
||||
|
||||
[% url(mode='submit', id='wiz') %]
|
||||
|
||||
Which, for the same three examples, produces:
|
||||
|
||||
http://www.somewhere.com/cgi-bin/foo.pl?mode=submit&id=wiz
|
||||
/cgi-bin/bar.pl?mode=browse&id=wiz
|
||||
/cgi-bin/baz.pl?mode=browse&debug=1&id=wiz
|
||||
|
||||
A new base URL may also be specified as the first option:
|
||||
|
||||
[% url('/cgi-bin/waz.pl', test=1) %]
|
||||
|
||||
producing
|
||||
|
||||
/cgi-bin/waz.pl?test=1
|
||||
/cgi-bin/waz.pl?mode=browse&test=1
|
||||
/cgi-bin/waz.pl?mode=browse&debug=1&test=1
|
||||
|
||||
The ordering of the parameters is non-deterministic due to fact that
|
||||
Perl's hashes themselves are unordered. This isn't a problem as the
|
||||
ordering of CGI parameters is insignificant (to the best of my knowledge).
|
||||
All values will be properly escaped thanks to some code borrowed from
|
||||
Lincoln Stein's C<CGI> module. e.g.
|
||||
|
||||
[% USE url('/cgi-bin/woz.pl') %]
|
||||
[% url(name="Elrich von Benjy d'Weiro") %]
|
||||
|
||||
Here the space and "C<'>" single quote characters are escaped in the output:
|
||||
|
||||
/cgi-bin/woz.pl?name=Elrich%20von%20Benjy%20d%27Weiro
|
||||
|
||||
An alternate name may be provided for the plugin at construction time
|
||||
as per regular Template Toolkit syntax.
|
||||
|
||||
[% USE mycgi = url('cgi-bin/min.pl') %]
|
||||
[% mycgi(debug=1) %]
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
97
database/perl/vendor/lib/Template/Plugin/View.pm
vendored
Normal file
97
database/perl/vendor/lib/Template/Plugin/View.pm
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::View
|
||||
#
|
||||
# DESCRIPTION
|
||||
# A user-definable view based on templates. Similar to the concept of
|
||||
# a "Skin".
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 2000-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::View;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
use Template::View;
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# new($context, \%config)
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $context = shift;
|
||||
my $view = Template::View->new($context, @_)
|
||||
|| return $class->error($Template::View::ERROR);
|
||||
$view->seal();
|
||||
return $view;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::View - Plugin to create views (Template::View)
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE view(
|
||||
prefix = 'splash/' # template prefix/suffix
|
||||
suffix = '.tt2'
|
||||
bgcol = '#ffffff' # and any other variables you
|
||||
style = 'Fancy HTML' # care to define as view metadata,
|
||||
items = [ foo, bar.baz ] # including complex data and
|
||||
foo = bar ? baz : x.y.z # expressions
|
||||
%]
|
||||
|
||||
[% view.title %] # access view metadata
|
||||
|
||||
[% view.header(title = 'Foo!') %] # view "methods" process blocks or
|
||||
[% view.footer %] # templates with prefix/suffix added
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin module creates L<Template::View> objects. Views are an
|
||||
experimental feature and are subject to change in the near future.
|
||||
In the mean time, please consult L<Template::View> for further info.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Template::View>, L<Template::Manual::Views>
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
142
database/perl/vendor/lib/Template/Plugin/Wrap.pm
vendored
Normal file
142
database/perl/vendor/lib/Template/Plugin/Wrap.pm
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
#============================================================= -*-Perl-*-
|
||||
#
|
||||
# Template::Plugin::Wrap
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Plugin for wrapping text via the Text::Wrap module.
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
#
|
||||
# This module is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#
|
||||
#============================================================================
|
||||
|
||||
package Template::Plugin::Wrap;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Template::Plugin';
|
||||
use Text::Wrap;
|
||||
|
||||
our $VERSION = '3.009';
|
||||
|
||||
sub new {
|
||||
my ($class, $context, $format) = @_;;
|
||||
$context->define_filter('wrap', [ \&wrap_filter_factory => 1 ]);
|
||||
return \&tt_wrap;
|
||||
}
|
||||
|
||||
sub tt_wrap {
|
||||
my $text = shift;
|
||||
my $width = shift || 72;
|
||||
my $itab = shift;
|
||||
my $ntab = shift;
|
||||
$itab = '' unless defined $itab;
|
||||
$ntab = '' unless defined $ntab;
|
||||
$Text::Wrap::columns = $width;
|
||||
Text::Wrap::wrap($itab, $ntab, $text);
|
||||
}
|
||||
|
||||
sub wrap_filter_factory {
|
||||
my ($context, @args) = @_;
|
||||
return sub {
|
||||
my $text = shift;
|
||||
tt_wrap($text, @args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Plugin::Wrap - Plugin interface to Text::Wrap
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
[% USE wrap %]
|
||||
|
||||
# call wrap subroutine
|
||||
[% wrap(mytext, width, initial_tab, subsequent_tab) %]
|
||||
|
||||
# or use wrap FILTER
|
||||
[% mytext FILTER wrap(width, initital_tab, subsequent_tab) %]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin provides an interface to the L<Text::Wrap> module which
|
||||
provides simple paragraph formatting.
|
||||
|
||||
It defines a C<wrap> subroutine which can be called, passing the input
|
||||
text and further optional parameters to specify the page width (default:
|
||||
72), and tab characters for the first and subsequent lines (no defaults).
|
||||
|
||||
[% USE wrap %]
|
||||
|
||||
[% text = BLOCK %]
|
||||
First, attach the transmutex multiplier to the cross-wired
|
||||
quantum homogeniser.
|
||||
[% END %]
|
||||
|
||||
[% wrap(text, 40, '* ', ' ') %]
|
||||
|
||||
Output:
|
||||
|
||||
* First, attach the transmutex
|
||||
multiplier to the cross-wired quantum
|
||||
homogeniser.
|
||||
|
||||
It also registers a C<wrap> filter which accepts the same three optional
|
||||
arguments but takes the input text directly via the filter input.
|
||||
|
||||
Example 1:
|
||||
|
||||
[% FILTER bullet = wrap(40, '* ', ' ') -%]
|
||||
First, attach the transmutex multiplier to the cross-wired quantum
|
||||
homogeniser.
|
||||
[%- END %]
|
||||
|
||||
Output:
|
||||
|
||||
* First, attach the transmutex
|
||||
multiplier to the cross-wired quantum
|
||||
homogeniser.
|
||||
|
||||
Example 2:
|
||||
|
||||
[% FILTER bullet -%]
|
||||
Then remodulate the shield to match the harmonic frequency, taking
|
||||
care to correct the phase difference.
|
||||
[% END %]
|
||||
|
||||
Output:
|
||||
|
||||
* Then remodulate the shield to match
|
||||
the harmonic frequency, taking
|
||||
care to correct the phase difference.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
The L<Text::Wrap> module was written by David Muir Sharnoff
|
||||
with help from Tim Pierce and many others.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
|
||||
|
||||
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::Plugin>, L<Text::Wrap>
|
||||
|
||||
Reference in New Issue
Block a user