From: John Napiorkowski Date: Tue, 28 Apr 2015 18:21:29 +0000 (-0500) Subject: docs updates X-Git-Tag: 5.90089_004~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=9e7f288e0bd785c69c8e54c77d951b2e878f5b8f docs updates --- diff --git a/Changes b/Changes index 63a406c..11227b8 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ # This file documents the revision history for Perl extension Catalyst. 5.90089_004 - TDB + - Added swanky github badges. + - Reverted a change to how the stats engine is setup that was incorrect. - New application setup hook 'config_for' which allows one to get the canonical application configuration for a controller, view or model, or a plugin. Can also be used to override and adapt what configuration is diff --git a/README.mkdn b/README.mkdn new file mode 100644 index 0000000..f30025c --- /dev/null +++ b/README.mkdn @@ -0,0 +1,2161 @@ +# NAME + +Catalyst - The Elegant MVC Web Application Framework + +
+ + CPAN version + Catalyst></a>
+    <a href=Kwalitee Score +
+ +# SYNOPSIS + +See the [Catalyst::Manual](https://metacpan.org/pod/Catalyst::Manual) distribution for comprehensive +documentation and tutorials. + + # Install Catalyst::Devel for helpers and other development tools + # use the helper to create a new application + catalyst.pl MyApp + + # add models, views, controllers + script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db + script/myapp_create.pl view MyTemplate TT + script/myapp_create.pl controller Search + + # built in testserver -- use -r to restart automatically on changes + # --help to see all available options + script/myapp_server.pl + + # command line testing interface + script/myapp_test.pl /yada + + ### in lib/MyApp.pm + use Catalyst qw/-Debug/; # include plugins here as well + + ### In lib/MyApp/Controller/Root.pm (autocreated) + sub foo : Chained('/') Args() { # called for /foo, /foo/1, /foo/1/2, etc. + my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2 + $c->stash->{template} = 'foo.tt'; # set the template + # lookup something from db -- stash vars are passed to TT + $c->stash->{data} = + $c->model('Database::Foo')->search( { country => $args[0] } ); + if ( $c->req->params->{bar} ) { # access GET or POST parameters + $c->forward( 'bar' ); # process another action + # do something else after forward returns + } + } + + # The foo.tt TT template can use the stash data from the database + [% WHILE (item = data.next) %] + [% item.foo %] + [% END %] + + # called for /bar/of/soap, /bar/of/soap/10, etc. + sub bar : Chained('/') PathPart('/bar/of/soap') Args() { ... } + + # called after all actions are finished + sub end : Action { + my ( $self, $c ) = @_; + if ( scalar @{ $c->error } ) { ... } # handle errors + return if $c->res->body; # already have a response + $c->forward( 'MyApp::View::TT' ); # render template + } + +See [Catalyst::Manual::Intro](https://metacpan.org/pod/Catalyst::Manual::Intro) for additional information. + +# DESCRIPTION + +Catalyst is a modern framework for making web applications without the +pain usually associated with this process. This document is a reference +to the main Catalyst application. If you are a new user, we suggest you +start with [Catalyst::Manual::Tutorial](https://metacpan.org/pod/Catalyst::Manual::Tutorial) or [Catalyst::Manual::Intro](https://metacpan.org/pod/Catalyst::Manual::Intro). + +See [Catalyst::Manual](https://metacpan.org/pod/Catalyst::Manual) for more documentation. + +Catalyst plugins can be loaded by naming them as arguments to the "use +Catalyst" statement. Omit the `Catalyst::Plugin::` prefix from the +plugin name, i.e., `Catalyst::Plugin::My::Module` becomes +`My::Module`. + + use Catalyst qw/My::Module/; + +If your plugin starts with a name other than `Catalyst::Plugin::`, you can +fully qualify the name by using a unary plus: + + use Catalyst qw/ + My::Module + +Fully::Qualified::Plugin::Name + /; + +Special flags like `-Debug` can also be specified as +arguments when Catalyst is loaded: + + use Catalyst qw/-Debug My::Module/; + +The position of plugins and flags in the chain is important, because +they are loaded in the order in which they appear. + +The following flags are supported: + +## -Debug + +Enables debug output. You can also force this setting from the system +environment with CATALYST\_DEBUG or \_DEBUG. The environment +settings override the application, with \_DEBUG having the highest +priority. + +This sets the log level to 'debug' and enables full debug output on the +error screen. If you only want the latter, see [$c->debug](https://metacpan.org/pod/$c->debug). + +## -Home + +Forces Catalyst to use a specific home directory, e.g.: + + use Catalyst qw[-Home=/usr/mst]; + +This can also be done in the shell environment by setting either the +`CATALYST_HOME` environment variable or `MYAPP_HOME`; where `MYAPP` +is replaced with the uppercased name of your application, any "::" in +the name will be replaced with underscores, e.g. MyApp::Web should use +MYAPP\_WEB\_HOME. If both variables are set, the MYAPP\_HOME one will be used. + +If none of these are set, Catalyst will attempt to automatically detect the +home directory. If you are working in a development environment, Catalyst +will try and find the directory containing either Makefile.PL, Build.PL, +dist.ini, or cpanfile. If the application has been installed into the system +(i.e. you have done `make install`), then Catalyst will use the path to your +application module, without the .pm extension (e.g., /foo/MyApp if your +application was installed at /foo/MyApp.pm) + +## -Log + + use Catalyst '-Log=warn,fatal,error'; + +Specifies a comma-delimited list of log levels. + +## -Stats + +Enables statistics collection and reporting. + + use Catalyst qw/-Stats=1/; + +You can also force this setting from the system environment with CATALYST\_STATS +or \_STATS. The environment settings override the application, with +\_STATS having the highest priority. + +Stats are also enabled if [debugging ](#debug) is enabled. + +# METHODS + +## INFORMATION ABOUT THE CURRENT REQUEST + +## $c->action + +Returns a [Catalyst::Action](https://metacpan.org/pod/Catalyst::Action) object for the current action, which +stringifies to the action name. See [Catalyst::Action](https://metacpan.org/pod/Catalyst::Action). + +## $c->namespace + +Returns the namespace of the current action, i.e., the URI prefix +corresponding to the controller of the current action. For example: + + # in Controller::Foo::Bar + $c->namespace; # returns 'foo/bar'; + +## $c->request + +## $c->req + +Returns the current [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request) object, giving access to +information about the current client request (including parameters, +cookies, HTTP headers, etc.). See [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request). + +## REQUEST FLOW HANDLING + +## $c->forward( $action \[, \\@arguments \] ) + +## $c->forward( $class, $method, \[, \\@arguments \] ) + +This is one way of calling another action (method) in the same or +a different controller. You can also use `$self->my_method($c, @args)` +in the same controller or `$c->controller('MyController')->my_method($c, @args)` +in a different controller. +The main difference is that 'forward' uses some of the Catalyst request +cycle overhead, including debugging, which may be useful to you. On the +other hand, there are some complications to using 'forward', restrictions +on values returned from 'forward', and it may not handle errors as you prefer. +Whether you use 'forward' or not is up to you; it is not considered superior to +the other ways to call a method. + +'forward' calls another action, by its private name. If you give a +class name but no method, `process()` is called. You may also optionally +pass arguments in an arrayref. The action will receive the arguments in +`@_` and `$c->req->args`. Upon returning from the function, +`$c->req->args` will be restored to the previous values. + +Any data `return`ed from the action forwarded to, will be returned by the +call to forward. + + my $foodata = $c->forward('/foo'); + $c->forward('index'); + $c->forward(qw/Model::DBIC::Foo do_stuff/); + $c->forward('View::TT'); + +Note that [forward](#c-forward-action-arguments) implies +an `eval { }` around the call (actually +[execute](#c-execute-class-coderef) does), thus rendering all +exceptions thrown by the called action non-fatal and pushing them onto +$c->error instead. If you want `die` to propagate you need to do something +like: + + $c->forward('foo'); + die join "\n", @{ $c->error } if @{ $c->error }; + +Or make sure to always return true values from your actions and write +your code like this: + + $c->forward('foo') || return; + +Another note is that `$c->forward` always returns a scalar because it +actually returns $c->state which operates in a scalar context. +Thus, something like: + + return @array; + +in an action that is forwarded to is going to return a scalar, +i.e. how many items are in that array, which is probably not what you want. +If you need to return an array then return a reference to it, +or stash it like so: + + $c->stash->{array} = \@array; + +and access it from the stash. + +Keep in mind that the `end` method used is that of the caller action. So a `$c->detach` inside a forwarded action would run the `end` method from the original action requested. + +## $c->detach( $action \[, \\@arguments \] ) + +## $c->detach( $class, $method, \[, \\@arguments \] ) + +## $c->detach() + +The same as [forward](#c-forward-action-arguments), but +doesn't return to the previous action when processing is finished. + +When called with no arguments it escapes the processing chain entirely. + +## $c->visit( $action \[, \\@arguments \] ) + +## $c->visit( $action \[, \\@captures, \\@arguments \] ) + +## $c->visit( $class, $method, \[, \\@arguments \] ) + +## $c->visit( $class, $method, \[, \\@captures, \\@arguments \] ) + +Almost the same as [forward](#c-forward-action-arguments), +but does a full dispatch, instead of just calling the new `$action` / +`$class->$method`. This means that `begin`, `auto` and the method +you go to are called, just like a new request. + +In addition both `$c->action` and `$c->namespace` are localized. +This means, for example, that `$c->action` methods such as +[name](https://metacpan.org/pod/Catalyst::Action#name), [class](https://metacpan.org/pod/Catalyst::Action#class) and +[reverse](https://metacpan.org/pod/Catalyst::Action#reverse) return information for the visited action +when they are invoked within the visited action. This is different from the +behavior of [forward](#c-forward-action-arguments), which +continues to use the $c->action object from the caller action even when +invoked from the called action. + +`$c->stash` is kept unchanged. + +In effect, [visit](#c-visit-action-captures-arguments) +allows you to "wrap" another action, just as it would have been called by +dispatching from a URL, while the analogous +[go](#c-go-action-captures-arguments) allows you to +transfer control to another action as if it had been reached directly from a URL. + +## $c->go( $action \[, \\@arguments \] ) + +## $c->go( $action \[, \\@captures, \\@arguments \] ) + +## $c->go( $class, $method, \[, \\@arguments \] ) + +## $c->go( $class, $method, \[, \\@captures, \\@arguments \] ) + +The relationship between `go` and +[visit](#c-visit-action-captures-arguments) is the same as +the relationship between +[forward](#c-forward-class-method-arguments) and +[detach](#c-detach-action-arguments). Like `$c->visit`, +`$c->go` will perform a full dispatch on the specified action or method, +with localized `$c->action` and `$c->namespace`. Like `detach`, +`go` escapes the processing of the current request chain on completion, and +does not return to its cunless blessed $cunless blessed $caller. + +@arguments are arguments to the final destination of $action. @captures are +arguments to the intermediate steps, if any, on the way to the final sub of +$action. + +## $c->response + +## $c->res + +Returns the current [Catalyst::Response](https://metacpan.org/pod/Catalyst::Response) object, see there for details. + +## $c->stash + +Returns a hashref to the stash, which may be used to store data and pass +it between components during a request. You can also set hash keys by +passing arguments. The stash is automatically sent to the view. The +stash is cleared at the end of a request; it cannot be used for +persistent storage (for this you must use a session; see +[Catalyst::Plugin::Session](https://metacpan.org/pod/Catalyst::Plugin::Session) for a complete system integrated with +Catalyst). + + $c->stash->{foo} = $bar; + $c->stash( { moose => 'majestic', qux => 0 } ); + $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref + + # stash is automatically passed to the view for use in a template + $c->forward( 'MyApp::View::TT' ); + +The stash hash is currently stored in the PSGI `$env` and is managed by +[Catalyst::Middleware::Stash](https://metacpan.org/pod/Catalyst::Middleware::Stash). Since it's part of the `$env` items in +the stash can be accessed in sub applications mounted under your main +[Catalyst](https://metacpan.org/pod/Catalyst) application. For example if you delegate the response of an +action to another [Catalyst](https://metacpan.org/pod/Catalyst) application, that sub application will have +access to all the stash keys of the main one, and if can of course add +more keys of its own. However those new keys will not 'bubble' back up +to the main application. + +For more information the best thing to do is to review the test case: +t/middleware-stash.t in the distribution /t directory. + +## $c->error + +## $c->error($error, ...) + +## $c->error($arrayref) + +Returns an arrayref containing error messages. If Catalyst encounters an +error while processing a request, it stores the error in $c->error. This +method should only be used to store fatal error messages. + + my @error = @{ $c->error }; + +Add a new error. + + $c->error('Something bad happened'); + +Calling this will always return an arrayref (if there are no errors it +will be an empty arrayref. + +## $c->state + +Contains the return value of the last executed action. +Note that << $c->state >> operates in a scalar context which means that all +values it returns are scalar. + +## $c->clear\_errors + +Clear errors. You probably don't want to clear the errors unless you are +implementing a custom error screen. + +This is equivalent to running + + $c->error(0); + +## $c->has\_errors + +Returns true if you have errors + +## $c->last\_error + +Returns the most recent error in the stack (the one most recently added...) +or nothing if there are no errors. + +## shift\_errors + +shifts the most recently added error off the error stack and returns if. Returns +nothing if there are no more errors. + +## COMPONENT ACCESSORS + +## $c->controller($name) + +Gets a [Catalyst::Controller](https://metacpan.org/pod/Catalyst::Controller) instance by name. + + $c->controller('Foo')->do_stuff; + +If the name is omitted, will return the controller for the dispatched +action. + +If you want to search for controllers, pass in a regexp as the argument. + + # find all controllers that start with Foo + my @foo_controllers = $c->controller(qr{^Foo}); + +## $c->model($name) + +Gets a [Catalyst::Model](https://metacpan.org/pod/Catalyst::Model) instance by name. + + $c->model('Foo')->do_stuff; + +Any extra arguments are directly passed to ACCEPT\_CONTEXT, if the model +defines ACCEPT\_CONTEXT. If it does not, the args are discarded. + +If the name is omitted, it will look for + - a model object in $c->stash->{current\_model\_instance}, then + - a model name in $c->stash->{current\_model}, then + - a config setting 'default\_model', or + - check if there is only one model, and return it if that's the case. + +If you want to search for models, pass in a regexp as the argument. + + # find all models that start with Foo + my @foo_models = $c->model(qr{^Foo}); + +## $c->view($name) + +Gets a [Catalyst::View](https://metacpan.org/pod/Catalyst::View) instance by name. + + $c->view('Foo')->do_stuff; + +Any extra arguments are directly passed to ACCEPT\_CONTEXT. + +If the name is omitted, it will look for + - a view object in $c->stash->{current\_view\_instance}, then + - a view name in $c->stash->{current\_view}, then + - a config setting 'default\_view', or + - check if there is only one view, and return it if that's the case. + +If you want to search for views, pass in a regexp as the argument. + + # find all views that start with Foo + my @foo_views = $c->view(qr{^Foo}); + +## $c->controllers + +Returns the available names which can be passed to $c->controller + +## $c->models + +Returns the available names which can be passed to $c->model + +## $c->views + +Returns the available names which can be passed to $c->view + +## $c->comp($name) + +## $c->component($name) + +Gets a component object by name. This method is not recommended, +unless you want to get a specific component by full +class. `$c->controller`, `$c->model`, and `$c->view` +should be used instead. + +If `$name` is a regexp, a list of components matched against the full +component name will be returned. + +If Catalyst can't find a component by name, it will fallback to regex +matching by default. To disable this behaviour set +disable\_component\_resolution\_regex\_fallback to a true value. + + __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 ); + +## CLASS DATA AND HELPER CLASSES + +## $c->config + +Returns or takes a hashref containing the application's configuration. + + __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } ); + +You can also use a `YAML`, `XML` or [Config::General](https://metacpan.org/pod/Config::General) config file +like `myapp.conf` in your applications home directory. See +[Catalyst::Plugin::ConfigLoader](https://metacpan.org/pod/Catalyst::Plugin::ConfigLoader). + +### Cascading configuration + +The config method is present on all Catalyst components, and configuration +will be merged when an application is started. Configuration loaded with +[Catalyst::Plugin::ConfigLoader](https://metacpan.org/pod/Catalyst::Plugin::ConfigLoader) takes precedence over other configuration, +followed by configuration in your top level `MyApp` class. These two +configurations are merged, and then configuration data whose hash key matches a +component name is merged with configuration for that component. + +The configuration for a component is then passed to the `new` method when a +component is constructed. + +For example: + + MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } }); + MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' }); + +will mean that `MyApp::Model::Foo` receives the following data when +constructed: + + MyApp::Model::Foo->new({ + bar => 'baz', + quux => 'frob', + overrides => 'me', + }); + +It's common practice to use a Moose attribute +on the receiving component to access the config value. + + package MyApp::Model::Foo; + + use Moose; + + # this attr will receive 'baz' at construction time + has 'bar' => ( + is => 'rw', + isa => 'Str', + ); + +You can then get the value 'baz' by calling $c->model('Foo')->bar +(or $self->bar inside code in the model). + +**NOTE:** you MUST NOT call `$self->config` or `__PACKAGE__->config` +as a way of reading config within your code, as this **will not** give you the +correctly merged config back. You **MUST** take the config values supplied to +the constructor and use those instead. + +## $c->log + +Returns the logging object instance. Unless it is already set, Catalyst +sets this up with a [Catalyst::Log](https://metacpan.org/pod/Catalyst::Log) object. To use your own log class, +set the logger with the `__PACKAGE__->log` method prior to calling +`__PACKAGE__->setup`. + + __PACKAGE__->log( MyLogger->new ); + __PACKAGE__->setup; + +And later: + + $c->log->info( 'Now logging with my own logger!' ); + +Your log class should implement the methods described in +[Catalyst::Log](https://metacpan.org/pod/Catalyst::Log). + +## has\_encoding + +Returned True if there's a valid encoding + +## clear\_encoding + +Clears the encoding for the current context + +## encoding + +Sets or gets the application encoding. Setting encoding takes either an +Encoding object or a string that we try to resolve via [Encode::find\_encoding](https://metacpan.org/pod/Encode::find_encoding). + +You would expect to get the encoding object back if you attempt to set it. If +there is a failure you will get undef returned and an error message in the log. + +## $c->debug + +Returns 1 if debug mode is enabled, 0 otherwise. + +You can enable debug mode in several ways: + +- By calling myapp\_server.pl with the -d flag +- With the environment variables MYAPP\_DEBUG, or CATALYST\_DEBUG +- The -Debug option in your MyApp.pm +- By declaring `sub debug { 1 }` in your MyApp.pm. + +The first three also set the log level to 'debug'. + +Calling `$c->debug(1)` has no effect. + +## $c->dispatcher + +Returns the dispatcher instance. See [Catalyst::Dispatcher](https://metacpan.org/pod/Catalyst::Dispatcher). + +## $c->engine + +Returns the engine instance. See [Catalyst::Engine](https://metacpan.org/pod/Catalyst::Engine). + +## UTILITY METHODS + +## $c->path\_to(@path) + +Merges `@path` with `$c->config->{home}` and returns a +[Path::Class::Dir](https://metacpan.org/pod/Path::Class::Dir) object. Note you can usually use this object as +a filename, but sometimes you will have to explicitly stringify it +yourself by calling the `->stringify` method. + +For example: + + $c->path_to( 'db', 'sqlite.db' ); + +## MyApp->setup + +Initializes the dispatcher and engine, loads any plugins, and loads the +model, view, and controller components. You may also specify an array +of plugins to load here, if you choose to not load them in the `use +Catalyst` line. + + MyApp->setup; + MyApp->setup( qw/-Debug/ ); + +**Note:** You **should not** wrap this method with method modifiers +or bad things will happen - wrap the `setup_finalize` method instead. + +**Note:** You can create a custom setup stage that will execute when the +application is starting. Use this to customize setup. + + MyApp->setup(-Custom=value); + + sub setup_custom { + my ($class, $value) = @_; + } + +Can be handy if you want to hook into the setup phase. + +## $app->setup\_finalize + +A hook to attach modifiers to. This method does not do anything except set the +`setup_finished` accessor. + +Applying method modifiers to the `setup` method doesn't work, because of quirky things done for plugin setup. + +Example: + + after setup_finalize => sub { + my $app = shift; + + ## do stuff here.. + }; + +## $c->uri\_for( $path?, @args?, \\%query\_values? ) + +## $c->uri\_for( $action, \\@captures?, @args?, \\%query\_values? ) + +## $c->uri\_for( $action, \[@captures, @args\], \\%query\_values? ) + +Constructs an absolute [URI](https://metacpan.org/pod/URI) object based on the application root, the +provided path, and the additional arguments and query parameters provided. +When used as a string, provides a textual URI. If you need more flexibility +than this (i.e. the option to provide relative URIs etc.) see +[Catalyst::Plugin::SmartURI](https://metacpan.org/pod/Catalyst::Plugin::SmartURI). + +If no arguments are provided, the URI for the current action is returned. +To return the current action and also provide @args, use +`$c->uri_for( $c->action, @args )`. + +If the first argument is a string, it is taken as a public URI path relative +to `$c->namespace` (if it doesn't begin with a forward slash) or +relative to the application root (if it does). It is then merged with +`$c->request->base`; any `@args` are appended as additional path +components; and any `%query_values` are appended as `?foo=bar` parameters. + +If the first argument is a [Catalyst::Action](https://metacpan.org/pod/Catalyst::Action) it represents an action which +will have its path resolved using `$c->dispatcher->uri_for_action`. The +optional `\@captures` argument (an arrayref) allows passing the captured +variables that are needed to fill in the paths of Chained and Regex actions; +once the path is resolved, `uri_for` continues as though a path was +provided, appending any arguments or parameters and creating an absolute +URI. + +The captures for the current request can be found in +`$c->request->captures`, and actions can be resolved using +`Catalyst::Controller->action_for($name)`. If you have a private action +path, use `$c->uri_for_action` instead. + + # Equivalent to $c->req->uri + $c->uri_for($c->action, $c->req->captures, + @{ $c->req->args }, $c->req->params); + + # For the Foo action in the Bar controller + $c->uri_for($c->controller('Bar')->action_for('Foo')); + + # Path to a static resource + $c->uri_for('/static/images/logo.png'); + +In general the scheme of the generated URI object will follow the incoming request +however if your targeted action or action chain has the Scheme attribute it will +use that instead. + +Also, if the targeted Action or Action chain declares Args/CaptureArgs that have +type constraints, we will require that your proposed URL verify on those declared +constraints. + +## $c->uri\_for\_action( $path, \\@captures\_and\_args?, @args?, \\%query\_values? ) + +## $c->uri\_for\_action( $action, \\@captures\_and\_args?, @args?, \\%query\_values? ) + +- $path + + A private path to the Catalyst action you want to create a URI for. + + This is a shortcut for calling `$c->dispatcher->get_action_by_path($path)` and passing the resulting `$action` and the remaining arguments to `$c->uri_for`. + + You can also pass in a Catalyst::Action object, in which case it is passed to + `$c->uri_for`. + + Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action. + + For example, if the action looks like: + + package MyApp::Controller::Users; + + sub lst : Path('the-list') {} + + You can use: + + $c->uri_for_action('/users/lst') + + and it will create the URI /users/the-list. + +- \\@captures\_and\_args? + + Optional array reference of Captures (i.e. `captures>) + and arguments to the request. Usually used with [Catalyst::DispatchType::Chained](https://metacpan.org/pod/Catalyst::DispatchType::Chained) + to interpolate all the parameters in the URI. + +- @args? + + Optional list of extra arguments - can be supplied in the + `\@captures_and_args?` array ref, or here - whichever is easier for your + code. + + Your action can have zero, a fixed or a variable number of args (e.g. + `Args(1)` for a fixed number or `Args()` for a variable number).. + +- \\%query\_values? + + Optional array reference of query parameters to append. E.g. + + { foo => 'bar' } + + will generate + + /rest/of/your/uri?foo=bar + +## $c->welcome\_message + +Returns the Catalyst welcome HTML page. + +## run\_options + +Contains a hash of options passed from the application script, including +the original ARGV the script received, the processed values from that +ARGV and any extra arguments to the script which were not processed. + +This can be used to add custom options to your application's scripts +and setup your application differently depending on the values of these +options. + +# INTERNAL METHODS + +These methods are not meant to be used by end users. + +## $c->components + +Returns a hash of components. + +## $c->context\_class + +Returns or sets the context class. + +## $c->counter + +Returns a hashref containing coderefs and execution counts (needed for +deep recursion detection). + +## $c->depth + +Returns the number of actions on the current internal execution stack. + +## $c->dispatch + +Dispatches a request to actions. + +## $c->dispatcher\_class + +Returns or sets the dispatcher class. + +## $c->dump\_these + +Returns a list of 2-element array references (name, structure) pairs +that will be dumped on the error page in debug mode. + +## $c->engine\_class + +Returns or sets the engine class. + +## $c->execute( $class, $coderef ) + +Execute a coderef in given class and catch exceptions. Errors are available +via $c->error. + +## $c->finalize + +Finalizes the request. + +## $c->finalize\_body + +Finalizes body. + +## $c->finalize\_cookies + +Finalizes cookies. + +## $c->finalize\_error + +Finalizes error. If there is only one error in ["error"](#error) and it is an object that +does `as_psgi` or `code` we rethrow the error and presume it caught by middleware +up the ladder. Otherwise we return the debugging error page (in debug mode) or we +return the default error page (production mode). + +## $c->finalize\_headers + +Finalizes headers. + +## $c->finalize\_encoding + +Make sure your body is encoded properly IF you set an encoding. By +default the encoding is UTF-8 but you can disable it by explicitly setting the +encoding configuration value to undef. + +We can only encode when the body is a scalar. Methods for encoding via the +streaming interfaces (such as `write` and `write_fh` on [Catalyst::Response](https://metacpan.org/pod/Catalyst::Response) +are available). + +See ["ENCODING"](#encoding). + +## $c->finalize\_output + +An alias for finalize\_body. + +## $c->finalize\_read + +Finalizes the input after reading is complete. + +## $c->finalize\_uploads + +Finalizes uploads. Cleans up any temporary files. + +## $c->get\_action( $action, $namespace ) + +Gets an action in a given namespace. + +## $c->get\_actions( $action, $namespace ) + +Gets all actions of a given name in a namespace and all parent +namespaces. + +## $app->handle\_request( @arguments ) + +Called to handle each HTTP request. + +## $class->prepare( @arguments ) + +Creates a Catalyst context from an engine-specific request (Apache, CGI, +etc.). + +## $c->prepare\_action + +Prepares action. See [Catalyst::Dispatcher](https://metacpan.org/pod/Catalyst::Dispatcher). + +## $c->prepare\_body + +Prepares message body. + +## $c->prepare\_body\_chunk( $chunk ) + +Prepares a chunk of data before sending it to [HTTP::Body](https://metacpan.org/pod/HTTP::Body). + +See [Catalyst::Engine](https://metacpan.org/pod/Catalyst::Engine). + +## $c->prepare\_body\_parameters + +Prepares body parameters. + +## $c->prepare\_connection + +Prepares connection. + +## $c->prepare\_cookies + +Prepares cookies by ensuring that the attribute on the request +object has been built. + +## $c->prepare\_headers + +Prepares request headers by ensuring that the attribute on the request +object has been built. + +## $c->prepare\_parameters + +Prepares parameters. + +## $c->prepare\_path + +Prepares path and base. + +## $c->prepare\_query\_parameters + +Prepares query parameters. + +## $c->log\_request + +Writes information about the request to the debug logs. This includes: + +- Request method, path, and remote IP address +- Query keywords (see ["query\_keywords" in Catalyst::Request](https://metacpan.org/pod/Catalyst::Request#query_keywords)) +- Request parameters +- File uploads + +## $c->log\_response + +Writes information about the response to the debug logs by calling +`$c->log_response_status_line` and `$c->log_response_headers`. + +## $c->log\_response\_status\_line($response) + +Writes one line of information about the response to the debug logs. This includes: + +- Response status code +- Content-Type header (if present) +- Content-Length header (if present) + +## $c->log\_response\_headers($headers); + +Hook method which can be wrapped by plugins to log the response headers. +No-op in the default implementation. + +## $c->log\_request\_parameters( query => {}, body => {} ) + +Logs request parameters to debug logs + +## $c->log\_request\_uploads + +Logs file uploads included in the request to the debug logs. +The parameter name, filename, file type, and file size are all included in +the debug logs. + +## $c->log\_request\_headers($headers); + +Hook method which can be wrapped by plugins to log the request headers. +No-op in the default implementation. + +## $c->log\_headers($type => $headers) + +Logs [HTTP::Headers](https://metacpan.org/pod/HTTP::Headers) (either request or response) to the debug logs. + +## $c->prepare\_read + +Prepares the input for reading. + +## $c->prepare\_request + +Prepares the engine request. + +## $c->prepare\_uploads + +Prepares uploads. + +## $c->prepare\_write + +Prepares the output for writing. + +## $c->request\_class + +Returns or sets the request class. Defaults to [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request). + +## $app->request\_class\_traits + +An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s which are applied to the request class. + +## $app->composed\_request\_class + +This is the request class which has been composed with any request\_class\_traits. + +## $c->response\_class + +Returns or sets the response class. Defaults to [Catalyst::Response](https://metacpan.org/pod/Catalyst::Response). + +## $app->response\_class\_traits + +An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s which are applied to the response class. + +## $app->composed\_response\_class + +This is the request class which has been composed with any response\_class\_traits. + +## $c->read( \[$maxlength\] ) + +Reads a chunk of data from the request body. This method is designed to +be used in a while loop, reading `$maxlength` bytes on every call. +`$maxlength` defaults to the size of the request if not specified. + +You have to set `MyApp->config(parse_on_demand => 1)` to use this +directly. + +Warning: If you use read(), Catalyst will not process the body, +so you will not be able to access POST parameters or file uploads via +$c->request. You must handle all body parsing yourself. + +## $c->run + +Starts the engine. + +## $c->set\_action( $action, $code, $namespace, $attrs ) + +Sets an action in a given namespace. + +## $c->setup\_actions($component) + +Sets up actions for a component. + +## $c->setup\_components + +This method is called internally to set up the application's components. + +It finds modules by calling the [locate\_components](https://metacpan.org/pod/locate_components) method, expands them to +package names with the [expand\_component\_module](https://metacpan.org/pod/expand_component_module) method, and then installs +each component into the application. + +The `setup_components` config option is passed to both of the above methods. + +Installation of each component is performed by the [setup\_component](https://metacpan.org/pod/setup_component) method, +below. + +## $app->setup\_injected\_components + +Called by setup\_compoents to setup components that are injected. + +## $app->setup\_injected\_component( $injected\_component\_name, $config ) + +Setup a given injected component. + +## $app->inject\_component($MyApp\_Component\_name => \\%args); + +Add a component that is injected at setup: + + MyApp->inject_component( 'Model::Foo' => { from_component => 'Common::Foo' } ); + +Must be called before ->setup. Expects a component name for your +current application and \\%args where + +- from\_component + + The target component being injected into your application + +- roles + + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that are applied to your component. + +Example + + MyApp->inject_component( + 'Model::Foo' => { + from_component => 'Common::Model::Foo', + roles => ['Role1', 'Role2'], + }); + +## $app->inject\_components + +Inject a list of components: + + MyApp->inject_components( + 'Model::FooOne' => { + from_component => 'Common::Model::Foo', + roles => ['Role1', 'Role2'], + }, + 'Model::FooTwo' => { + from_component => 'Common::Model::Foo', + roles => ['Role1', 'Role2'], + }); + +## $c->locate\_components( $setup\_component\_config ) + +This method is meant to provide a list of component modules that should be +setup for the application. By default, it will use [Module::Pluggable](https://metacpan.org/pod/Module::Pluggable). + +Specify a `setup_components` config option to pass additional options directly +to [Module::Pluggable](https://metacpan.org/pod/Module::Pluggable). To add additional search paths, specify a key named +`search_extra` as an array reference. Items in the array beginning with `::` +will have the application class name prepended to them. + +## $c->expand\_component\_module( $component, $setup\_component\_config ) + +Components found by `locate_components` will be passed to this method, which +is expected to return a list of component (package) names to be set up. + +## $app->delayed\_setup\_component + +Returns a coderef that points to a setup\_component instance. Used +internally for when you want to delay setup until the first time +the component is called. + +## $c->setup\_component + +## $app->config\_for( $component\_name ) + +Return the application level configuration (which is not yet merged with any +local component configuration, via $component\_class->config) for the named +component or component object. Example: + + MyApp->config( + 'Model::Foo' => { a => 1, b => 2}, + ); + + my $config = MyApp->config_for('MyApp::Model::Foo'); + +In this case $config is the hashref ` {a=`1, b=>2} >. + +This is also handy for looking up configuration for a plugin, to make sure you follow +existing [Catalyst](https://metacpan.org/pod/Catalyst) standards for where a plugin should put its configuration. + +## $c->setup\_dispatcher + +Sets up dispatcher. + +## $c->setup\_engine + +Sets up engine. + +## $c->apply\_default\_middlewares + +Adds the following [Plack](https://metacpan.org/pod/Plack) middlewares to your application, since they are +useful and commonly needed: + +[Plack::Middleware::LighttpdScriptNameFix](https://metacpan.org/pod/Plack::Middleware::LighttpdScriptNameFix) (if you are using Lighttpd), +[Plack::Middleware::IIS6ScriptNameFix](https://metacpan.org/pod/Plack::Middleware::IIS6ScriptNameFix) (always applied since this middleware +is smart enough to conditionally apply itself). + +We will also automatically add [Plack::Middleware::ReverseProxy](https://metacpan.org/pod/Plack::Middleware::ReverseProxy) if we notice +that your HTTP $env variable `REMOTE_ADDR` is '127.0.0.1'. This is usually +an indication that your server is running behind a proxy frontend. However in +2014 this is often not the case. We preserve this code for backwards compatibility +however I **highly** recommend that if you are running the server behind a front +end proxy that you clearly indicate so with the `using_frontend_proxy` configuration +setting to true for your environment configurations that run behind a proxy. This +way if you change your front end proxy address someday your code would inexplicably +stop working as expected. + +Additionally if we detect we are using Nginx, we add a bit of custom middleware +to solve some problems with the way that server handles $ENV{PATH\_INFO} and +$ENV{SCRIPT\_NAME}. + +Please **NOTE** that if you do use `using_frontend_proxy` the middleware is now +adding via `registered_middleware` rather than this method. + +If you are using Lighttpd or IIS6 you may wish to apply these middlewares. In +general this is no longer a common case but we have this here for backward +compatibility. + +## App->psgi\_app + +## App->to\_app + +Returns a PSGI application code reference for the catalyst application +`$c`. This is the bare application created without the `apply_default_middlewares` +method called. We do however apply `registered_middleware` since those are +integral to how [Catalyst](https://metacpan.org/pod/Catalyst) functions. Also, unlike starting your application +with a generated server script (via [Catalyst::Devel](https://metacpan.org/pod/Catalyst::Devel) and `catalyst.pl`) we do +not attempt to return a valid [PSGI](https://metacpan.org/pod/PSGI) application using any existing `${myapp}.psgi` +scripts in your $HOME directory. + +**NOTE** `apply_default_middlewares` was originally created when the first PSGI +port was done for v5.90000. These are middlewares that are added to achieve +backward compatibility with older applications. If you start your application +using one of the supplied server scripts (generated with [Catalyst::Devel](https://metacpan.org/pod/Catalyst::Devel) and +the project skeleton script `catalyst.pl`) we apply `apply_default_middlewares` +automatically. This was done so that pre and post PSGI port applications would +work the same way. + +This is what you want to be using to retrieve the PSGI application code +reference of your Catalyst application for use in a custom `.psgi` or in your +own created server modules. + +## $c->setup\_home + +Sets up the home directory. + +## $c->setup\_encoding + +Sets up the input/output encoding. See [ENCODING](https://metacpan.org/pod/ENCODING) + +## handle\_unicode\_encoding\_exception + +Hook to let you customize how encoding errors are handled. By default +we just throw an exception. Receives a hashref of debug information. +Example: + + $c->handle_unicode_encoding_exception({ + param_value => $value, + error_msg => $_, + encoding_step => 'params', + }); + +## $c->setup\_log + +Sets up log by instantiating a [Catalyst::Log](https://metacpan.org/pod/Catalyst::Log) object and +passing it to `log()`. Pass in a comma-delimited list of levels to set the +log to. + +This method also installs a `debug` method that returns a true value into the +catalyst subclass if the "debug" level is passed in the comma-delimited list, +or if the `$CATALYST_DEBUG` environment variable is set to a true value. + +Note that if the log has already been setup, by either a previous call to +`setup_log` or by a call such as `__PACKAGE__->log( MyLogger->new )`, +that this method won't actually set up the log object. + +## $c->setup\_plugins + +Sets up plugins. + +## $c->setup\_stats + +Sets up timing statistics class. + +## $c->registered\_plugins + +Returns a sorted list of the plugins which have either been stated in the +import list. + +If passed a given plugin name, it will report a boolean value indicating +whether or not that plugin is loaded. A fully qualified name is required if +the plugin name does not begin with `Catalyst::Plugin::`. + + if ($c->registered_plugins('Some::Plugin')) { + ... + } + +## default\_middleware + +Returns a list of instantiated PSGI middleware objects which is the default +middleware that is active for this application (taking any configuration +options into account, excluding your custom added middleware via the `psgi_middleware` +configuration option). You can override this method if you wish to change +the default middleware (although do so at risk since some middleware is vital +to application function.) + +The current default middleware list is: + + Catalyst::Middleware::Stash + Plack::Middleware::HTTPExceptions + Plack::Middleware::RemoveRedundantBody + Plack::Middleware::FixMissingBodyInRedirect + Plack::Middleware::ContentLength + Plack::Middleware::MethodOverride + Plack::Middleware::Head + +If the configuration setting `using_frontend_proxy` is true we add: + + Plack::Middleware::ReverseProxy + +If the configuration setting `using_frontend_proxy_path` is true we add: + + Plack::Middleware::ReverseProxyPath + +But **NOTE** that [Plack::Middleware::ReverseProxyPath](https://metacpan.org/pod/Plack::Middleware::ReverseProxyPath) is not a dependency of the +[Catalyst](https://metacpan.org/pod/Catalyst) distribution so if you want to use this option you should add it to +your project distribution file. + +These middlewares will be added at ["setup\_middleware"](#setup_middleware) during the +["setup"](#setup) phase of application startup. + +## registered\_middlewares + +Read only accessor that returns an array of all the middleware in the order +that they were added (which is the REVERSE of the order they will be applied). + +The values returned will be either instances of [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) or of a +compatible interface, or a coderef, which is assumed to be inlined middleware + +## setup\_middleware (?@middleware) + +Read configuration information stored in configuration key `psgi_middleware` or +from passed @args. + +See under ["CONFIGURATION"](#configuration) information regarding `psgi_middleware` and how +to use it to enable [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) + +This method is automatically called during 'setup' of your application, so +you really don't need to invoke it. However you may do so if you find the idea +of loading middleware via configuration weird :). For example: + + package MyApp; + + use Catalyst; + + __PACKAGE__->setup_middleware('Head'); + __PACKAGE__->setup; + +When we read middleware definitions from configuration, we reverse the list +which sounds odd but is likely how you expect it to work if you have prior +experience with [Plack::Builder](https://metacpan.org/pod/Plack::Builder) or if you previously used the plugin +[Catalyst::Plugin::EnableMiddleware](https://metacpan.org/pod/Catalyst::Plugin::EnableMiddleware) (which is now considered deprecated) + +So basically your middleware handles an incoming request from the first +registered middleware, down and handles the response from the last middleware +up. + +## registered\_data\_handlers + +A read only copy of registered Data Handlers returned as a Hash, where each key +is a content type and each value is a subref that attempts to decode that content +type. + +## setup\_data\_handlers (?@data\_handler) + +Read configuration information stored in configuration key `data_handlers` or +from passed @args. + +See under ["CONFIGURATION"](#configuration) information regarding `data_handlers`. + +This method is automatically called during 'setup' of your application, so +you really don't need to invoke it. + +## default\_data\_handlers + +Default Data Handlers that come bundled with [Catalyst](https://metacpan.org/pod/Catalyst). Currently there are +only two default data handlers, for 'application/json' and an alternative to +'application/x-www-form-urlencoded' which supposed nested form parameters via +[CGI::Struct](https://metacpan.org/pod/CGI::Struct) or via [CGI::Struct::XS](https://metacpan.org/pod/CGI::Struct::XS) IF you've installed it. + +The 'application/json' data handler is used to parse incoming JSON into a Perl +data structure. It used either [JSON::MaybeXS](https://metacpan.org/pod/JSON::MaybeXS) or [JSON](https://metacpan.org/pod/JSON), depending on which +is installed. This allows you to fail back to [JSON:PP](JSON:PP), which is a Pure Perl +JSON decoder, and has the smallest dependency impact. + +Because we don't wish to add more dependencies to [Catalyst](https://metacpan.org/pod/Catalyst), if you wish to +use this new feature we recommend installing [JSON](https://metacpan.org/pod/JSON) or [JSON::MaybeXS](https://metacpan.org/pod/JSON::MaybeXS) in +order to get the best performance. You should add either to your dependency +list (Makefile.PL, dist.ini, cpanfile, etc.) + +## $c->stack + +Returns an arrayref of the internal execution stack (actions that are +currently executing). + +## $c->stats + +Returns the current timing statistics object. By default Catalyst uses +[Catalyst::Stats](https://metacpan.org/pod/Catalyst::Stats), but can be set otherwise with +[stats\_class](#c-stats_class). + +Even if [-Stats](#stats) is not enabled, the stats object is still +available. By enabling it with ` $c-`stats->enabled(1) >, it can be used to +profile explicitly, although MyApp.pm still won't profile nor output anything +by itself. + +## $c->stats\_class + +Returns or sets the stats (timing statistics) class. [Catalyst::Stats](https://metacpan.org/pod/Catalyst::Stats) is used by default. + +## $app->stats\_class\_traits + +A arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that are applied to the stats\_class before creating it. + +## $app->composed\_stats\_class + +this is the stats\_class composed with any 'stats\_class\_traits'. + +## $c->use\_stats + +Returns 1 when [stats collection](#stats) is enabled. + +Note that this is a static method, not an accessor and should be overridden +by declaring `sub use_stats { 1 }` in your MyApp.pm, not by calling `$c->use_stats(1)`. + +## $c->write( $data ) + +Writes $data to the output stream. When using this method directly, you +will need to manually set the `Content-Length` header to the length of +your output data, if known. + +## version + +Returns the Catalyst version number. Mostly useful for "powered by" +messages in template systems. + +# CONFIGURATION + +There are a number of 'base' config variables which can be set: + +- `always_catch_http_exceptions` - As of version 5.90060 Catalyst +rethrows errors conforming to the interface described by +[Plack::Middleware::HTTPExceptions](https://metacpan.org/pod/Plack::Middleware::HTTPExceptions) and lets the middleware deal with it. +Set true to get the deprecated behaviour and have Catalyst catch HTTP exceptions. +- `default_model` - The default model picked if you say `$c->model`. See ["$c->model($name)"](#c-model-name). +- `default_view` - The default view to be rendered or returned when `$c->view` is called. See ["$c->view($name)"](#c-view-name). +- `disable_component_resolution_regex_fallback` - Turns +off the deprecated component resolution functionality so +that if any of the component methods (e.g. `$c->controller('Foo')`) +are called then regex search will not be attempted on string values and +instead `undef` will be returned. +- `home` - The application home directory. In an uninstalled application, +this is the top level application directory. In an installed application, +this will be the directory containing `MyApp.pm`. +- `ignore_frontend_proxy` - See ["PROXY SUPPORT"](#proxy-support) +- `name` - The name of the application in debug messages and the debug and +welcome screens +- `parse_on_demand` - The request body (for example file uploads) will not be parsed +until it is accessed. This allows you to (for example) check authentication (and reject +the upload) before actually receiving all the data. See ["ON-DEMAND PARSER"](#on-demand-parser) +- `root` - The root directory for templates. Usually this is just a +subdirectory of the home directory, but you can set it to change the +templates to a different directory. +- `search_extra` - Array reference passed to Module::Pluggable to for additional +namespaces from which components will be loaded (and constructed and stored in +`$c->components`). +- `show_internal_actions` - If true, causes internal actions such as `_DISPATCH` +to be shown in hit debug tables in the test server. +- `use_request_uri_for_path` - Controls if the `REQUEST_URI` or `PATH_INFO` environment +variable should be used for determining the request path. + + Most web server environments pass the requested path to the application using environment variables, + from which Catalyst has to reconstruct the request base (i.e. the top level path to / in the application, + exposed as `$c->request->base`) and the request path below that base. + + There are two methods of doing this, both of which have advantages and disadvantages. Which method is used + is determined by the `$c->config(use_request_uri_for_path)` setting (which can either be true or false). + + - use\_request\_uri\_for\_path => 0 + + This is the default (and the) traditional method that Catalyst has used for determining the path information. + The path is generated from a combination of the `PATH_INFO` and `SCRIPT_NAME` environment variables. + The allows the application to behave correctly when `mod_rewrite` is being used to redirect requests + into the application, as these variables are adjusted by mod\_rewrite to take account for the redirect. + + However this method has the major disadvantage that it is impossible to correctly decode some elements + of the path, as RFC 3875 says: "`Unlike a URI path, the PATH_INFO is not URL-encoded, and cannot + contain path-segment parameters.`" This means PATH\_INFO is **always** decoded, and therefore Catalyst + can't distinguish / vs %2F in paths (in addition to other encoded values). + + - use\_request\_uri\_for\_path => 1 + + This method uses the `REQUEST_URI` and `SCRIPT_NAME` environment variables. As `REQUEST_URI` is never + decoded, this means that applications using this mode can correctly handle URIs including the %2F character + (i.e. with `AllowEncodedSlashes` set to `On` in Apache). + + Given that this method of path resolution is provably more correct, it is recommended that you use + this unless you have a specific need to deploy your application in a non-standard environment, and you are + aware of the implications of not being able to handle encoded URI paths correctly. + + However it also means that in a number of cases when the app isn't installed directly at a path, but instead + is having paths rewritten into it (e.g. as a .cgi/fcgi in a public\_html directory, with mod\_rewrite in a + .htaccess file, or when SSI is used to rewrite pages into the app, or when sub-paths of the app are exposed + at other URIs than that which the app is 'normally' based at with `mod_rewrite`), the resolution of + `$c->request->base` will be incorrect. + +- `using_frontend_proxy` - See ["PROXY SUPPORT"](#proxy-support). +- `using_frontend_proxy_path` - Enabled [Plack::Middleware::ReverseProxyPath](https://metacpan.org/pod/Plack::Middleware::ReverseProxyPath) on your application (if +installed, otherwise log an error). This is useful if your application is not running on the +'root' (or /) of your host server. **NOTE** if you use this feature you should add the required +middleware to your project dependency list since its not automatically a dependency of [Catalyst](https://metacpan.org/pod/Catalyst). +This has been done since not all people need this feature and we wish to restrict the growth of +[Catalyst](https://metacpan.org/pod/Catalyst) dependencies. +- `encoding` - See ["ENCODING"](#encoding) + + This now defaults to 'UTF-8'. You my turn it off by setting this configuration + value to undef. + +- `abort_chain_on_error_fix` + + When there is an error in an action chain, the default behavior is to continue + processing the remaining actions and then catch the error upon chain end. This + can lead to running actions when the application is in an unexpected state. If + you have this issue, setting this config value to true will promptly exit a + chain when there is an error raised in any action (thus terminating the chain + early.) + + use like: + + __PACKAGE__->config(abort_chain_on_error_fix => 1); + + In the future this might become the default behavior. + +- `use_hash_multivalue_in_request` + + In [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request) the methods `query_parameters`, `body_parametes` + and `parameters` return a hashref where values might be scalar or an arrayref + depending on the incoming data. In many cases this can be undesirable as it + leads one to writing defensive code like the following: + + my ($val) = ref($c->req->parameters->{a}) ? + @{$c->req->parameters->{a}} : + $c->req->parameters->{a}; + + Setting this configuration item to true will make [Catalyst](https://metacpan.org/pod/Catalyst) populate the + attributes underlying these methods with an instance of [Hash::MultiValue](https://metacpan.org/pod/Hash::MultiValue) + which is used by [Plack::Request](https://metacpan.org/pod/Plack::Request) and others to solve this very issue. You + may prefer this behavior to the default, if so enable this option (be warned + if you enable it in a legacy application we are not sure if it is completely + backwardly compatible). + +- `skip_complex_post_part_handling` + + When creating body parameters from a POST, if we run into a multpart POST + that does not contain uploads, but instead contains inlined complex data + (very uncommon) we cannot reliably convert that into field => value pairs. So + instead we create an instance of [Catalyst::Request::PartData](https://metacpan.org/pod/Catalyst::Request::PartData). If this causes + issue for you, you can disable this by setting `skip_complex_post_part_handling` + to true (default is false). + +- `skip_body_param_unicode_decoding` + + Generally we decode incoming POST params based on your declared encoding (the + default for this is to decode UTF-8). If this is causing you trouble and you + do not wish to turn all encoding support off (with the `encoding` configuration + parameter) you may disable this step atomically by setting this configuration + parameter to true. + +- `do_not_decode_query` + + If true, then do not try to character decode any wide characters in your + request URL query or keywords. Most readings of the relevent specifications + suggest these should be UTF-\* encoded, which is the default that [Catalyst](https://metacpan.org/pod/Catalyst) + will use, hwoever if you are creating a lot of URLs manually or have external + evil clients, this might cause you trouble. If you find the changes introduced + in Catalyst version 5.90080+ break some of your query code, you may disable + the UTF-8 decoding globally using this configuration. + + This setting takes precedence over `default_query_encoding` and + `decode_query_using_global_encoding` + +- `default_query_encoding` + + By default we decode query and keywords in your request URL using UTF-8, which + is our reading of the relevent specifications. This setting allows one to + specify a fixed value for how to decode your query. You might need this if + you are doing a lot of custom encoding of your URLs and not using UTF-8. + + This setting take precedence over `decode_query_using_global_encoding`. + +- `decode_query_using_global_encoding` + + Setting this to true will default your query decoding to whatever your + general global encoding is (the default is UTF-8). + +- `use_chained_args_0_special_case` + + In older versions of Catalyst, when more than one action matched the same path + AND all those matching actions declared Args(0), we'd break the tie by choosing + the first action defined. We now normalized how Args(0) works so that it + follows the same rule as Args(N), which is to say when we need to break a tie + we choose the LAST action defined. If this breaks your code and you don't + have time to update to follow the new normalized approach, you may set this + value to true and it will globally revert to the original chaining behavior. + +- `psgi_middleware` - See ["PSGI MIDDLEWARE"](#psgi-middleware). +- `data_handlers` - See ["DATA HANDLERS"](#data-handlers). +- `stats_class_traits` + + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your stats class. + +- `request_class_traits` + + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your request class. + +- `response_class_traits` + + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your response class. + +- `inject_components` + + A Hashref of [Catalyst::Component](https://metacpan.org/pod/Catalyst::Component) subclasses that are 'injected' into configuration. + For example: + + MyApp->config({ + inject_components => { + 'Controller::Err' => { from_component => 'Local::Controller::Errors' }, + 'Model::Zoo' => { from_component => 'Local::Model::Foo' }, + 'Model::Foo' => { from_component => 'Local::Model::Foo', roles => ['TestRole'] }, + }, + 'Controller::Err' => { a => 100, b=>200, namespace=>'error' }, + 'Model::Zoo' => { a => 2 }, + 'Model::Foo' => { a => 100 }, + }); + + Generally [Catalyst](https://metacpan.org/pod/Catalyst) looks for components in your Model/View or Controller directories. + However for cases when you which to use an existing component and you don't need any + customization (where for when you can apply a role to customize it) you may inject those + components into your application. Please note any configuration should be done 'in the + normal way', with a key under configuration named after the component affix, as in the + above example. + + Using this type of injection allows you to construct significant amounts of your application + with only configuration!. This may or may not lead to increased code understanding. + + Please not you may also call the ->inject\_components application method as well, although + you must do so BEFORE setup. + +# EXCEPTIONS + +Generally when you throw an exception inside an Action (or somewhere in +your stack, such as in a model that an Action is calling) that exception +is caught by Catalyst and unless you either catch it yourself (via eval +or something like [Try::Tiny](https://metacpan.org/pod/Try::Tiny) or by reviewing the ["error"](#error) stack, it +will eventually reach ["finalize\_errors"](#finalize_errors) and return either the debugging +error stack page, or the default error page. However, if your exception +can be caught by [Plack::Middleware::HTTPExceptions](https://metacpan.org/pod/Plack::Middleware::HTTPExceptions), [Catalyst](https://metacpan.org/pod/Catalyst) will +instead rethrow it so that it can be handled by that middleware (which +is part of the default middleware). For example this would allow + + use HTTP::Throwable::Factory 'http_throw'; + + sub throws_exception :Local { + my ($self, $c) = @_; + + http_throw(SeeOther => { location => + $c->uri_for($self->action_for('redirect')) }); + + } + +# INTERNAL ACTIONS + +Catalyst uses internal actions like `_DISPATCH`, `_BEGIN`, `_AUTO`, +`_ACTION`, and `_END`. These are by default not shown in the private +action table, but you can make them visible with a config parameter. + + MyApp->config(show_internal_actions => 1); + +# ON-DEMAND PARSER + +The request body is usually parsed at the beginning of a request, +but if you want to handle input yourself, you can enable on-demand +parsing with a config parameter. + + MyApp->config(parse_on_demand => 1); + +# PROXY SUPPORT + +Many production servers operate using the common double-server approach, +with a lightweight frontend web server passing requests to a larger +backend server. An application running on the backend server must deal +with two problems: the remote user always appears to be `127.0.0.1` and +the server's hostname will appear to be `localhost` regardless of the +virtual host that the user connected through. + +Catalyst will automatically detect this situation when you are running +the frontend and backend servers on the same machine. The following +changes are made to the request. + + $c->req->address is set to the user's real IP address, as read from + the HTTP X-Forwarded-For header. + + The host value for $c->req->base and $c->req->uri is set to the real + host, as read from the HTTP X-Forwarded-Host header. + +Additionally, you may be running your backend application on an insecure +connection (port 80) while your frontend proxy is running under SSL. If there +is a discrepancy in the ports, use the HTTP header `X-Forwarded-Port` to +tell Catalyst what port the frontend listens on. This will allow all URIs to +be created properly. + +In the case of passing in: + + X-Forwarded-Port: 443 + +All calls to `uri_for` will result in an https link, as is expected. + +Obviously, your web server must support these headers for this to work. + +In a more complex server farm environment where you may have your +frontend proxy server(s) on different machines, you will need to set a +configuration option to tell Catalyst to read the proxied data from the +headers. + + MyApp->config(using_frontend_proxy => 1); + +If you do not wish to use the proxy support at all, you may set: + + MyApp->config(ignore_frontend_proxy => 0); + +## Note about psgi files + +Note that if you supply your own .psgi file, calling +`MyApp->psgi_app(@_);`, then **this will not happen automatically**. + +You either need to apply [Plack::Middleware::ReverseProxy](https://metacpan.org/pod/Plack::Middleware::ReverseProxy) yourself +in your psgi, for example: + + builder { + enable "Plack::Middleware::ReverseProxy"; + MyApp->psgi_app + }; + +This will unconditionally add the ReverseProxy support, or you need to call +`$app = MyApp->apply_default_middlewares($app)` (to conditionally +apply the support depending upon your config). + +See [Catalyst::PSGI](https://metacpan.org/pod/Catalyst::PSGI) for more information. + +# THREAD SAFETY + +Catalyst has been tested under Apache 2's threading `mpm_worker`, +`mpm_winnt`, and the standalone forking HTTP server on Windows. We +believe the Catalyst core to be thread-safe. + +If you plan to operate in a threaded environment, remember that all other +modules you are using must also be thread-safe. Some modules, most notably +[DBD::SQLite](https://metacpan.org/pod/DBD::SQLite), are not thread-safe. + +# DATA HANDLERS + +The [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request) object uses [HTTP::Body](https://metacpan.org/pod/HTTP::Body) to populate 'classic' HTML +form parameters and URL search query fields. However it has become common +for various alternative content types to be PUT or POSTed to your controllers +and actions. People working on RESTful APIs, or using AJAX often use JSON, +XML and other content types when communicating with an application server. In +order to better support this use case, [Catalyst](https://metacpan.org/pod/Catalyst) defines a global configuration +option, `data_handlers`, which lets you associate a content type with a coderef +that parses that content type into something Perl can readily access. + + package MyApp::Web; + + use Catalyst; + use JSON::Maybe; + + __PACKAGE__->config( + data_handlers => { + 'application/json' => sub { local $/; decode_json $_->getline }, + }, + ## Any other configuration. + ); + + __PACKAGE__->setup; + +By default [Catalyst](https://metacpan.org/pod/Catalyst) comes with a generic JSON data handler similar to the +example given above, which uses [JSON::Maybe](https://metacpan.org/pod/JSON::Maybe) to provide either [JSON::PP](https://metacpan.org/pod/JSON::PP) +(a pure Perl, dependency free JSON parser) or [Cpanel::JSON::XS](https://metacpan.org/pod/Cpanel::JSON::XS) if you have +it installed (if you want the faster XS parser, add it to you project Makefile.PL +or dist.ini, cpanfile, etc.) + +The `data_handlers` configuration is a hashref whose keys are HTTP Content-Types +(matched against the incoming request type using a regexp such as to be case +insensitive) and whose values are coderefs that receive a localized version of +`$_` which is a filehandle object pointing to received body. + +This feature is considered an early access release and we reserve the right +to alter the interface in order to provide a performant and secure solution to +alternative request body content. Your reports welcomed! + +# PSGI MIDDLEWARE + +You can define middleware, defined as [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) or a compatible +interface in configuration. Your middleware definitions are in the form of an +arrayref under the configuration key `psgi_middleware`. Here's an example +with details to follow: + + package MyApp::Web; + + use Catalyst; + use Plack::Middleware::StackTrace; + + my $stacktrace_middleware = Plack::Middleware::StackTrace->new; + + __PACKAGE__->config( + 'psgi_middleware', [ + 'Debug', + '+MyApp::Custom', + $stacktrace_middleware, + 'Session' => {store => 'File'}, + sub { + my $app = shift; + return sub { + my $env = shift; + $env->{myapp.customkey} = 'helloworld'; + $app->($env); + }, + }, + ], + ); + + __PACKAGE__->setup; + +So the general form is: + + __PACKAGE__->config(psgi_middleware => \@middleware_definitions); + +Where `@middleware` is one or more of the following, applied in the REVERSE of +the order listed (to make it function similarly to [Plack::Builder](https://metacpan.org/pod/Plack::Builder): + +Alternatively, you may also define middleware by calling the ["setup\_middleware"](#setup_middleware) +package method: + + package MyApp::Web; + + use Catalyst; + + __PACKAGE__->setup_middleware( \@middleware_definitions); + __PACKAGE__->setup; + +In the case where you do both (use 'setup\_middleware' and configuration) the +package call to setup\_middleware will be applied earlier (in other words its +middleware will wrap closer to the application). Keep this in mind since in +some cases the order of middleware is important. + +The two approaches are not exclusive. + +- Middleware Object + + An already initialized object that conforms to the [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) + specification: + + my $stacktrace_middleware = Plack::Middleware::StackTrace->new; + + __PACKAGE__->config( + 'psgi_middleware', [ + $stacktrace_middleware, + ]); + + + +- coderef + + A coderef that is an inlined middleware: + + __PACKAGE__->config( + 'psgi_middleware', [ + sub { + my $app = shift; + return sub { + my $env = shift; + if($env->{PATH_INFO} =~m/forced/) { + Plack::App::File + ->new(file=>TestApp->path_to(qw/share static forced.txt/)) + ->call($env); + } else { + return $app->($env); + } + }, + }, + ]); + + + + +- a scalar + + We assume the scalar refers to a namespace after normalizing it using the + following rules: + + (1) If the scalar is prefixed with a "+" (as in `+MyApp::Foo`) then the full string + is assumed to be 'as is', and we just install and use the middleware. + + (2) If the scalar begins with "Plack::Middleware" or your application namespace + (the package name of your Catalyst application subclass), we also assume then + that it is a full namespace, and use it. + + (3) Lastly, we then assume that the scalar is a partial namespace, and attempt to + resolve it first by looking for it under your application namespace (for example + if you application is "MyApp::Web" and the scalar is "MyMiddleware", we'd look + under "MyApp::Web::Middleware::MyMiddleware") and if we don't find it there, we + will then look under the regular [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) namespace (i.e. for the + previous we'd try "Plack::Middleware::MyMiddleware"). We look under your application + namespace first to let you 'override' common [Plack::Middleware](https://metacpan.org/pod/Plack::Middleware) locally, should + you find that a good idea. + + Examples: + + package MyApp::Web; + + __PACKAGE__->config( + 'psgi_middleware', [ + 'Debug', ## MyAppWeb::Middleware::Debug->wrap or Plack::Middleware::Debug->wrap + 'Plack::Middleware::Stacktrace', ## Plack::Middleware::Stacktrace->wrap + '+MyApp::Custom', ## MyApp::Custom->wrap + ], + ); + + +- a scalar followed by a hashref + + Just like the previous, except the following `HashRef` is used as arguments + to initialize the middleware object. + + __PACKAGE__->config( + 'psgi_middleware', [ + 'Session' => {store => 'File'}, + ]); + +Please see [PSGI](https://metacpan.org/pod/PSGI) for more on middleware. + +# ENCODING + +Starting in [Catalyst](https://metacpan.org/pod/Catalyst) version 5.90080 encoding is automatically enabled +and set to encode all body responses to UTF8 when possible and applicable. +Following is documentation on this process. If you are using an older +version of [Catalyst](https://metacpan.org/pod/Catalyst) you should review documentation for that version since +a lot has changed. + +By default encoding is now 'UTF-8'. You may turn it off by setting +the encoding configuration to undef. + + MyApp->config(encoding => undef); + +This is recommended for temporary backwards compatibility only. + +Encoding is automatically applied when the content-type is set to +a type that can be encoded. Currently we encode when the content type +matches the following regular expression: + + $content_type =~ /^text|xml$|javascript$/ + +Encoding is set on the application, but it is copied to the context object +so that you can override it on a request basis. + +Be default we don't automatically encode 'application/json' since the most +common approaches to generating this type of response (Either via [Catalyst::View::JSON](https://metacpan.org/pod/Catalyst::View::JSON) +or [Catalyst::Action::REST](https://metacpan.org/pod/Catalyst::Action::REST)) will do so already and we want to avoid double +encoding issues. + +If you are producing JSON response in an unconventional manner (such +as via a template or manual strings) you should perform the UTF8 encoding +manually as well such as to conform to the JSON specification. + +NOTE: We also examine the value of $c->response->content\_encoding. If +you set this (like for example 'gzip', and manually gzipping the body) +we assume that you have done all the necessary encoding yourself, since +we cannot encode the gzipped contents. If you use a plugin like +[Catalyst::Plugin::Compress](https://metacpan.org/pod/Catalyst::Plugin::Compress) you need to update to a modern version in order +to have this function correctly with the new UTF8 encoding code, or you +can use [Plack::Middleware::Deflater](https://metacpan.org/pod/Plack::Middleware::Deflater) or (probably best) do your compression on +a front end proxy. + +## Methods + +- encoding + + Returns an instance of an `Encode` encoding + + print $c->encoding->name + +- handle\_unicode\_encoding\_exception ($exception\_context) + + Method called when decoding process for a request fails. + + An `$exception_context` hashref is provided to allow you to override the + behaviour of your application when given data with incorrect encodings. + + The default method throws exceptions in the case of invalid request parameters + (resulting in a 500 error), but ignores errors in upload filenames. + + The keys passed in the `$exception_context` hash are: + + - param\_value + + The value which was not able to be decoded. + + - error\_msg + + The exception received from [Encode](https://metacpan.org/pod/Encode). + + - encoding\_step + + What type of data was being decoded. Valid values are (currently) + `params` - for request parameters / arguments / captures + and `uploads` - for request upload filenames. + +# SUPPORT + +IRC: + + Join #catalyst on irc.perl.org. + +Mailing Lists: + + http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst + http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev + +Web: + + http://catalyst.perl.org + +Wiki: + + http://dev.catalyst.perl.org + +# SEE ALSO + +## [Task::Catalyst](https://metacpan.org/pod/Task::Catalyst) - All you need to start with Catalyst + +## [Catalyst::Manual](https://metacpan.org/pod/Catalyst::Manual) - The Catalyst Manual + +## [Catalyst::Component](https://metacpan.org/pod/Catalyst::Component), [Catalyst::Controller](https://metacpan.org/pod/Catalyst::Controller) - Base classes for components + +## [Catalyst::Engine](https://metacpan.org/pod/Catalyst::Engine) - Core engine + +## [Catalyst::Log](https://metacpan.org/pod/Catalyst::Log) - Log class. + +## [Catalyst::Request](https://metacpan.org/pod/Catalyst::Request) - Request object + +## [Catalyst::Response](https://metacpan.org/pod/Catalyst::Response) - Response object + +## [Catalyst::Test](https://metacpan.org/pod/Catalyst::Test) - The test suite. + +# PROJECT FOUNDER + +sri: Sebastian Riedel + +# CONTRIBUTORS + +abw: Andy Wardley + +acme: Leon Brocard + +abraxxa: Alexander Hartmaier + +andrewalker: André Walker + +Andrew Bramble + +Andrew Ford + +Andrew Ruthven + +andyg: Andy Grundman + +audreyt: Audrey Tang + +bricas: Brian Cassidy + +Caelum: Rafael Kitover + +chansen: Christian Hansen + +chicks: Christopher Hicks + +Chisel Wright `pause@herlpacker.co.uk` + +Danijel Milicevic `me@danijel.de` + +davewood: David Schmidt + +David Kamholz + +David Naughton, `naughton@umn.edu` + +David E. Wheeler + +dhoss: Devin Austin + +dkubb: Dan Kubb + +Drew Taylor + +dwc: Daniel Westermann-Clark + +esskar: Sascha Kiefer + +fireartist: Carl Franks + +frew: Arthur Axel "fREW" Schmidt + +gabb: Danijel Milicevic + +Gary Ashton Jones + +Gavin Henry `ghenry@perl.me.uk` + +Geoff Richards + +groditi: Guillermo Roditi + +hobbs: Andrew Rodland + +ilmari: Dagfinn Ilmari Mannsåker + +jcamacho: Juan Camacho + +jester: Jesse Sheidlower `jester@panix.com` + +jhannah: Jay Hannah + +Jody Belka + +Johan Lindstrom + +jon: Jon Schutz + +Jonathan Rockway `` + +Kieren Diment `kd@totaldatasolution.com` + +konobi: Scott McWhirter + +marcus: Marcus Ramberg + +miyagawa: Tatsuhiko Miyagawa + +mgrimes: Mark Grimes + +mst: Matt S. Trout + +mugwump: Sam Vilain + +naughton: David Naughton + +ningu: David Kamholz + +nothingmuch: Yuval Kogman + +numa: Dan Sully + +obra: Jesse Vincent + +Octavian Rasnita + +omega: Andreas Marienborg + +Oleg Kostyuk + +phaylon: Robert Sedlacek + +rafl: Florian Ragwitz + +random: Roland Lammel + +Robert Sedlacek `` + +SpiceMan: Marcel Montes + +sky: Arthur Bergman + +szbalint: Balint Szilakszi + +t0m: Tomas Doran + +Ulf Edvinsson + +vanstyn: Henry Van Styn + +Viljo Marrandi `vilts@yahoo.com` + +Will Hawes `info@whawes.co.uk` + +willert: Sebastian Willert + +wreis: Wallace Reis + +Yuval Kogman, `nothingmuch@woobling.org` + +rainboxx: Matthias Dietrich, `perl@rainboxx.de` + +dd070: Dhaval Dhanani + +Upasana + +John Napiorkowski (jnap) + +# COPYRIGHT + +Copyright (c) 2005-2015, the above named PROJECT FOUNDER and CONTRIBUTORS. + +# LICENSE + +This library is free software. You can redistribute it and/or modify it under +the same terms as Perl itself. diff --git a/README.pod b/README.pod deleted file mode 100644 index 8d874e7..0000000 --- a/README.pod +++ /dev/null @@ -1,41 +0,0 @@ -=head1 Welcome to Catalyst - -This is the Runtime distribution for the L. - -For more information about Catalyst, write - - perldoc Catalyst - -at the command line, or visit http://www.catalystframework.org/. - -=head2 Getting Started - -1. Install Catalyst if you haven't yet: - - cpanm Catalyst - -2. Create a new catalyst application: - - catalyst.pl DemoApp - -3. Change the directory to the newly created directory and start the built-in developer server - - cd DemoApp; plackup -Ilib demoapp.psgi - -4. Go to http://localhost:5000 and you'll see the default welcome page. - -=head2 Resources - -You can also install L -from CPAN for more comprehensive information. - -If you are going to write your own Catalyst application, you will need to -install L. -Afterwards run I for more information about creating your first -app. - -=head2 Contributing - -If you would like to contribute to Catalyst, please -L on IRC, -or visit the L. diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 068a249..65b93bf 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -199,6 +199,11 @@ sub _application { $_[0] } Catalyst - The Elegant MVC Web Application Framework +=for html +CPAN version +Catalyst></a>
+<a href=Kwalitee Score + =head1 SYNOPSIS See the L distribution for comprehensive