1CGI::Prototype(3) User Contributed Perl Documentation CGI::Prototype(3)
2
3
4
6 CGI::Prototype - Create a CGI application by subclassing
7
9 package My::HelloWorld;
10 use base CGI::Prototype;
11
12 sub template { \ <<'END_OF_TEMPLATE' }
13 [% self.CGI.header; %]
14 Hello world at [% USE Date; Date.format(date.now) ⎪ html %]!
15 END_OF_TEMPLATE
16
17 My::HelloWorld->activate;
18
20 The core of every CGI application seems to be roughly the same:
21
22 · Analyze the incoming parameters, cookies, and URLs to determine the
23 state of the application (let's call this "dispatch").
24
25 · Based on the current state, analyze the incoming parameters to
26 respond to any form submitted ("respond").
27
28 · From there, decide what response page should be generated, and pro‐
29 duce it ("render").
30
31 CGI::Prototype creates a "Class::Prototyped" engine for doing all this,
32 with the right amount of callback hooks to customize the process.
33 Because I'm biased toward Template Toolkit for rendering HTML, I've
34 also integrated that as my rendering engine of choice. And, being a
35 fan of clean MVC designs, the classes become the controllers, and the
36 templates become the views, with clean separation of responsibilities,
37 and "CGI::Prototype" a sort of "archetypal" controller.
38
39 You can create the null application by simply activating it:
40
41 use CGI::Prototype;
42 CGI::Prototype->activate;
43
44 But this won't be very interesting. You'll want to subclass this class
45 in a "Class::Prototyped"-style manner to override most of its behavior.
46 Slots can be added to add or alter behavior. You can subclass your
47 subclasses when groups of your CGI pages share similar behavior. The
48 possibilities are mind-boggling.
49
50 Within the templates, "self" refers to the current controller. Thus,
51 you can define callbacks trivially. In your template, if you need some
52 data, you can pull it as a request:
53
54 [% my_data = self.get_some_big_data %]
55
56 which is supplied by simply adding the same slot (method or data) in
57 the controlling class:
58
59 sub get_some_big_data {
60 my $self = shift;
61 return $self->some_other_method(size => 'big');
62 }
63
64 And since the classes are hierarchical, you can start out with an
65 implementation for one page, then move it to a region or globally
66 quickly.
67
68 Although the name "CGI::Prototype" implies a CGI protocol, I see no
69 reason that this would not work with "Apache::Registry" in a "mod_perl"
70 environment, or a direct content handler such as:
71
72 package My::App;
73 use base CGI::Prototype;
74 sub handler {
75 __PACKAGE__->activate;
76 }
77
78 Note that the $r request object will have to be created if needed if
79 you use this approach.
80
81 CORE SLOTS
82
83 These slots provide core functionality. You will probably not need to
84 override these.
85
86 activate
87 Invoke the "activate" slot to "activate" your application, causing
88 it to process the incoming CGI values, select a page to be respond
89 to the parameters, which in turn selects a page to render, and then
90 responds with that page. For example, your App might consist only
91 of:
92
93 package My::App;
94 use base qw(CGI::Prototype);
95 My::App->activate;
96
97 Again, this will not be interesting, but it shows that the null app
98 is easy to create. Almost always, you will want to override some
99 of the "callback" slots below.
100
101 CGI Invoking "$self->CGI" gives you access to the CGI.pm object repre‐
102 senting the incoming parameters and other CGI.pm-related values.
103 For example,
104
105 $self->CGI->self_url
106
107 generates a self-referencing URL. From a template, this is:
108
109 [% self.CGI.self_url %]
110
111 for the same thing.
112
113 See "initialize_CGI" for how this slot gets established.
114
115 render
116 The "render" method uses the results from "engine" and "template"
117 to process a selected template through Template Toolkit. If the
118 result does not throw an error, "$self->display" is called to show
119 the result.
120
121 display
122 The "display" method is called to render the output of the template
123 under normal circumstances, normally dumping the first parameter to
124 "STDOUT". Test harnesses may override this method to cause the
125 output to appear into a variable, but normally this method is left
126 alone.
127
128 param
129 The "param" method is a convenience method that maps to
130 "$self->CGI->param", because accessing params is a very common
131 thing.
132
133 interstitial
134 Please note that this feature is still experimental and subject to
135 change.
136
137 Use this in your per-page respond methods if you have a lot of
138 heavy processing to perform. For example, suppose you're deleting
139 something, and it takes 5 seconds to do the first step, and 3 sec‐
140 onds to do the second step, and then you want to go back to normal
141 web interaction. Simulating the heavy lifting with sleep, we get:
142
143 my $p = $self->interstitial
144 ({ message => "Your delete is being processed...",
145 action => sub { sleep 5 },
146 },
147 { message => "Just a few seconds more....",
148 action => sub { sleep 3 },
149 },
150 );
151 return $p if $p;
152
153 "interstitial" returns either a page that should be returned so
154 that it can be rendered (inside a wrapper that provides the stan‐
155 dard top and bottom of your application page), or "undef".
156
157 The list passed to "interstitial" should be a series of hashrefs
158 with one or more parameters reflecting the steps:
159
160 message
161 What the user should see while the step is computing.
162 (Default: "Working...".)
163
164 action
165 A coderef with the action performed server-side during the mes‐
166 sage. (Default: no action.)
167
168 delay
169 The number of seconds the browser should wait before initiating
170 the next connection, triggering the start of "action".
171 (Default: 0 seconds.)
172
173 The user sees the first message at the first call to "interstitial"
174 (via the first returned page), at which time a meta-refresh will
175 immediately repost the same parameters as on the call that got you
176 here. (Thus, it's important not to have changed the params yet, or
177 you might end up in a different part of your code.) When the call
178 to "interstitial" is re-executed, the first coderef is then per‐
179 formed. At the end of that coderef, the second interstitial page
180 is returned, and the user sees the second message, which then per‐
181 forms the next meta-refresh, which gets us back to this call to
182 "interstitial" again (whew). The second coderef is executed while
183 the user is seeing the second message, and then "interstitial"
184 returns "undef", letting us roll through to the final code. Slick.
185
186 config_interstitial_param
187 This parameter is used by "interstitial" to determine the process‐
188 ing step. You should ensure that the name doesn't conflict with
189 any other param that you might need.
190
191 The default value is "_interstitial".
192
193 CALLBACK SLOTS
194
195 engine
196 The engine returns a Template object that will be generating any
197 response. The object is computed lazily (with autoloading) when
198 needed.
199
200 The Template object is passed the configuration returned from the
201 "engine_config" callback.
202
203 engine_config
204 Returns a hashref of desired parameters to pass to the "Template"
205 "new" method as a configuration. Defaults to an empty hash.
206
207 prototype_enter
208 Called when the prototype mechanism is entered, at the very begin‐
209 ning of each hit. Defaults to calling "-"initialize_CGI>, which
210 see.
211
212 Generally, you should not override this method. If you do, be sure
213 to call the SUPER method, in case future versions of this module
214 need additional initialization.
215
216 prototype_leave
217 Called when the prototype mechanism is exited, at the very end of
218 each hit. Defaults to no action.
219
220 Generally, you should not override this method. If you do, be sure
221 to call the SUPER method, in case future versions of this module
222 need additional teardown.
223
224 initialize_CGI
225 Sets up the CGI slot as an autoload, defaulting to creating a new
226 CGI.pm object. Called from "prototype_enter".
227
228 app_enter
229 Called when the application is entered, at the very beginning of
230 each hit. Defaults to no action.
231
232 app_leave
233 Called when the application is left, at the very end of each hit.
234 Defaults to no action.
235
236 control_enter
237 Called when a page gains control, either at the beginning for a
238 response, or in the middle when switched for rendering. Defaults
239 to nothing.
240
241 This is a great place to hang per-page initialization, because
242 you'll get this callback at most once per hit.
243
244 control_leave
245 Called when a page loses control, either after a response phase
246 because we're switching to a new page, or render phase after we've
247 delivered the new text to the browser.
248
249 This is a great place to hang per-page teardown, because you'll get
250 this callback at most once per hit.
251
252 render_enter
253 Called when a page gains control specifically for rendering (deliv‐
254 ering text to the browser), just after "control_enter" if needed.
255
256 render_leave
257 Called when a page loses control specifically for rendering (deliv‐
258 ering text to the browser), just before "control_leave".
259
260 respond_enter
261 Called when a page gains control specifically for responding
262 (understanding the incoming parameters, and deciding what page
263 should render the response), just after "control_enter".
264
265 respond_leave
266 Called when a page loses control specifically for rendering (under‐
267 standing the incoming parameters, and deciding what page should
268 render the response), just before "control_leave" (if needed).
269
270 template
271 Delivers a template document object (something compatible to the
272 "Template" "process" method, such as a "Template::Document" or a
273 filehandle or a reference to a scalar). The default is a simple
274 "this page intentionally left blank" template.
275
276 When rendered, the only extra global variable passed into the tem‐
277 plate is the "self" variable, representing the controller object.
278 However, as seen earlier, this is sufficient to allow access to
279 anything you need from the template, thanks to Template Toolkit's
280 ability to call methods on an object and understand the results.
281
282 For example, to get at the "barney" parameter:
283
284 The barney field is [% self.param("barney") ⎪ html %].
285
286 error
287 Called if an uncaught error is triggered in any of the other steps,
288 passing the error text or object as the first method parameter.
289 The default callback simply displays the output to the browser,
290 which is highly insecure and should be overridden, perhaps with
291 something that logs the error and puts up a generic error message
292 with an incident code for tracking.
293
294 dispatch
295 Called to analyze the incoming parameters to define which page
296 object gets control based on the incoming CGI parameters.
297
298 This callback must return a page object (the object taking control
299 during the response phase). By default, this callback returns the
300 application itself.
301
302 respond
303 Called to determine how to respond specifically to this set of
304 incoming parameters. Probably updates databases and such.
305
306 This callback must return a page object (the object taking control
307 during the render phase). By default, this callback returns the
308 same object that had control during the response phase ("stay here"
309 logic), which works most of the time.
310
312 Class::Prototyped, Template::Manual, <http://www.stonehenge.com/mer‐
313 lyn/LinuxMag/col56.html>.
314
316 Please report any bugs or feature requests to bug-cgi-proto‐
317 type@rt.cpan.org, or through the web interface at http://rt.cpan.org. I
318 will be notified, and then you'll automatically be notified of progress
319 on your bug as I make changes.
320
322 Randal L. Schwartz, <merlyn@stonehenge.com>
323
324 Special thanks to Geekcruises.com and an unnamed large university for
325 providing funding for the development of this module.
326
328 Copyright (C) 2003, 2004, 2005 by Randal L. Schwartz
329
330 This library is free software; you can redistribute it and/or modify it
331 under the same terms as Perl itself, either Perl version 5.8.5 or, at
332 your option, any later version of Perl 5 you may have available.
333
334
335
336perl v5.8.8 2005-03-23 CGI::Prototype(3)