.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Template::Plugin::VMethods 3" .TH Template::Plugin::VMethods 3 "2003-09-03" "perl v5.8.8" "User Contributed Perl Documentation" .SH "NAME" Template::Plugin::VMethods \- install vmethods .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& package Template::Plugin::ReverseVMethod; \& use base qw(Template::Plugin::VMethods); \& @SCALAR_OPS = qw(reverse); .Ve .PP .Vb 5 \& sub reverse \& { \& my $string = shift; \& scalar reverse $string; \& } .Ve .PP .Vb 1 \& 1; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Simple base class to allow your module to install and remove virtual methods into the Template Toolkit. .PP All you need to do in your package is declare one or more of the variables \f(CW@LIST_OPS\fR, \f(CW@SCALAR_OPS\fR or \f(CW@HASH_OPS\fR to indicate what virtual methods you want to export. .PP These can either be the names of functions in your package, or name/subroutine reference pairs. .PP For example, using named functions: .PP .Vb 5 \& package Template::Plugin::HexVMethod; \& use base qw(Template::Plugin::VMethods); \& @SCALAR_OPS = ( "hex" ); \& sub hex { sprintf "%x", $_[0] }; \& 1; .Ve .PP For example, using the name and subroutine ref pairs: .PP .Vb 7 \& package Template::Plugin::DoubleVMethod; \& use base qw(Template::Plugin::VMethods); \& @SCALAR_OPS = ( double => \e&double_string); \& @LIST_OPS = ( double => \e&double_list); \& sub double_string { $_[0]x2 } \& sub double_list { [ (@{ $_[0] }) x 2] } \& 1; .Ve .PP For example, mixing the two freely: .PP .Vb 10 \& package CaesarVMethod; \& use base qw(Template::Plugin::VMethods); \& @SCALAR_OPS = ( "caesar", \& "rot13" => sub { caesar($_[0],"13") } ); \& sub caesar \& { \& $string = shift; \& $string =~ tr/A-Za-z/B-ZAb-za/ for 1..$_[0]; \& return $string; \& } .Ve .Sh "Using VMethods Based Plugins" .IX Subsection "Using VMethods Based Plugins" Once you've done this people can use your plugin just like they would any other: .PP .Vb 3 \& [% USE CaesarVMethod %] \& [% foo = "Crbcyr jub yvxr gur pbybhe benatr ner fvyyl" %] \& The secret phrase is [% foo.rot13 %] .Ve .PP The vmethods will remain in effect till the end of the template, meaning all templates called from within this template (i.e. via \&\s-1PROCESS\s0, \s-1INCLUDE\s0, \s-1WRAPPER\s0, etc) will be able to access the VMethods. .PP It's possible to permanently install the vmethods from perl space, so that all instances of Template everywhere will always have access to all the vmethods by using your plugin like so: .PP .Vb 1 \& use Template::Plugin::CaesarVMethod 'install'; .Ve .Sh "Using subroutines from other classes." .IX Subsection "Using subroutines from other classes." Instead of writing virtual methods, you might be using the \&\fBTemplate::Plugin::Procedural\fR class: .PP .Vb 6 \& package Template::Plugin::MD5; \& use base qw(Template::Plugin::Procedural); \& use Digest::MD5; \& sub md5 { Digest::MD5::md5_hex(@_) }; \& sub md5_base64 { Digest::MD5::md5_base64(@_) }; \& 1; .Ve .PP And you'll be calling the methods as so from within the template: .PP .Vb 2 \& [% USE MD5 %] \& [% MD5.md5(foo) %] .Ve .PP You'd rather use VMethods though, to do things like this: .PP .Vb 2 \& [% USE MD5VMethods %] \& [% foo.md5 %] .Ve .PP The obvious way to do this is to load the original class and take references to those subroutines: .PP .Vb 6 \& package Template::Plugin::MD5VMethods; \& use base qw(Template::Plugin::VMethods); \& use Template::Plugin::MD5; \& @SCALAR_OPS = (md5 => \e&Template::Plugin::MD5::md5, \& md5_base64 => \e&Template::Plugin::MD5::md5_base64); \& 1; .Ve .PP This can get awfully tedious very soon when you're attempting to re-wrap a class with many subroutines in it. Because of this \&\fBTemplate::Plugin::VMethods\fR allows you to use a special variable \&\fB$VMETHOD_PACKAGE\fR which can be used to alter the package this module uses to find named VMethods. .PP .Vb 6 \& package Template::Plugin::MD5VMethods; \& use base qw(Template::Plugin::VMethods); \& use Template::Plugin::MD5; \& $VMETHOD_PACKAGE = 'Template::Plugin::MD5'; \& @SCALAR_OPS = qw(md5 md5_base64); \& 1; .Ve .SH "BUGS" .IX Header "BUGS" This module has an 'import' and a 'new' method; If you implement any of these in your subclass you'll need to chain the methods like this: .PP .Vb 4 \& sub new \& { \& my $class = shift; \& my $this = $class->SUPER::new(@_); .Ve .PP .Vb 2 \& ... \& } .Ve .PP Even if you manually redefine a VMethod that this module has defined (by manually assigning to the \f(CW$Template::Stash::\fR*_OPS variables) then that VMethod will still be restored to the value that it had before the \s-1USE\s0 statement that installed the VMethod you are overriding as soon as you leave the template that that \s-1USE\s0 method was declared in. .PP Sharing \f(CW$Template::Stash::\fR*_OPS across threads will really screw this whole system up; But you weren't going to do that anyway, were you? .PP Further bugs (and requests for new features) can be reported to the author though the \s-1CPAN\s0 \s-1RT\s0 system: .SH "AUTHOR" .IX Header "AUTHOR" Written by Mark Fowler .PP Copyright Mark Fowler 2003. All Rights Reserved. .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .PP Caesar code example adapted from Crypt::Caesar by Juerd .SH "SEE ALSO" .IX Header "SEE ALSO" Template::Stash