d15c8c366aa1f0e3e3a6be4f5332420369df9f82
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / ExtendingCatalyst.pod
1 =head1 NAME
2
3 Catalyst::Manual::ExtendingCatalyst - Extending The Framework
4
5 =head1 DESCRIPTION
6
7 This document will provide you with access points, techniques and best
8 practices to extend the framework itself or to find more elegant ways
9 to abstract and use your own code.
10
11 The L<Catalyst> core developer community tries to build and evolve the 
12 framework in a design that won't get in your way. There are many entry
13 points to alter or extend the behaviour of the framework and the 
14 applications built upon it, and it can be confusing at first to decide
15 on a place to start. This document is written to help you orient 
16 yourself in the possibilities, current practices and their consequences.
17
18 Please read the L<BEST PRACTICES> section before deciding on a design,
19 especially if you plan to release your code to the CPAN. The Catalyst
20 developer and user communities, which you naturally also belong to, will
21 benefit most if we all work together and coordinate. 
22
23 If you are unsure on an implementation or have an idea you would like to
24 have RfC'ed, it surely is a good idea to send your questions and 
25 suggestions to the Catalyst mailing list (See L<Catalyst/SUPPORT>) or
26 come to the C<#catalyst> channel on the C<irc.perl.org> network. You 
27 might also want to refer to those places for research if a module doing 
28 what you're trying to implement already exists. This might give you 
29 either a solution to your problem or a already built base, which gives 
30 you at least a head start.
31
32 =head1 BEST PRACTICES
33
34 During Catalyst's early days, it was common to write plugins to provide
35 functionality application wide. Since then, Catalyst grew a lot more 
36 flexible and powerful. It soon became a best practice to use some other
37 form of abstraction or interface, to keep the scope of its influence as
38 close as possible to where it belongs.
39
40 For those in a hurry, here's a quick checklist of some fundamental 
41 points. If you are going to read the whole thing anyway, you can jump 
42 forward to L</Namespaces>.
43
44 =head2 Quick Checklist
45
46 =over
47
48 =item Use the C<CatalystX::*> namespace if you can!
49
50 Excluding plugins and of course your C<MyApp> code. B<Mind the X!>
51
52 =item Don't make it a plugin unless you have to!
53
54 A plugin should be careful as it declares in global namespace.
55
56 =item There's a community. Use it!
57
58 There are many experienced developers in the Catalyst community, there's
59 always the IRC channel and the mailing list to discuss things.
60
61 =item Add tests and documentation!
62
63 This gives a stable base for contribution, and even more important, 
64 trust. The easiest way is a test application. See
65 L<Catalyst::Manual::Tutorial::Testing> for more information.
66
67 =back
68
69 =head2 Namespaces
70
71 While some core extensions (engines, plugins, etc.) have to be placed in
72 the C<Catalyst::*> namespace, the Catalyst core would like to ask 
73 developers to use the C<CatalystX::*> namespace if possible.
74
75 When you try to put a base class for a C<Model>, C<View> or C<Controller>
76 directly under your C<MyApp> directory as, for example, 
77 C<MyApp::Controller::Foo>, you will have the problem that Catalyst will 
78 try to load that base class as a component of your application. The 
79 solution is simple: Use another namespace. Common ones are 
80 C<MyApp::Base::Controller::*> or C<MyApp::ControllerBase::*> as examples.
81
82 =head2 Can it be a simple module?
83
84 Sometimes you want to use functionality in your application that doesn't
85 require the framework at all. Remember that Catalyst is just Perl and you
86 always can just C<use> a module. If you have application specific code 
87 that doesn't need the framework, there is no problem in putting it in 
88 your C<MyApp::*> namespace. Just don't put it in C<Model>, C<Controller> 
89 or C<View>, because that would make Catalyst try to load them as 
90 components.
91
92 =head2 Inheritance and overriding methods
93
94 While Catalyst itself is still based on L<NEXT>, extension developers
95 are encouraged to use L<Class::C3>, which is what Catalyst will be 
96 switching to in some point in the future.
97
98 When overriding a method, keep in mind that some day additionally
99 arguments may be provided to the method, if the last parameter is not
100 a flat list. It is thus better to override a method by shifting the
101 invocant off of C<@_> and assign the rest of the used arguments, so
102 you can pass your complete arguments to the original method via C<@_>:
103
104   use Class::C3;
105   ...
106
107   sub foo {
108       my $self = shift;
109       my ($bar, $baz) = @_;
110       # ...
111       return $self->next::method(@_);
112   }
113
114 If you would do the common
115
116   my ($self, $foo, $bar) = @_;
117
118 you'd have to use a much uglier construct to ensure that all arguments
119 will be passed along and the method is future proof:
120
121   $self->next::method(@_[ 1 .. $#_ ]);
122
123 =head2 Tests and documentation
124
125 When you release your module to the CPAN, proper documentation and at 
126 least a basic test suite (which means more than pod or even just 
127 C<use_ok>, sorry) gives people a good base to contribute to the module. 
128 It also shows that you care for your users. If you would like your 
129 module to become a recommended addition, these things will prove 
130 invaluable.
131
132 =head2 Maintenance
133
134 In planning to release a module to a broad community like those of 
135 Catalyst or CPAN and Perl themselves, you should include beforehand if 
136 you can spare the resources to keep it up to date, fix bugs and include 
137 contributions.
138
139 If you're not sure about this, you can always ask in the proper Catalyst
140 or Perl channels if someone else might be interested in the project, and
141 would jump in as co-maintainer.
142
143 A public repository can further ease interaction with the community. Even
144 read only access enables people to provide you with patches to your 
145 current development version. subversion, SVN and SVK, are broadly 
146 preferred in the Catalyst community.
147
148 If you're developing a Catalyst extension, please consider asking the 
149 core team for space in Catalyst's own subversion repository. You can get
150 in touch about this via IRC or the Catalyst developers mailing list.
151
152 =head2 The context object
153
154 Sometimes you want to get a hold of the context object in a component
155 that was created on startup time, where no context existed yet. Often 
156 this is about the model reading something out of the stash or other
157 context information (current language, for example). 
158
159 First it should be said that, if you use the context object in your
160 component and therefor tie it to an existing request, you might get into
161 problems when you try to use the component (e.g. the model, which would 
162 be the most common case) outside of Catalyst, for example in cronjobs.
163
164 A stable solution to this problem is to design the Catalyst model 
165 separately from the underlying model logic. Let's take 
166 L<Catalyst::Model::DBIC::Schema> as an example. You can create a 
167 schema outside of Catalyst that knows nothing about the web. This kind
168 of design ensures encapsulation and makes development and maintenance
169 a whole lot easier. The you use the aforementioned model to tie your
170 schema to your application. This gives you a C<MyApp::DBIC> (the
171 name is of course just an example) model as well as 
172 C<MyApp::DBIC::$ResultSource> models to access your result sources
173 directly. 
174
175 By creating such a thin layer between the actual model and the Catalyst
176 application the schema itself is not at all tied to any application, and
177 the layer in-between can access the model's API using information from
178 the context object.
179
180 So the only question remaining is, how does a Catalyst component access
181 the context object at request time? The solution to this problem is
182 L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
183
184 =head1 CONFIGURATION
185
186 The application and/or its developer have to interact with the extension
187 by configuring them. There is of course again more than one way to do it.
188
189 =head2 Attributes
190
191 You can specify any valid Perl attribute on Catalyst actions you like. 
192 (See L<attributes/"Syntax of Attribute Lists"> for a description of what 
193 is valid.) They will be available on the C<Catalyst::Action> instance via
194 its C<attributes> accessor. To give an example, this action
195
196   sub foo : Local Bar('Baz') {
197       my ($self, $c) = @_;
198       my $attributes = $self->action_for('foo')->attributes;
199       $c->res->body( $attributes->{Bar}[0] );
200   }
201
202 will set the response body to C<Baz>. The values always come in an array
203 reference. As you can see, you can use attributes to configure your 
204 actions. You can specify or alter these attributes via 
205 L</"Component Configuration">, or even react on them as soon as Catalyst
206 encounters them by providing your own 
207 L<component base class|/"Component Base Classes">.
208
209 =head2 Creating custom accessors
210
211 L<Catalyst::Component> uses L<Class::Accessor::Fast> for accessor 
212 creation. Please refer to the modules documentation for usage 
213 information.
214
215 =head2 Component configuration
216
217 On creation time, the class configuration of your component (the one
218 available via C<$self-E<gt>config>) will be merged with possible 
219 configuration settings from the applications configuration (either
220 directly or via config file) and stored in the controller object's
221 hash reference. So, if you read possible configurations like
222
223   my $model_name = $controller->{model_name};
224
225 you will get the right value. The C<config> accessor always only 
226 contains the original class configuration and must not be used for
227 component configuration.
228
229 You are advised to create accessors on your component class for your
230 configuration values. This is good practice and makes it easier to
231 capture configuration key typos. You can do this with the 
232 C<mk_ro_accessors> method provided to L<Catalyst::Component> via
233 L<Class::Accessor::Fast>:
234
235   use base 'Catalyst::Controller';
236   __PACKAGE__->mk_ro_accessors('model_name');
237   ...
238   my $model_name = $controller->model_name;
239
240 =head1 IMPLEMENTATION
241
242 This part contains the technical details of various implementation 
243 methods. Please read the L</"BEST PRACTICES"> before you start your
244 implementation, if you haven't already.
245
246 =head2 Action classes
247
248 Usually, your action objects are of the class L<Catalyst::Action>.
249 You can override this with the C<ActionClass> attribute to influence
250 execution and/or dispatching of the action. A popular example is 
251 L<Catalyst::Action::RenderView>, which is used in every newly created
252 Catalyst application in your root controller:
253
254   sub end : ActionClass('RenderView') { }
255
256 Usually, you want to override either the C<execute> or the C<match>
257 method, or both. The execute method of the action will naturally
258 call the methods code. You can surround this by overriding the method
259 in a subclass: 
260
261   package Catalyst::Action::MyFoo;
262   use strict;
263
264   use Class::C3;
265   use base 'Catalyst::Action';
266
267   sub execute {
268       my $self = shift;
269       my ($controller, $c, @args) = @_;
270
271       # put your 'before' code here
272       my $r = $self->next::method(@_);
273       # put your 'after' code here
274
275       return $r;
276   }
277
278   1;
279
280 We use L<Class::C3> to re-dispatch to the original C<execute> method in
281 the L<Catalyst::Action> class.
282
283 When a request comes in, Catalyst's dispatcher searches, depending on
284 the dispatch type, the target action or chain to invoke. From time to
285 time it asks the actions themselves, or through the controller, if they
286 would match the current request. That's what the C<match> method does.
287 So with overriding this, you can change on what the action will match
288 and add new matching criteria.
289
290 To give a totally bogus example, this action class will make the action 
291 only match on Mondays:
292
293   package Catalyst::Action::OnlyMondays;
294   use strict;
295
296   use Class::C3;
297   use base 'Catalyst::Action';
298
299   sub match {
300       my $self = shift;
301       return 0 if ( localtime(time) )[6] == 1;
302       return $self->next::method(@_);
303   }
304
305   1;
306
307 And this is how we'd use it:
308
309   sub foo: Local ActionClass('OnlyMondays') {
310       my ($self, $c) = @_;
311       $c->res->body('I feel motivated!');
312   }
313
314 If you are using action classes often or have some specific base classes
315 that you want to specify more conveniently, you can implement a component
316 base class providing an attribute handler.
317
318 For further information on action classes, please refer to 
319 L<Catalyst::Action> and L<Catalyst::Manual::Actions>.
320
321 =head2 Component base classes
322
323 Many plugins that were written should really have been just controller 
324 base classes. With such a class, you could provide functionality scoped
325 to a single controller, not polluting the global namespace in the context
326 object.
327
328 You can provide regular Perl methods in a base class as well as actions
329 which will be inherited to the subclass. Please refer to L</Controllers>
330 for an example of this.
331
332 You can introduce your own attributes by specifying a handler method in 
333 the controller base. For example, to use a C<FullClass> attribute to 
334 specify a fully qualified action class name, you could use the following
335 implementation. Note, however, that this functionality is already 
336 provided via the C<+> prefix for action classes. A simple
337
338   sub foo : Local ActionClass('+MyApp::Action::Bar') { ... }
339
340 will use C<MyApp::Action::Bar> as action class.
341
342   package MyApp::Base::Controller::FullClass;
343   use strict;
344   use base 'Catalyst::Controller';
345
346   sub _parse_FullClass_attr {
347       my ($self, $app_class, $action_name, $value, $attrs) = @_;
348       return( ActionClass => $value );
349   }
350
351   1;
352
353 Note that the full line of arguments is only provided for completeness 
354 sake. We could use this attribute in a subclass like any other Catalyst
355 attribute:
356
357   package MyApp::Controller::Foo;
358   use strict;
359   use base 'MyApp::Base::Controller::FullClass';
360
361   sub foo : Local FullClass('MyApp::Action::Bar') { ... }
362
363   1;
364
365 =head2 Controllers
366
367 Many things can happen in controllers, and it often improves 
368 maintainability to abstract some of the code out into reusable base 
369 classes.
370
371 You can provide usual Perl methods that will be available via your
372 controller object, or you can even define Catalyst actions which will be
373 inherited by the subclasses. Consider this controller base class:
374
375   package MyApp::Base::Controller::ModelBase;
376   use strict;
377   use base 'Catalyst::Controller';
378
379   sub list : Chained('base') PathPart('') Args(0) {
380       my ($self, $c) = @_;
381       my $model     = $c->model( $self->{model_name} );
382       my $condition = $self->{model_search_condition} || {};
383       my $attrs     = $self->{model_search_attrs}     || {};
384       $c->stash(rs => $model->search($condition, $attrs);
385   }
386
387   sub load : Chained('base') PathPart('') CaptureArgs(1) {
388       my ($self, $c, $id) = @_;
389       my $model = $c->model( $self->{model_name} );
390       $c->stash(row => $model->find($id));
391   }
392
393   1;
394
395 This example implements two simple actions. The C<list> action chains to
396 a (currently non-existent) C<base> action and puts a result-set into the
397 stash taking a configured C<model_name> as well as a search condition and
398 attributes. This action is a L<chained|Catalyst::DispatchType::Chained>
399 endpoint. The other action, called C<load> is a chain midpoint that takes
400 one argument. It takes the value as an ID and loads the row from the 
401 configured model. Please not that the above code is simplified for 
402 clarity. It misses error handling, input validation, and probably some 
403 other things too.
404
405 The class above is not very useful by its own, but we can combine it with
406 some custom actions by sub-classing it:
407
408   package MyApp::Controller::Foo;
409   use strict;
410   use base 'MyApp::Base::Controller::ModelBase';
411
412   __PACKAGE__->config(
413       model_name             => 'DB::Foo',
414       model_search_condition => { is_active => 1 },
415       model_search_attrs     => { order_by  => 'name' },
416   );
417
418   sub base : Chained PathPart('foo') CaptureArgs(0) { }
419
420   sub view : Chained('load') Args(0) {
421       my ($self, $c) = @_;
422       my $row = $c->stash->{row};
423       $c->res->body(join ': ', $row->name, $row->description);
424   }
425
426   1;
427
428 This class uses the formerly created controller as a base class. First,
429 we see the configurations that were used in the parent class. Next comes
430 the C<base> action, where everything chains off of.
431
432 Note that inherited actions act like they were declared in your 
433 controller itself. You can therefor call them just by their name in 
434 C<forward>s, C<detaches> and C<Chained(..)> specifications. This is an
435 important part of what makes this technique so useful.
436
437 The new C<view> action ties itself to the C<load> action specified in the
438 base class and outputs the loaded row's C<name> and C<description>
439 columns. The controller C<MyApp::Controller::Foo> now has these publicly
440 available paths:
441
442 =over
443
444 =item /foo
445
446 Will call the controller's C<base>, then the base classes C<list> action.
447
448 =item /foo/$id/view
449
450 First, the controller's C<base> will be called, then it will C<load> the 
451 row with the corresponding C<$id>. After that, C<view> will display some
452 fields out of the object.
453
454 =back
455
456 =head2 Models and Views
457
458 If the functionality you'd like to add is really a data-set you want to
459 manipulate, for example internal document types, images, files, it might
460 be better suited as a model.
461
462 Same goes for views. If your code handles representation or deals with
463 the applications interface and should be universally available, it could
464 be a perfect candidate for a view.
465
466 Please implement a C<process> method in your views. This method will be
467 called by Catalyst if it is asked to forward to a component without a
468 specified action. Note that C<process> is B<not a Catalyst action> but
469 a simple Perl method.
470
471 You are also encouraged to implement a C<render> method corresponding
472 with the one in L<Catalyst::View::TT>. This has proven invaluable,
473 because people can use your view for much more fine-grained content
474 generation.
475
476 Here is some example code for a fictional view:
477
478   package CatalystX::View::MyView;
479   use strict;
480   use base 'Catalyst::View';
481
482   sub process {
483       my ($self, $c) = @_;
484       
485       my $template = $c->stash->{template};
486       my $content  = $self->render($c, $template, $c->stash);
487       $c->res->body( $content );
488   }
489
490   sub render {
491       my ($self, $c, $template, $args) = @_;
492       
493       #
494       #  prepare content here
495       #
496       
497       return $content;
498   }
499
500   1;
501
502 =head2 Plugins
503
504 The first thing to say about plugins is that if you're not sure if your
505 module should be a plugin, it probably shouldn't. It once was common to
506 add features to Catalyst by writing plugins that provide accessors to 
507 said functionality. As Catalyst grew more popular, it became obvious that
508 this qualifies as bad practice. 
509
510 By designing your module as a Catalyst plugin, every method you implement,
511 import or inherit will be available via your applications context object.
512 Said more harshly, you're polluting global namespace, and you should be
513 only doing that when you really need.
514
515 Often, developers design extensions as plugins because they need to get
516 hold of the context object. Either to get at the stash or 
517 request/response objects are the widely spread reasons. It is, however,
518 perfectly possible to implement a regular Catalyst component (read: 
519 model, view or controller) that receives the current context object via
520 L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
521
522 So when is a plugin suited to your task? Your code needs to be a plugin 
523 to act upon or alter specific parts of Catalyst's request lifecycle. If
524 your functionality needs to wrap some C<prepare_*> or C<finalize_*>
525 stages, you won't get around a plugin.
526
527 Another valid target for a plugin architecture are things that B<really>
528 have to be globally available, like sessions or authentication.
529
530 B<Please do not> release Catalyst extensions as plugins only to provide
531 some functionality application wide. Design it as a controller base class
532 or another suiting technique with a smaller scope, so that your code only
533 influences those parts of the application where it is needed, and 
534 namespace clashes and conflicts are ruled out.
535
536 The implementation is pretty easy. Your plugin will be inserted in the
537 application's inheritance list, above Catalyst itself. You can by this
538 alter Catalyst's request lifecycle behaviour. Every method you declare,
539 every import in your package will be available as method on the 
540 application and the context object. As an example, let's say you want
541 Catalyst to warn you every time uri_for returned an undefined value, for
542 example because you specified the wrong number of captures for the
543 targeted action chain. You could do this with this simple 
544 implementation (excuse the lame class name, it's just an example):
545
546   package Catalyst::Plugin::UriforUndefWarning;
547   use strict;
548   use Class::C3;
549
550   sub uri_for {
551       my $c   = shift;
552       my $uri = $c->next::method(@_);
553       $c->log->warn(
554           'uri_for returned undef for:', 
555           join(', ', @_),
556       );
557       return $uri;
558   }
559
560   1;
561
562 This would override Catalyst's C<uri_for> method and emit a C<warn> log
563 entry containing the arguments that led to the undefined return value.
564
565 =head2 Factory components with COMPONENT()
566
567 Every component inheriting from L<Catalyst::Component> contains a 
568 C<COMPONENT> method. It is used on application startup by 
569 C<setup_components> to instantiate the component object for the Catalyst
570 application. By default, this will merge the components own 
571 C<config>uration with the application wide overrides and call the class'
572 C<new> method to return the component object.
573
574 You can override this method and do and return whatever you want. 
575 However, you should use L<Class::C3> to forward to the original 
576 C<COMPONENT> method to merge the configuration of your component.
577
578 Here is a stub C<COMPONENT> method:
579
580   package CatalystX::Component::Foo;
581   use strict;
582   use base 'Catalyst::Component';
583
584   use Class::C3;
585
586   sub COMPONENT {
587       my $class = shift;
588       my ($app_class, $config) = @_;
589
590       # do things here before instantiation
591       my $obj = $self->next::method(@_);
592       # do things to object after instantiation
593       
594       return $object;
595   }
596
597 The arguments are the class name of the component, the class name of
598 the application instantiating the component, and a hash reference
599 with the controller's configuration.
600
601 You are free to re-bless the object, instantiate a whole other component
602 or really do anything compatible with Catalyst's expectations on a 
603 component.
604
605 For more information, please see 
606 L<Catalyst::Component/"COMPONENT($c, $arguments)">.
607
608 =head1 SEE ALSO
609
610 L<Catalyst>,
611 L<Catalyst::Manual::Actions>,
612 L<Catalyst::Component>
613
614 =head1 AUTHOR
615
616 Robert Sedlacek C<rs@474.at>
617
618 =head1 LICENSE AND COPYRIGHT
619
620 This document is free, you can redistribute it and/or modify it under 
621 the same terms as Perl itself.
622
623 =cut
624