File Coverage

blib/lib/CGI/Prototype.pm
Criterion Covered Total %
statement 65 81 80.2
branch 6 12 50.0
condition 0 12 0.0
subroutine 26 28 92.8
pod 22 22 100.0
total 119 155 76.7


line stmt bran cond sub pod time code
1             package CGI::Prototype;
2              
3 3     3   2885 use 5.006;
  3         12  
  3         121  
4 3     3   16 use strict;
  3         5  
  3         96  
5 3     3   25 use warnings;
  3         4  
  3         114  
6              
7 3     3   21 use base qw(Class::Prototyped);
  3         4  
  3         4467  
8              
9             ## no exports
10              
11             our $VERSION = '0.9054';
12              
13             our $_mirror = __PACKAGE__->reflect; # for slots that aren't subs
14              
15             =head1 NAME
16              
17             CGI::Prototype - Create a CGI application by subclassing
18              
19             =head1 SYNOPSIS
20              
21             package My::HelloWorld;
22             use base CGI::Prototype;
23              
24             sub template { \ <<'END_OF_TEMPLATE' }
25             [% self.CGI.header; %]
26             Hello world at [% USE Date; Date.format(date.now) | html %]!
27             END_OF_TEMPLATE
28              
29             My::HelloWorld->activate;
30              
31             =head1 DESCRIPTION
32              
33             The core of every CGI application seems to be roughly the same:
34              
35             =over 4
36              
37             =item *
38              
39             Analyze the incoming parameters, cookies, and URLs to determine the
40             state of the application (let's call this "dispatch").
41              
42             =item *
43              
44             Based on the current state, analyze the incoming parameters to respond
45             to any form submitted ("respond").
46              
47             =item *
48              
49             From there, decide what response page should be generated, and produce
50             it ("render").
51              
52             =back
53              
54             L creates a C engine for doing all
55             this, with the right amount of callback hooks to customize the
56             process. Because I'm biased toward Template Toolkit for rendering
57             HTML, I've also integrated that as my rendering engine of choice.
58             And, being a fan of clean MVC designs, the classes become the
59             controllers, and the templates become the views, with clean separation
60             of responsibilities, and C a sort of "archetypal"
61             controller.
62              
63             You can create the null application by simply I it:
64              
65             use CGI::Prototype;
66             CGI::Prototype->activate;
67              
68             But this won't be very interesting. You'll want to subclass this
69             class in a C-style manner to override most of its
70             behavior. Slots can be added to add or alter behavior. You can
71             subclass your subclasses when groups of your CGI pages share similar
72             behavior. The possibilities are mind-boggling.
73              
74             Within the templates, C refers to the current controller. Thus,
75             you can define callbacks trivially. In your template, if you need some
76             data, you can pull it as a request:
77              
78             [% my_data = self.get_some_big_data %]
79              
80             which is supplied by simply adding the same slot (method or data) in
81             the controlling class:
82              
83             sub get_some_big_data {
84             my $self = shift;
85             return $self->some_other_method(size => 'big');
86             }
87              
88             And since the classes are hierarchical, you can start out with an
89             implementation for one page, then move it to a region or globally
90             quickly.
91              
92             Although the name C implies a CGI protocol, I see no
93             reason that this would not work with C in a
94             C environment, or a direct content handler such as:
95              
96             package My::App;
97             use base CGI::Prototype;
98             sub handler {
99             __PACKAGE__->activate;
100             }
101              
102             Note that the C<$r> request object will have to be created if needed
103             if you use this approach.
104              
105             =head2 CORE SLOTS
106              
107             These slots provide core functionality. You will probably not
108             need to override these.
109              
110             =over 4
111              
112             =item activate
113              
114             Invoke the C slot to "activate" your application,
115             causing it to process the incoming CGI values, select a page to be
116             respond to the parameters, which in turn selects a page to render, and
117             then responds with that page. For example, your App might consist
118             only of:
119              
120             package My::App;
121             use base qw(CGI::Prototype);
122             My::App->activate;
123              
124             Again, this will not be interesting, but it shows that the null app
125             is easy to create. Almost always, you will want to override some
126             of the "callback" slots below.
127              
128             =cut
129              
130             sub activate {
131 4     4 1 9308 my $self = shift;
132 4         8 eval {
133 4         22 $self->prototype_enter;
134 4         603 $self->app_enter;
135 4         34 my $this_page = $self->dispatch;
136 4         52 $this_page->control_enter;
137 4         103 $this_page->respond_enter;
138 4         30 my $next_page = $this_page->respond;
139 4         37 $this_page->respond_leave;
140 4 100       37 if ($this_page ne $next_page) {
141 1         479 $this_page->control_leave;
142 1         21 $next_page->control_enter;
143             }
144 4         125 $next_page->render_enter;
145 4         39 $next_page->render;
146 3         63 $next_page->render_leave;
147 3         33 $next_page->control_leave;
148 3         35 $self->app_leave;
149 3         39 $self->prototype_leave;
150             };
151 4 100       36098 $self->error($@) if $@; # failed something, go to safe mode
152             }
153              
154             =item CGI
155              
156             Invoking C<< $self->CGI >> gives you access to the CGI.pm object
157             representing the incoming parameters and other CGI.pm-related values.
158             For example,
159              
160             $self->CGI->self_url
161              
162             generates a self-referencing URL. From a template, this is:
163              
164             [% self.CGI.self_url %]
165              
166             for the same thing.
167              
168             See C for how this slot gets established.
169              
170             =cut
171              
172             $_mirror->addSlot
173 2     2   4509 (CGI => sub { die shift, "->initialize_CGI not called" });
174              
175             =item render
176              
177             The C method uses the results from C and C