-
Notifications
You must be signed in to change notification settings - Fork 94
/
Plugin.html
254 lines (241 loc) · 7.75 KB
/
Plugin.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
[%#
# IMPORTANT NOTE
# This documentation is generated automatically from source
# templates. Any changes you make here may be lost.
#
# The 'docsrc' documentation source bundle is available for download
# from http://www.template-toolkit.org/docs.html and contains all
# the source templates, XML files, scripts, etc., from which the
# documentation for the Template Toolkit is built.
-%]
[% META book = 'Modules'
page = 'Plugin'
%]
[% WRAPPER toc;
INCLUDE tocitem title='SYNOPSIS';
INCLUDE tocitem title='DESCRIPTION';
INCLUDE tocitem title='PLUGIN API';
INCLUDE tocitem title='DEEPER MAGIC';
INCLUDE tocitem title='Template::Plugin Delegation';
INCLUDE tocitem title='AUTHOR';
INCLUDE tocitem title='VERSION';
INCLUDE tocitem title='COPYRIGHT';
INCLUDE tocitem title='SEE ALSO';
END
%]
<!-- Pod to HTML conversion by the Template Toolkit version 2 -->
[% WRAPPER section
title='SYNOPSIS'
-%]<pre> package MyOrg::Template::Plugin::MyPlugin;
use base qw( Template::Plugin );
use Template::Plugin;
use MyModule;</pre>
<pre> sub new {
my $class = shift;
my $context = shift;
bless {
...
}, $class;
}</pre>
[%- END %]
[% WRAPPER section
title='DESCRIPTION'
-%]<p>
A "plugin" for the Template Toolkit is simply a Perl module which
exists in a known package location (e.g. Template::Plugin::*) and
conforms to a regular standard, allowing it to be loaded and used
automatically.
</p>
<p>
The Template::Plugin module defines a base class from which other
plugin modules can be derived. A plugin does not have to be derived
from Template::Plugin but should at least conform to its object-oriented
interface.
</p>
<p>
It is recommended that you create plugins in your own package namespace
to avoid conflict with toolkit plugins. e.g.
</p>
<pre> package MyOrg::Template::Plugin::FooBar;</pre>
<p>
Use the PLUGIN_BASE option to specify the namespace that you use. e.g.
</p>
<pre> use Template;
my $template = Template->new({
PLUGIN_BASE => 'MyOrg::Template::Plugin',
});</pre>
[%- END %]
[% WRAPPER section
title='PLUGIN API'
-%]<p>
The following methods form the basic interface between the Template
Toolkit and plugin modules.
</p>
<ul>
<li><b>load($context)</b><br>
<p>
This method is called by the Template Toolkit when the plugin module
is first loaded. It is called as a package method and thus implicitly
receives the package name as the first parameter. A reference to the
Template::Context object loading the plugin is also passed. The
default behaviour for the load() method is to simply return the class
name. The calling context then uses this class name to call the new()
package method.
</p>
<pre> package MyPlugin;</pre>
<pre> sub load { # called as MyPlugin->load($context)
my ($class, $context) = @_;
return $class; # returns 'MyPlugin'
}</pre>
<li><b>new($context, @params)</b><br>
<p>
This method is called to instantiate a new plugin object for the USE
directive. It is called as a package method against the class name
returned by load(). A reference to the Template::Context object creating
the plugin is passed, along with any additional parameters specified in
the USE directive.
</p>
<pre> sub new { # called as MyPlugin->new($context)
my ($class, $context, @params) = @_;
bless {
_CONTEXT => $context,
}, $class; # returns blessed MyPlugin object
}</pre>
<li><b>error($error)</b><br>
<p>
This method, inherited from the Template::Base module, is used for
reporting and returning errors. It can be called as a package method
to set/return the $ERROR package variable, or as an object method to
set/return the object _ERROR member. When called with an argument, it
sets the relevant variable and returns undef. When called without an
argument, it returns the value of the variable.
</p>
<pre> sub new {
my ($class, $context, $dsn) = @_;</pre>
<pre> return $class->error('No data source specified')
unless $dsn;</pre>
<pre> bless {
_DSN => $dsn,
}, $class;
}</pre>
<pre> ...</pre>
<pre> my $something = MyModule->new()
|| die MyModule->error(), "\n";</pre>
<pre> $something->do_something()
|| die $something->error(), "\n";</pre>
</ul>
[%- END %]
[% WRAPPER section
title='DEEPER MAGIC'
-%]<p>
The Template::Context object that handles the loading and use of
plugins calls the new() and error() methods against the package name
returned by the load() method. In pseudo-code terms, it might look
something like this:
</p>
<pre> $class = MyPlugin->load($context); # returns 'MyPlugin'</pre>
<pre> $object = $class->new($context, @params) # MyPlugin->new(...)
|| die $class->error(); # MyPlugin->error()</pre>
<p>
The load() method may alterately return a blessed reference to an
object instance. In this case, new() and error() are then called as
<i>object</i> methods against that prototype instance.
</p>
<pre> package YourPlugin;</pre>
<pre> sub load {
my ($class, $context) = @_;
bless {
_CONTEXT => $context,
}, $class;
}</pre>
<pre> sub new {
my ($self, $context, @params) = @_;
return $self;
}</pre>
<p>
In this example, we have implemented a 'Singleton' plugin. One object
gets created when load() is called and this simply returns itself for
each call to new().
</p>
<p>
Another implementation might require individual objects to be created
for every call to new(), but with each object sharing a reference to
some other object to maintain cached data, database handles, etc.
This pseudo-code example demonstrates the principle.
</p>
<pre> package MyServer;</pre>
<pre> sub load {
my ($class, $context) = @_;
bless {
_CONTEXT => $context,
_CACHE => { },
}, $class;
}</pre>
<pre> sub new {
my ($self, $context, @params) = @_;
MyClient->new($self, @params);
}</pre>
<pre> sub add_to_cache { ... }</pre>
<pre> sub get_from_cache { ... }</pre>
<pre> package MyClient;</pre>
<pre> sub new {
my ($class, $server, $blah) = @_;
bless {
_SERVER => $server,
_BLAH => $blah,
}, $class;
}</pre>
<pre> sub get {
my $self = shift;
$self->{ _SERVER }->get_from_cache(@_);
}</pre>
<pre> sub put {
my $self = shift;
$self->{ _SERVER }->add_to_cache(@_);
}</pre>
<p>
When the plugin is loaded, a MyServer instance is created. The new()
method is called against this object which instantiates and returns a
MyClient object, primed to communicate with the creating MyServer.
</p>
[%- END %]
[% WRAPPER section
title='Template::Plugin Delegation'
-%]<p>
As of version 2.01, the Template::Plugin module no longer provides an
AUTOLOAD method to delegate to other objects or classes. This was a
badly designed featured that caused more trouble than good. You can
easily add your own AUTOLOAD method to perform delegation if you
require this kind of functionality.
</p>
[%- END %]
[% WRAPPER section
title='AUTHOR'
-%]<p>
Andy Wardley <abw@kfs.org>
</p>
<p>
[% ttlink('http://www.andywardley.com/', 'http://www.andywardley.com/') -%]
</p>
[%- END %]
[% WRAPPER section
title='VERSION'
-%]<p>
Template Toolkit version 2.02, released on 4th March 2001.
</p>
[%- END %]
[% WRAPPER section
title='COPYRIGHT'
-%]<pre> Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved.
Copyright (C) 1998-2001 Canon Research Centre Europe Ltd.</pre>
<p>
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
</p>
[%- END %]
[% WRAPPER section
title='SEE ALSO'
-%]<p>
[% ttlink('Template', 'Template') -%], [% ttlink('Template::Plugins', 'Template::Plugins') -%], [% ttlink('Template::Context', 'Template::Context') -%]
</p>
[%- END %]