Replaced WritingPlugins with ExtendingCatalyst (phaylon)
Robert 'phaylon' Sedlacek [Tue, 13 Mar 2007 12:18:18 +0000 (12:18 +0000)]
lib/Catalyst/Manual/ExtendingCatalyst.pod [new file with mode: 0644]
lib/Catalyst/Manual/WritingPlugins.pod [deleted file]

diff --git a/lib/Catalyst/Manual/ExtendingCatalyst.pod b/lib/Catalyst/Manual/ExtendingCatalyst.pod
new file mode 100644 (file)
index 0000000..d15c8c3
--- /dev/null
@@ -0,0 +1,624 @@
+=head1 NAME
+
+Catalyst::Manual::ExtendingCatalyst - Extending The Framework
+
+=head1 DESCRIPTION
+
+This document will provide you with access points, techniques and best
+practices to extend the framework itself or to find more elegant ways
+to abstract and use your own code.
+
+The L<Catalyst> core developer community tries to build and evolve the 
+framework in a design that won't get in your way. There are many entry
+points to alter or extend the behaviour of the framework and the 
+applications built upon it, and it can be confusing at first to decide
+on a place to start. This document is written to help you orient 
+yourself in the possibilities, current practices and their consequences.
+
+Please read the L<BEST PRACTICES> section before deciding on a design,
+especially if you plan to release your code to the CPAN. The Catalyst
+developer and user communities, which you naturally also belong to, will
+benefit most if we all work together and coordinate. 
+
+If you are unsure on an implementation or have an idea you would like to
+have RfC'ed, it surely is a good idea to send your questions and 
+suggestions to the Catalyst mailing list (See L<Catalyst/SUPPORT>) or
+come to the C<#catalyst> channel on the C<irc.perl.org> network. You 
+might also want to refer to those places for research if a module doing 
+what you're trying to implement already exists. This might give you 
+either a solution to your problem or a already built base, which gives 
+you at least a head start.
+
+=head1 BEST PRACTICES
+
+During Catalyst's early days, it was common to write plugins to provide
+functionality application wide. Since then, Catalyst grew a lot more 
+flexible and powerful. It soon became a best practice to use some other
+form of abstraction or interface, to keep the scope of its influence as
+close as possible to where it belongs.
+
+For those in a hurry, here's a quick checklist of some fundamental 
+points. If you are going to read the whole thing anyway, you can jump 
+forward to L</Namespaces>.
+
+=head2 Quick Checklist
+
+=over
+
+=item Use the C<CatalystX::*> namespace if you can!
+
+Excluding plugins and of course your C<MyApp> code. B<Mind the X!>
+
+=item Don't make it a plugin unless you have to!
+
+A plugin should be careful as it declares in global namespace.
+
+=item There's a community. Use it!
+
+There are many experienced developers in the Catalyst community, there's
+always the IRC channel and the mailing list to discuss things.
+
+=item Add tests and documentation!
+
+This gives a stable base for contribution, and even more important, 
+trust. The easiest way is a test application. See
+L<Catalyst::Manual::Tutorial::Testing> for more information.
+
+=back
+
+=head2 Namespaces
+
+While some core extensions (engines, plugins, etc.) have to be placed in
+the C<Catalyst::*> namespace, the Catalyst core would like to ask 
+developers to use the C<CatalystX::*> namespace if possible.
+
+When you try to put a base class for a C<Model>, C<View> or C<Controller>
+directly under your C<MyApp> directory as, for example, 
+C<MyApp::Controller::Foo>, you will have the problem that Catalyst will 
+try to load that base class as a component of your application. The 
+solution is simple: Use another namespace. Common ones are 
+C<MyApp::Base::Controller::*> or C<MyApp::ControllerBase::*> as examples.
+
+=head2 Can it be a simple module?
+
+Sometimes you want to use functionality in your application that doesn't
+require the framework at all. Remember that Catalyst is just Perl and you
+always can just C<use> a module. If you have application specific code 
+that doesn't need the framework, there is no problem in putting it in 
+your C<MyApp::*> namespace. Just don't put it in C<Model>, C<Controller> 
+or C<View>, because that would make Catalyst try to load them as 
+components.
+
+=head2 Inheritance and overriding methods
+
+While Catalyst itself is still based on L<NEXT>, extension developers
+are encouraged to use L<Class::C3>, which is what Catalyst will be 
+switching to in some point in the future.
+
+When overriding a method, keep in mind that some day additionally
+arguments may be provided to the method, if the last parameter is not
+a flat list. It is thus better to override a method by shifting the
+invocant off of C<@_> and assign the rest of the used arguments, so
+you can pass your complete arguments to the original method via C<@_>:
+
+  use Class::C3;
+  ...
+
+  sub foo {
+      my $self = shift;
+      my ($bar, $baz) = @_;
+      # ...
+      return $self->next::method(@_);
+  }
+
+If you would do the common
+
+  my ($self, $foo, $bar) = @_;
+
+you'd have to use a much uglier construct to ensure that all arguments
+will be passed along and the method is future proof:
+
+  $self->next::method(@_[ 1 .. $#_ ]);
+
+=head2 Tests and documentation
+
+When you release your module to the CPAN, proper documentation and at 
+least a basic test suite (which means more than pod or even just 
+C<use_ok>, sorry) gives people a good base to contribute to the module. 
+It also shows that you care for your users. If you would like your 
+module to become a recommended addition, these things will prove 
+invaluable.
+
+=head2 Maintenance
+
+In planning to release a module to a broad community like those of 
+Catalyst or CPAN and Perl themselves, you should include beforehand if 
+you can spare the resources to keep it up to date, fix bugs and include 
+contributions.
+
+If you're not sure about this, you can always ask in the proper Catalyst
+or Perl channels if someone else might be interested in the project, and
+would jump in as co-maintainer.
+
+A public repository can further ease interaction with the community. Even
+read only access enables people to provide you with patches to your 
+current development version. subversion, SVN and SVK, are broadly 
+preferred in the Catalyst community.
+
+If you're developing a Catalyst extension, please consider asking the 
+core team for space in Catalyst's own subversion repository. You can get
+in touch about this via IRC or the Catalyst developers mailing list.
+
+=head2 The context object
+
+Sometimes you want to get a hold of the context object in a component
+that was created on startup time, where no context existed yet. Often 
+this is about the model reading something out of the stash or other
+context information (current language, for example). 
+
+First it should be said that, if you use the context object in your
+component and therefor tie it to an existing request, you might get into
+problems when you try to use the component (e.g. the model, which would 
+be the most common case) outside of Catalyst, for example in cronjobs.
+
+A stable solution to this problem is to design the Catalyst model 
+separately from the underlying model logic. Let's take 
+L<Catalyst::Model::DBIC::Schema> as an example. You can create a 
+schema outside of Catalyst that knows nothing about the web. This kind
+of design ensures encapsulation and makes development and maintenance
+a whole lot easier. The you use the aforementioned model to tie your
+schema to your application. This gives you a C<MyApp::DBIC> (the
+name is of course just an example) model as well as 
+C<MyApp::DBIC::$ResultSource> models to access your result sources
+directly. 
+
+By creating such a thin layer between the actual model and the Catalyst
+application the schema itself is not at all tied to any application, and
+the layer in-between can access the model's API using information from
+the context object.
+
+So the only question remaining is, how does a Catalyst component access
+the context object at request time? The solution to this problem is
+L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
+
+=head1 CONFIGURATION
+
+The application and/or its developer have to interact with the extension
+by configuring them. There is of course again more than one way to do it.
+
+=head2 Attributes
+
+You can specify any valid Perl attribute on Catalyst actions you like. 
+(See L<attributes/"Syntax of Attribute Lists"> for a description of what 
+is valid.) They will be available on the C<Catalyst::Action> instance via
+its C<attributes> accessor. To give an example, this action
+
+  sub foo : Local Bar('Baz') {
+      my ($self, $c) = @_;
+      my $attributes = $self->action_for('foo')->attributes;
+      $c->res->body( $attributes->{Bar}[0] );
+  }
+
+will set the response body to C<Baz>. The values always come in an array
+reference. As you can see, you can use attributes to configure your 
+actions. You can specify or alter these attributes via 
+L</"Component Configuration">, or even react on them as soon as Catalyst
+encounters them by providing your own 
+L<component base class|/"Component Base Classes">.
+
+=head2 Creating custom accessors
+
+L<Catalyst::Component> uses L<Class::Accessor::Fast> for accessor 
+creation. Please refer to the modules documentation for usage 
+information.
+
+=head2 Component configuration
+
+On creation time, the class configuration of your component (the one
+available via C<$self-E<gt>config>) will be merged with possible 
+configuration settings from the applications configuration (either
+directly or via config file) and stored in the controller object's
+hash reference. So, if you read possible configurations like
+
+  my $model_name = $controller->{model_name};
+
+you will get the right value. The C<config> accessor always only 
+contains the original class configuration and must not be used for
+component configuration.
+
+You are advised to create accessors on your component class for your
+configuration values. This is good practice and makes it easier to
+capture configuration key typos. You can do this with the 
+C<mk_ro_accessors> method provided to L<Catalyst::Component> via
+L<Class::Accessor::Fast>:
+
+  use base 'Catalyst::Controller';
+  __PACKAGE__->mk_ro_accessors('model_name');
+  ...
+  my $model_name = $controller->model_name;
+
+=head1 IMPLEMENTATION
+
+This part contains the technical details of various implementation 
+methods. Please read the L</"BEST PRACTICES"> before you start your
+implementation, if you haven't already.
+
+=head2 Action classes
+
+Usually, your action objects are of the class L<Catalyst::Action>.
+You can override this with the C<ActionClass> attribute to influence
+execution and/or dispatching of the action. A popular example is 
+L<Catalyst::Action::RenderView>, which is used in every newly created
+Catalyst application in your root controller:
+
+  sub end : ActionClass('RenderView') { }
+
+Usually, you want to override either the C<execute> or the C<match>
+method, or both. The execute method of the action will naturally
+call the methods code. You can surround this by overriding the method
+in a subclass: 
+
+  package Catalyst::Action::MyFoo;
+  use strict;
+
+  use Class::C3;
+  use base 'Catalyst::Action';
+
+  sub execute {
+      my $self = shift;
+      my ($controller, $c, @args) = @_;
+
+      # put your 'before' code here
+      my $r = $self->next::method(@_);
+      # put your 'after' code here
+
+      return $r;
+  }
+
+  1;
+
+We use L<Class::C3> to re-dispatch to the original C<execute> method in
+the L<Catalyst::Action> class.
+
+When a request comes in, Catalyst's dispatcher searches, depending on
+the dispatch type, the target action or chain to invoke. From time to
+time it asks the actions themselves, or through the controller, if they
+would match the current request. That's what the C<match> method does.
+So with overriding this, you can change on what the action will match
+and add new matching criteria.
+
+To give a totally bogus example, this action class will make the action 
+only match on Mondays:
+
+  package Catalyst::Action::OnlyMondays;
+  use strict;
+
+  use Class::C3;
+  use base 'Catalyst::Action';
+
+  sub match {
+      my $self = shift;
+      return 0 if ( localtime(time) )[6] == 1;
+      return $self->next::method(@_);
+  }
+
+  1;
+
+And this is how we'd use it:
+
+  sub foo: Local ActionClass('OnlyMondays') {
+      my ($self, $c) = @_;
+      $c->res->body('I feel motivated!');
+  }
+
+If you are using action classes often or have some specific base classes
+that you want to specify more conveniently, you can implement a component
+base class providing an attribute handler.
+
+For further information on action classes, please refer to 
+L<Catalyst::Action> and L<Catalyst::Manual::Actions>.
+
+=head2 Component base classes
+
+Many plugins that were written should really have been just controller 
+base classes. With such a class, you could provide functionality scoped
+to a single controller, not polluting the global namespace in the context
+object.
+
+You can provide regular Perl methods in a base class as well as actions
+which will be inherited to the subclass. Please refer to L</Controllers>
+for an example of this.
+
+You can introduce your own attributes by specifying a handler method in 
+the controller base. For example, to use a C<FullClass> attribute to 
+specify a fully qualified action class name, you could use the following
+implementation. Note, however, that this functionality is already 
+provided via the C<+> prefix for action classes. A simple
+
+  sub foo : Local ActionClass('+MyApp::Action::Bar') { ... }
+
+will use C<MyApp::Action::Bar> as action class.
+
+  package MyApp::Base::Controller::FullClass;
+  use strict;
+  use base 'Catalyst::Controller';
+
+  sub _parse_FullClass_attr {
+      my ($self, $app_class, $action_name, $value, $attrs) = @_;
+      return( ActionClass => $value );
+  }
+
+  1;
+
+Note that the full line of arguments is only provided for completeness 
+sake. We could use this attribute in a subclass like any other Catalyst
+attribute:
+
+  package MyApp::Controller::Foo;
+  use strict;
+  use base 'MyApp::Base::Controller::FullClass';
+
+  sub foo : Local FullClass('MyApp::Action::Bar') { ... }
+
+  1;
+
+=head2 Controllers
+
+Many things can happen in controllers, and it often improves 
+maintainability to abstract some of the code out into reusable base 
+classes.
+
+You can provide usual Perl methods that will be available via your
+controller object, or you can even define Catalyst actions which will be
+inherited by the subclasses. Consider this controller base class:
+
+  package MyApp::Base::Controller::ModelBase;
+  use strict;
+  use base 'Catalyst::Controller';
+
+  sub list : Chained('base') PathPart('') Args(0) {
+      my ($self, $c) = @_;
+      my $model     = $c->model( $self->{model_name} );
+      my $condition = $self->{model_search_condition} || {};
+      my $attrs     = $self->{model_search_attrs}     || {};
+      $c->stash(rs => $model->search($condition, $attrs);
+  }
+
+  sub load : Chained('base') PathPart('') CaptureArgs(1) {
+      my ($self, $c, $id) = @_;
+      my $model = $c->model( $self->{model_name} );
+      $c->stash(row => $model->find($id));
+  }
+
+  1;
+
+This example implements two simple actions. The C<list> action chains to
+a (currently non-existent) C<base> action and puts a result-set into the
+stash taking a configured C<model_name> as well as a search condition and
+attributes. This action is a L<chained|Catalyst::DispatchType::Chained>
+endpoint. The other action, called C<load> is a chain midpoint that takes
+one argument. It takes the value as an ID and loads the row from the 
+configured model. Please not that the above code is simplified for 
+clarity. It misses error handling, input validation, and probably some 
+other things too.
+
+The class above is not very useful by its own, but we can combine it with
+some custom actions by sub-classing it:
+
+  package MyApp::Controller::Foo;
+  use strict;
+  use base 'MyApp::Base::Controller::ModelBase';
+
+  __PACKAGE__->config(
+      model_name             => 'DB::Foo',
+      model_search_condition => { is_active => 1 },
+      model_search_attrs     => { order_by  => 'name' },
+  );
+
+  sub base : Chained PathPart('foo') CaptureArgs(0) { }
+
+  sub view : Chained('load') Args(0) {
+      my ($self, $c) = @_;
+      my $row = $c->stash->{row};
+      $c->res->body(join ': ', $row->name, $row->description);
+  }
+
+  1;
+
+This class uses the formerly created controller as a base class. First,
+we see the configurations that were used in the parent class. Next comes
+the C<base> action, where everything chains off of.
+
+Note that inherited actions act like they were declared in your 
+controller itself. You can therefor call them just by their name in 
+C<forward>s, C<detaches> and C<Chained(..)> specifications. This is an
+important part of what makes this technique so useful.
+
+The new C<view> action ties itself to the C<load> action specified in the
+base class and outputs the loaded row's C<name> and C<description>
+columns. The controller C<MyApp::Controller::Foo> now has these publicly
+available paths:
+
+=over
+
+=item /foo
+
+Will call the controller's C<base>, then the base classes C<list> action.
+
+=item /foo/$id/view
+
+First, the controller's C<base> will be called, then it will C<load> the 
+row with the corresponding C<$id>. After that, C<view> will display some
+fields out of the object.
+
+=back
+
+=head2 Models and Views
+
+If the functionality you'd like to add is really a data-set you want to
+manipulate, for example internal document types, images, files, it might
+be better suited as a model.
+
+Same goes for views. If your code handles representation or deals with
+the applications interface and should be universally available, it could
+be a perfect candidate for a view.
+
+Please implement a C<process> method in your views. This method will be
+called by Catalyst if it is asked to forward to a component without a
+specified action. Note that C<process> is B<not a Catalyst action> but
+a simple Perl method.
+
+You are also encouraged to implement a C<render> method corresponding
+with the one in L<Catalyst::View::TT>. This has proven invaluable,
+because people can use your view for much more fine-grained content
+generation.
+
+Here is some example code for a fictional view:
+
+  package CatalystX::View::MyView;
+  use strict;
+  use base 'Catalyst::View';
+
+  sub process {
+      my ($self, $c) = @_;
+      
+      my $template = $c->stash->{template};
+      my $content  = $self->render($c, $template, $c->stash);
+      $c->res->body( $content );
+  }
+
+  sub render {
+      my ($self, $c, $template, $args) = @_;
+      
+      #
+      #  prepare content here
+      #
+      
+      return $content;
+  }
+
+  1;
+
+=head2 Plugins
+
+The first thing to say about plugins is that if you're not sure if your
+module should be a plugin, it probably shouldn't. It once was common to
+add features to Catalyst by writing plugins that provide accessors to 
+said functionality. As Catalyst grew more popular, it became obvious that
+this qualifies as bad practice. 
+
+By designing your module as a Catalyst plugin, every method you implement,
+import or inherit will be available via your applications context object.
+Said more harshly, you're polluting global namespace, and you should be
+only doing that when you really need.
+
+Often, developers design extensions as plugins because they need to get
+hold of the context object. Either to get at the stash or 
+request/response objects are the widely spread reasons. It is, however,
+perfectly possible to implement a regular Catalyst component (read: 
+model, view or controller) that receives the current context object via
+L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
+
+So when is a plugin suited to your task? Your code needs to be a plugin 
+to act upon or alter specific parts of Catalyst's request lifecycle. If
+your functionality needs to wrap some C<prepare_*> or C<finalize_*>
+stages, you won't get around a plugin.
+
+Another valid target for a plugin architecture are things that B<really>
+have to be globally available, like sessions or authentication.
+
+B<Please do not> release Catalyst extensions as plugins only to provide
+some functionality application wide. Design it as a controller base class
+or another suiting technique with a smaller scope, so that your code only
+influences those parts of the application where it is needed, and 
+namespace clashes and conflicts are ruled out.
+
+The implementation is pretty easy. Your plugin will be inserted in the
+application's inheritance list, above Catalyst itself. You can by this
+alter Catalyst's request lifecycle behaviour. Every method you declare,
+every import in your package will be available as method on the 
+application and the context object. As an example, let's say you want
+Catalyst to warn you every time uri_for returned an undefined value, for
+example because you specified the wrong number of captures for the
+targeted action chain. You could do this with this simple 
+implementation (excuse the lame class name, it's just an example):
+
+  package Catalyst::Plugin::UriforUndefWarning;
+  use strict;
+  use Class::C3;
+
+  sub uri_for {
+      my $c   = shift;
+      my $uri = $c->next::method(@_);
+      $c->log->warn(
+          'uri_for returned undef for:', 
+          join(', ', @_),
+      );
+      return $uri;
+  }
+
+  1;
+
+This would override Catalyst's C<uri_for> method and emit a C<warn> log
+entry containing the arguments that led to the undefined return value.
+
+=head2 Factory components with COMPONENT()
+
+Every component inheriting from L<Catalyst::Component> contains a 
+C<COMPONENT> method. It is used on application startup by 
+C<setup_components> to instantiate the component object for the Catalyst
+application. By default, this will merge the components own 
+C<config>uration with the application wide overrides and call the class'
+C<new> method to return the component object.
+
+You can override this method and do and return whatever you want. 
+However, you should use L<Class::C3> to forward to the original 
+C<COMPONENT> method to merge the configuration of your component.
+
+Here is a stub C<COMPONENT> method:
+
+  package CatalystX::Component::Foo;
+  use strict;
+  use base 'Catalyst::Component';
+
+  use Class::C3;
+
+  sub COMPONENT {
+      my $class = shift;
+      my ($app_class, $config) = @_;
+
+      # do things here before instantiation
+      my $obj = $self->next::method(@_);
+      # do things to object after instantiation
+      
+      return $object;
+  }
+
+The arguments are the class name of the component, the class name of
+the application instantiating the component, and a hash reference
+with the controller's configuration.
+
+You are free to re-bless the object, instantiate a whole other component
+or really do anything compatible with Catalyst's expectations on a 
+component.
+
+For more information, please see 
+L<Catalyst::Component/"COMPONENT($c, $arguments)">.
+
+=head1 SEE ALSO
+
+L<Catalyst>,
+L<Catalyst::Manual::Actions>,
+L<Catalyst::Component>
+
+=head1 AUTHOR
+
+Robert Sedlacek C<rs@474.at>
+
+=head1 LICENSE AND COPYRIGHT
+
+This document is free, you can redistribute it and/or modify it under 
+the same terms as Perl itself.
+
+=cut
+
diff --git a/lib/Catalyst/Manual/WritingPlugins.pod b/lib/Catalyst/Manual/WritingPlugins.pod
deleted file mode 100644 (file)
index 5af1713..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-=head1 NAME
-
-Catalyst::Manual::WritingPlugins - An introduction to writing plugins
-with L<NEXT>.
-
-=head1 DESCRIPTION
-
-Writing an integrated plugin for L<Catalyst> using L<NEXT>.
-
-=head1 WHY PLUGINS?
-
-A Catalyst plugin is an integrated part of your application. By writing
-plugins you can, for example, perform processing actions automatically,
-instead of having to C<forward> to a processing method every time you
-need it.
-
-=head1 WHAT'S NEXT?
-
-L<NEXT> is used to re-dispatch a method call as if the calling method
-doesn't exist at all. In other words: If the class you're inheriting
-from defines a method, and you're overloading that method in your own
-class, NEXT gives you the possibility to call that overloaded method.
-
-This technique is the usual way to plug a module into Catalyst.
-
-=head1 INTEGRATING YOUR PLUGIN
-
-You can use L<NEXT> for your plugin by overloading certain methods which
-are called by Catalyst during a request.
-
-=head2 The request life-cycle
-
-Catalyst creates a context object (C<$context> or, more usually, its
-alias C<$c>) on every request, which is passed to all the handlers that
-are called from preparation to finalization.
-
-For a complete list of the methods called during a request, see
-L<Catalyst::Manual::Internals>. The request can be split up in three
-main stages:
-
-=over 4
-
-=item preparation
-
-When the C<prepare> handler is called, it initializes the request
-object, connections, headers, and everything else that needs to be
-prepared. C<prepare> itself calls other methods to delegate these tasks.
-After this method has run, everything concerning the request is in
-place.
-
-=item dispatch
-
-The dispatching phase is where the black magic happens. The C<dispatch>
-handler decides which actions have to be called for this request.
-
-=item finalization
-
-Catalyst uses the C<finalize> method to prepare the response to give to
-the client. It makes decisions according to your C<response> (e.g. where
-you want to redirect the user to). After this method, the response is
-ready and waiting for you to do something with it--usually, hand it off
-to your View class.
-
-=back
-
-=head2 What Plugins look like
-
-There's nothing special about a plugin except its name. A module named
-C<Catalyst::Plugin::MyPlugin> will be loaded by Catalyst if you specify it
-in your application class, e.g.:
-
-    # your plugin
-    package Catalyst::Plugin::MyPlugin;
-    use warnings;
-    use strict;
-    ...
-
-    # MyApp.pm, your application class
-    use Catalyst qw/-Debug MyPlugin/;
-
-This does nothing but load your module. We'll now see how to overload stages of the request cycle, and provide accessors.
-
-=head2 Calling methods from your Plugin
-
-Methods that do not overload a handler are available directly in the
-C<$c> context object; they don't need to be qualified with namespaces,
-and you don't need to C<use> them.
-
-    package Catalyst::Plugin::Foobar;
-    use strict;
-    sub foo { return 'bar'; }
-
-    # anywhere else in your Catalyst application:
-
-    $c->foo(); # will return 'bar'
-
-That's it.
-
-=head2 Overloading - Plugging into Catalyst
-
-If you don't just want to provide methods, but want to actually plug
-your module into the request cycle, you have to overload the handler
-that suits your needs.
-
-Every handler gets the context object passed as its first argument. Pass
-the rest of the arguments to the next handler in row by calling it via
-
-    $c->NEXT::handler-name( @_ );
-
-if you already C<shift>ed it out of C<@_>. Remember to C<use> C<NEXT>.
-
-=head2 Storage and Configuration
-
-Some Plugins use their accessor names as a storage point, e.g.
-
-  sub my_accessor {
-    my $c = shift;
-    $c->{my_accessor} = ..
-
-but it is more safe and clear to put your data in your configuration
-hash:
-
-    $c->config->{my_plugin}{ name } = $value;
-
-If you need to maintain data for more than one request, you should
-store it in a session.
-
-=head1 EXAMPLE
-
-Here's a simple example Plugin that shows how to overload C<prepare> 
-to add a unique ID to every request:
-
-    package Catalyst::Plugin::RequestUUID;
-
-    use warnings;
-    use strict;
-
-    use Catalyst::Request;
-    use Data::UUID;
-    use NEXT;    
-
-    our $VERSION = 0.01;
-
-    {   # create a uuid accessor
-        package Catalyst::Request;
-        __PACKAGE__->mk_accessors('uuid');
-    }
-
-    sub prepare {
-      my $class = shift;
-
-      # Turns the engine-specific request into a Catalyst context .
-      my $c = $class->NEXT::prepare( @_ );
-
-      $c->request->uuid( Data::UUID->new->create_str );
-      $c->log->debug( 'Request UUID "'. $c->request->uuid .'"' );
-
-      return $c;
-    }
-
-    1;
-
-Let's just break it down into pieces:
-
-    package Catalyst::Plugin::RequestUUID;
-
-The package name has to start with C<Catalyst::Plugin::> to make sure you
-can load your plugin by simply specifying
-
-    use Catalyst qw/RequestUUID/;
-
-in the application class. L<warnings> and L<strict> are recommended for
-all Perl applications.
-
-    use NEXT;
-    use Data::UUID;
-    our $VERSION = 0.01;
-
-NEXT must be explicitly C<use>d. L<Data::UUID> generates our unique
-ID. The C<$VERSION> gets set because it's a) a good habit and b)
-L<ExtUtils::ModuleMaker> likes it.
-
-    sub prepare {
-
-These methods are called without attributes (Private, Local, etc.).
-
-    my $c = shift;
-
-We get the context object for this request as the first argument. 
-
-B<Hint!>:Be sure you shift the context object out of C<@_> in this. If
-you just do a
-
-  my ( $c ) = @_;
-
-it remains there, and you may run into problems if you're not aware of
-what you pass to the handler you've overloaded. If you take a look at
-
-    $c = $c->NEXT::prepare( @_ );
-
-you see you would pass the context twice here if you don't shift it out
-of your parameter list.
-
-This line is the main part of the plugin procedure. We call the
-overloaded C<prepare> method and pass along the parameters we got. We
-also overwrite the context object C<$c> with the one returned by the
-called method returns. We'll return our modified context object at the
-end.
-
-Note that that if we modify C<$c> before this line, we also modify it
-before the original (overloaded) C<prepare> is run. If we modify it
-after, we modify an already prepared context. And, of course, it's no
-problem to do both, if you need to. Another example of working on the
-context before calling the actual handler would be setting header
-information before C<finalize> does its job.
-
-    $c->req->{req_uuid} = Data::UUID->new->create_str;
-
-This line creates a new L<Data::UUID> object and calls the C<create_str>
-method. The value is saved in our request, under the key C<req_uuid>. We
-can use that to access it in future in our application.
-
-    $c->log->debug( 'Request UUID "'. $c->req->{req_uuid} .'"' );
-
-This sends our UUID to the C<debug> log.
-
-The final line
-
-    return $c;
-
-passes our modified context object back to whoever has called us. This
-could be Catalyst itself, or the overloaded handler of another plugin.
-
-=head1 SEE ALSO
-
-L<Catalyst>, L<NEXT>, L<ExtUtils::ModuleMaker>, L<Catalyst::Manual::Plugins>,
-L<Catalyst::Manual::Internals>.
-
-=head1 THANKS TO
-
-Sebastian Riedel and his team of Catalyst developers as well as all the
-helpful people in #catalyst.
-
-=head1 COPYRIGHT
-
-This program is free software, you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-=head1 AUTHOR
-
-S<Robert Sedlacek, C<phaylon@dunkelheit.at>> with a lot of help from the
-people on #catalyst.
-
-=cut