# configure base package
__PACKAGE__->config( name => MyApp );
# configure authentication
- __PACKAGE__->config->{authentication} = {
- user_class => 'MyApp::Model::MyDB::Customer',
- ...
- };
+ __PACKAGE__->config(
+ 'Plugin::Authentication' => {
+ user_class => 'MyApp::Model::MyDB::Customer',
+ ...
+ },
+ _;
# configure sessions
- __PACKAGE__->config->{session} = {
- expires => 3600,
- ...
- };
+ __PACKAGE__->config(
+ session => {
+ expires => 3600,
+ ...
+ },
+ );
# configure email sending
- __PACKAGE__->config->{email} = [qw/SMTP localhost/];
+ __PACKAGE__->config( email => [qw/SMTP localhost/] );
See also L<Config::General|Config::General>.
}
-
-=head1 Deployment
-
-The recipes below describe aspects of the deployment process,
-including web server engines and tips to improve application efficiency.
-
-=head2 mod_perl Deployment
-
-mod_perl is not the best solution for many applications, but we'll list some
-pros and cons so you can decide for yourself. The other (recommended)
-deployment option is FastCGI, for which see below.
-
-=head3 Pros
-
-=head4 Speed
-
-mod_perl is fast and your app will be loaded in memory
-within each Apache process.
-
-=head4 Shared memory for multiple apps
-
-If you need to run several Catalyst apps on the same server, mod_perl will
-share the memory for common modules.
-
-=head3 Cons
-
-=head4 Memory usage
-
-Since your application is fully loaded in memory, every Apache process will
-be rather large. This means a large Apache process will be tied up while
-serving static files, large files, or dealing with slow clients. For this
-reason, it is best to run a two-tiered web architecture with a lightweight
-frontend server passing dynamic requests to a large backend mod_perl
-server.
-
-=head4 Reloading
-
-Any changes made to the core code of your app require a full Apache restart.
-Catalyst does not support Apache::Reload or StatINC. This is another good
-reason to run a frontend web server where you can set up an
-C<ErrorDocument 502> page to report that your app is down for maintenance.
-
-=head4 Cannot run multiple versions of the same app
-
-It is not possible to run two different versions of the same application in
-the same Apache instance because the namespaces will collide.
-
-=head4 Cannot run different versions of libraries.
-
-If you have two different applications which run on the same machine,
-which need two different versions of a library then the only way to do
-this is to have per-vhost perl interpreters (with different library paths).
-This is entirely possible, but nullifies all the memory sharing benefits that
-you get from having multiple applications sharing the same interpreter.
-
-=head4 Setup
-
-Now that we have that out of the way, let's talk about setting up mod_perl
-to run a Catalyst app.
-
-=head4 1. Install Catalyst::Engine::Apache
-
-You should install the latest versions of both Catalyst and
-Catalyst::Engine::Apache. The Apache engines were separated from the
-Catalyst core in version 5.50 to allow for updates to the engine without
-requiring a new Catalyst release.
-
-=head4 2. Install Apache with mod_perl
-
-Both Apache 1.3 and Apache 2 are supported, although Apache 2 is highly
-recommended. With Apache 2, make sure you are using the prefork MPM and not
-the worker MPM. The reason for this is that many Perl modules are not
-thread-safe and may have problems running within the threaded worker
-environment. Catalyst is thread-safe however, so if you know what you're
-doing, you may be able to run using worker.
-
-In Debian, the following commands should get you going.
-
- apt-get install apache2-mpm-prefork
- apt-get install libapache2-mod-perl2
-
-=head4 3. Configure your application
-
-Every Catalyst application will automagically become a mod_perl handler
-when run within mod_perl. This makes the configuration extremely easy.
-Here is a basic Apache 2 configuration.
-
- PerlSwitches -I/var/www/MyApp/lib
- PerlModule MyApp
-
- <Location />
- SetHandler modperl
- PerlResponseHandler MyApp
- </Location>
-
-The most important line here is C<PerlModule MyApp>. This causes mod_perl
-to preload your entire application into shared memory, including all of your
-controller, model, and view classes and configuration. If you have -Debug
-mode enabled, you will see the startup output scroll by when you first
-start Apache.
-
-For an example Apache 1.3 configuration, please see the documentation for
-L<Catalyst::Engine::Apache::MP13>.
-
-=head3 Test It
-
-That's it, your app is now a full-fledged mod_perl application! Try it out
-by going to http://your.server.com/.
-
-=head3 Other Options
-
-=head4 Non-root location
-
-You may not always want to run your app at the root of your server or virtual
-host. In this case, it's a simple change to run at any non-root location
-of your choice.
-
- <Location /myapp>
- SetHandler modperl
- PerlResponseHandler MyApp
- </Location>
-
-When running this way, it is best to make use of the C<uri_for> method in
-Catalyst for constructing correct links.
-
-=head4 Static file handling
-
-Static files can be served directly by Apache for a performance boost.
-
- DocumentRoot /var/www/MyApp/root
- <Location /static>
- SetHandler default-handler
- </Location>
-
-This will let all files within root/static be handled directly by Apache. In
-a two-tiered setup, the frontend server should handle static files.
-The configuration to do this on the frontend will vary.
-
-The same is accomplished in lighttpd with the following snippet:
-
- $HTTP["url"] !~ "^/(?:img/|static/|css/|favicon.ico$)" {
- fastcgi.server = (
- "" => (
- "MyApp" => (
- "socket" => "/tmp/myapp.socket",
- "check-local" => "disable",
- )
- )
- )
- }
-
-Which serves everything in the img, static, css directories
-statically, as well as the favicon file.
-
-Note the path of the application needs to be stated explicitly in the
-web server configuration for both these recipes.
-
-=head2 Catalyst on shared hosting
-
-So, you want to put your Catalyst app out there for the whole world to
-see, but you don't want to break the bank. There is an answer - if you
-can get shared hosting with FastCGI and a shell, you can install your
-Catalyst app in a local directory on your shared host. First, run
-
- perl -MCPAN -e shell
-
-and go through the standard CPAN configuration process. Then exit out
-without installing anything. Next, open your .bashrc and add
-
- export PATH=$HOME/local/bin:$HOME/local/script:$PATH
- perlversion=`perl -v | grep 'built for' | awk '{print $4}' | sed -e 's/v//;'`
- export PERL5LIB=$HOME/local/share/perl/$perlversion:$HOME/local/lib/perl/$perlversion:$HOME/local/lib:$PERL5LIB
-
-and log out, then back in again (or run C<". .bashrc"> if you
-prefer). Finally, edit C<.cpan/CPAN/MyConfig.pm> and add
-
- 'make_install_arg' => qq[SITEPREFIX=$ENV{HOME}/local],
- 'makepl_arg' => qq[INSTALLDIRS=site install_base=$ENV{HOME}/local],
-
-Now you can install the modules you need using CPAN as normal; they
-will be installed into your local directory, and perl will pick them
-up. Finally, change directory into the root of your virtual host and
-symlink your application's script directory in:
-
- cd path/to/mydomain.com
- ln -s ~/lib/MyApp/script script
-
-And add the following lines to your .htaccess file (assuming the server
-is setup to handle .pl as fcgi - you may need to rename the script to
-myapp_fastcgi.fcgi and/or use a SetHandler directive):
-
- RewriteEngine On
- RewriteCond %{REQUEST_URI} !^/?script/myapp_fastcgi.pl
- RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]
-
-Now C<http://mydomain.com/> should now Just Work. Congratulations, now
-you can tell your friends about your new website (or in our case, tell
-the client it's time to pay the invoice :) )
-
-=head2 FastCGI Deployment
-
-FastCGI is a high-performance extension to CGI. It is suitable
-for production environments.
-
-=head3 Pros
-
-=head4 Speed
-
-FastCGI performs equally as well as mod_perl. Don't let the 'CGI' fool you;
-your app runs as multiple persistent processes ready to receive connections
-from the web server.
-
-=head4 App Server
-
-When using external FastCGI servers, your application runs as a standalone
-application server. It may be restarted independently from the web server.
-This allows for a more robust environment and faster reload times when
-pushing new app changes. The frontend server can even be configured to
-display a friendly "down for maintenance" page while the application is
-restarting.
-
-=head4 Load-balancing
-
-You can launch your application on multiple backend servers and allow the
-frontend web server to load-balance between all of them. And of course, if
-one goes down, your app continues to run fine.
-
-=head4 Multiple versions of the same app
-
-Each FastCGI application is a separate process, so you can run different
-versions of the same app on a single server.
-
-=head4 Can run with threaded Apache
-
-Since your app is not running inside of Apache, the faster mpm_worker module
-can be used without worrying about the thread safety of your application.
-
-=head3 Cons
-
-You may have to disable mod_deflate. If you experience page hangs with
-mod_fastcgi then remove deflate.load and deflate.conf from mods-enabled/
-
-=head4 More complex environment
-
-With FastCGI, there are more things to monitor and more processes running
-than when using mod_perl.
-
-=head3 Setup
-
-=head4 1. Install Apache with mod_fastcgi
-
-mod_fastcgi for Apache is a third party module, and can be found at
-L<http://www.fastcgi.com/>. It is also packaged in many distributions,
-for example, libapache2-mod-fastcgi in Debian. You will also need to install
-the L<FCGI> module from cpan.
-
-Important Note! If you experience difficulty properly rendering pages,
-try disabling Apache's mod_deflate (Deflate Module), e.g. 'a2dismod deflate'.
-
-=head4 2. Configure your application
-
- # Serve static content directly
- DocumentRoot /var/www/MyApp/root
- Alias /static /var/www/MyApp/root/static
-
- FastCgiServer /var/www/MyApp/script/myapp_fastcgi.pl -processes 3
- Alias /myapp/ /var/www/MyApp/script/myapp_fastcgi.pl/
-
- # Or, run at the root
- Alias / /var/www/MyApp/script/myapp_fastcgi.pl/
-
-The above commands will launch 3 app processes and make the app available at
-/myapp/
-
-=head3 Standalone server mode
-
-While not as easy as the previous method, running your app as an external
-server gives you much more flexibility.
-
-First, launch your app as a standalone server listening on a socket.
-
- script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -p /tmp/myapp.pid -d
-
-You can also listen on a TCP port if your web server is not on the same
-machine.
-
- script/myapp_fastcgi.pl -l :8080 -n 5 -p /tmp/myapp.pid -d
-
-You will probably want to write an init script to handle starting/stopping
-of the app using the pid file.
-
-Now, we simply configure Apache to connect to the running server.
-
- # 502 is a Bad Gateway error, and will occur if the backend server is down
- # This allows us to display a friendly static page that says "down for
- # maintenance"
- Alias /_errors /var/www/MyApp/root/error-pages
- ErrorDocument 502 /_errors/502.html
-
- FastCgiExternalServer /tmp/myapp.fcgi -socket /tmp/myapp.socket
- Alias /myapp/ /tmp/myapp.fcgi/
-
- # Or, run at the root
- Alias / /tmp/myapp.fcgi/
-
-=head3 More Info
-
-L<Catalyst::Engine::FastCGI>.
-
-=head2 Development server deployment
-
-The development server is a mini web server written in perl. If you
-expect a low number of hits or you don't need mod_perl/FastCGI speed,
-you could use the development server as the application server with a
-lightweight proxy web server at the front. However, consider using
-L<Catalyst::Engine::HTTP::Prefork> for this kind of deployment instead, since
-it can better handle multiple concurrent requests without forking, or can
-prefork a set number of servers for improved performance.
-
-=head3 Pros
-
-As this is an application server setup, the pros are the same as
-FastCGI (with the exception of speed).
-It is also:
-
-=head4 Simple
-
-The development server is what you create your code on, so if it works
-here, it should work in production!
-
-=head3 Cons
-
-=head4 Speed
-
-Not as fast as mod_perl or FastCGI. Needs to fork for each request
-that comes in - make sure static files are served by the web server to
-save forking.
-
-=head3 Setup
-
-=head4 Start up the development server
-
- script/myapp_server.pl -p 8080 -k -f -pidfile=/tmp/myapp.pid
-
-You will probably want to write an init script to handle stop/starting
-the app using the pid file.
-
-=head4 Configuring Apache
-
-Make sure mod_proxy is enabled and add:
-
- # Serve static content directly
- DocumentRoot /var/www/MyApp/root
- Alias /static /var/www/MyApp/root/static
-
- ProxyRequests Off
- <Proxy *>
- Order deny,allow
- Allow from all
- </Proxy>
-
- # Need to specifically stop these paths from being passed to proxy
- ProxyPass /static !
- ProxyPass /favicon.ico !
-
- ProxyPass / http://localhost:8080/
- ProxyPassReverse / http://localhost:8080/
-
- # This is optional if you'd like to show a custom error page
- # if the proxy is not available
- ErrorDocument 502 /static/error_pages/http502.html
-
-You can wrap the above within a VirtualHost container if you want
-different apps served on the same host.
-
-=head2 Quick deployment: Building PAR Packages
-
-You have an application running on your development box, but then you
-have to quickly move it to another one for
-demonstration/deployment/testing...
-
-PAR packages can save you from a lot of trouble here. They are usual Zip
-files that contain a blib tree; you can even include all prereqs and a
-perl interpreter by setting a few flags!
-
-=head3 Follow these few points to try it out!
-
-1. Install Catalyst and PAR 0.89 (or later)
-
- % perl -MCPAN -e 'install Catalyst'
- ...
- % perl -MCPAN -e 'install PAR'
- ...
-
-2. Create a application
-
- % catalyst.pl MyApp
- ...
- % cd MyApp
-
-Recent versions of Catalyst (5.62 and up) include
-L<Module::Install::Catalyst>, which simplifies the process greatly. From the shell in your application directory:
-
- % perl Makefile.PL
- % make catalyst_par
-
-You can customise the PAR creation process by special "catalyst_par_*" commands
-available from L<Module::Install::Catalyst>. You can add these commands in your
-Makefile.PL just before the line containing "catalyst;"
-
- #Makefile.PL example with extra PAR options
- use inc::Module::Install;
-
- name 'MyApp';
- all_from 'lib\MyApp.pm';
-
- requires 'Catalyst::Runtime' => '5.80005';
- <snip>
- ...
- <snip>
-
- catalyst_par_core(1); # bundle perl core modules in the resulting PAR
- catalyst_par_multiarch(1); # build a multi-architecture PAR file
- catalyst_par_classes(qw/
- Some::Additional::Module
- Some::Other::Module
- /); # specify additional modules you want to be included into PAR
- catalyst;
-
- install_script glob('script/*.pl');
- auto_install;
- WriteAll;
-
-Congratulations! Your package "myapp.par" is ready, the following
-steps are just optional.
-
-3. Test your PAR package with "parl" (no typo)
-
- % parl myapp.par
- Usage:
- [parl] myapp[.par] [script] [arguments]
-
- Examples:
- parl myapp.par myapp_server.pl -r
- myapp myapp_cgi.pl
-
- Available scripts:
- myapp_cgi.pl
- myapp_create.pl
- myapp_fastcgi.pl
- myapp_server.pl
- myapp_test.pl
-
- % parl myapp.par myapp_server.pl
- You can connect to your server at http://localhost:3000
-
-Yes, this nifty little starter application gets automatically included.
-You can also use "catalyst_par_script('myapp_server.pl')" to set a
-default script to execute.
-
-6. Want to create a binary that includes the Perl interpreter?
-
- % pp -o myapp myapp.par
- % ./myapp myapp_server.pl
- You can connect to your server at http://localhost:3000
-
=head2 Serving static content
Serving static content in Catalyst used to be somewhat tricky; the use
You may of course want to change the default locations, and make
Static::Simple look somewhere else, this is as easy as:
- MyApp->config->{static}->{include_path} = [
- MyApp->config->{root},
- '/path/to/my/files'
- ];
+ MyApp->config(
+ static => {
+ include_path => [
+ MyApp->path_to('/'),
+ '/path/to/my/files',
+ ],
+ },
+ );
When you override include_path, it will not automatically append the
normal root path, so you need to add it yourself if you still want
If you want to force some directories to be only static, you can set
them using paths relative to the root dir, or regular expressions:
- MyApp->config->{static}->{dirs} = [
- 'static',
- qr/^(images|css)/,
- ];
+ MyApp->config(
+ static => {
+ dirs => [
+ 'static',
+ qr/^(images|css)/,
+ ],
+ },
+ );
=item File extensions
be processed by Catalyst): B<tmpl, tt, tt2, html, xhtml>. This list can
be replaced easily:
- MyApp->config->{static}->{ignore_extensions} = [
- qw/tmpl tt tt2 html xhtml/
- ];
+ MyApp->config(
+ static => {
+ ignore_extensions => [
+ qw/tmpl tt tt2 html xhtml/
+ ],
+ },
+ );
=item Ignoring directories
Entire directories can be ignored. If used with include_path,
directories relative to the include_path dirs will also be ignored:
- MyApp->config->{static}->{ignore_dirs} = [ qw/tmpl css/ ];
+ MyApp->config( static => {
+ ignore_dirs => [ qw/tmpl css/ ],
+ });
=back
You can even get that front-end Squid proxy to help out by enabling HTTP
headers for the cached page.
- MyApp->config->{page_cache}->{set_http_headers} = 1;
+ MyApp->config(
+ page_cache => {
+ set_http_headers => 1,
+ },
+ );
This would now set the following headers so proxies and browsers may cache
the content themselves.
You can wrap the above within a VirtualHost container if you want
different apps served on the same host.
-=head2 Quick deployment: Building PAR Packages
-
-You have an application running on your development box, but then you
-have to quickly move it to another one for
-demonstration/deployment/testing...
-
-PAR packages can save you from a lot of trouble here. They are usual Zip
-files that contain a blib tree; you can even include all prereqs and a
-perl interpreter by setting a few flags!
-
-=head3 Follow these few points to try it out!
-
-1. Install Catalyst and PAR 0.89 (or later)
-
- % perl -MCPAN -e 'install Catalyst'
- ...
- % perl -MCPAN -e 'install PAR'
- ...
-
-2. Create a application
-
- % catalyst.pl MyApp
- ...
- % cd MyApp
-
-Recent versions of Catalyst (5.62 and up) include
-L<Module::Install::Catalyst>, which simplifies the process greatly. From the shell in your application directory:
-
- % perl Makefile.PL
- % make catalyst_par
-
-You can customise the PAR creation process by special "catalyst_par_*" commands
-available from L<Module::Install::Catalyst>. You can add these commands in your
-Makefile.PL just before the line containing "catalyst;"
-
- #Makefile.PL example with extra PAR options
- use inc::Module::Install;
-
- name 'MyApp';
- all_from 'lib\MyApp.pm';
-
- requires 'Catalyst::Runtime' => '5.80005';
- <snip>
- ...
- <snip>
-
- catalyst_par_core(1); # bundle perl core modules in the resulting PAR
- catalyst_par_multiarch(1); # build a multi-architecture PAR file
- catalyst_par_classes(qw/
- Some::Additional::Module
- Some::Other::Module
- /); # specify additional modules you want to be included into PAR
- catalyst;
-
- install_script glob('script/*.pl');
- auto_install;
- WriteAll;
-
-Congratulations! Your package "myapp.par" is ready, the following
-steps are just optional.
-
-3. Test your PAR package with "parl" (no typo)
-
- % parl myapp.par
- Usage:
- [parl] myapp[.par] [script] [arguments]
-
- Examples:
- parl myapp.par myapp_server.pl -r
- myapp myapp_cgi.pl
-
- Available scripts:
- myapp_cgi.pl
- myapp_create.pl
- myapp_fastcgi.pl
- myapp_server.pl
- myapp_test.pl
-
- % parl myapp.par myapp_server.pl
- You can connect to your server at http://localhost:3000
-
-Yes, this nifty little starter application gets automatically included.
-You can also use "catalyst_par_script('myapp_server.pl')" to set a
-default script to execute.
-
-6. Want to create a binary that includes the Perl interpreter?
-
- % pp -o myapp myapp.par
- % ./myapp myapp_server.pl
- You can connect to your server at http://localhost:3000
-
-=head2 Serving static content
-
-Serving static content in Catalyst used to be somewhat tricky; the use
-of L<Catalyst::Plugin::Static::Simple> makes everything much easier.
-This plugin will automatically serve your static content during development,
-but allows you to easily switch to Apache (or other server) in a
-production environment.
-
-=head3 Introduction to Static::Simple
-
-Static::Simple is a plugin that will help to serve static content for your
-application. By default, it will serve most types of files, excluding some
-standard Template Toolkit extensions, out of your B<root> file directory. All
-files are served by path, so if B<images/me.jpg> is requested, then
-B<root/images/me.jpg> is found and served.
-
-=head3 Usage
-
-Using the plugin is as simple as setting your use line in MyApp.pm to include:
-
- use Catalyst qw/Static::Simple/;
-
-and already files will be served.
-
-=head3 Configuring
-
-Static content is best served from a single directory within your root
-directory. Having many different directories such as C<root/css> and
-C<root/images> requires more code to manage, because you must separately
-identify each static directory--if you decide to add a C<root/js>
-directory, you'll need to change your code to account for it. In
-contrast, keeping all static directories as subdirectories of a main
-C<root/static> directory makes things much easier to manage. Here's an
-example of a typical root directory structure:
-
- root/
- root/content.tt
- root/controller/stuff.tt
- root/header.tt
- root/static/
- root/static/css/main.css
- root/static/images/logo.jpg
- root/static/js/code.js
-
-
-All static content lives under C<root/static>, with everything else being
-Template Toolkit files.
-
-=over 4
-
-=item Include Path
-
-You may of course want to change the default locations, and make
-Static::Simple look somewhere else, this is as easy as:
-
- MyApp->config->{static}->{include_path} = [
- MyApp->config->{root},
- '/path/to/my/files'
- ];
-
-When you override include_path, it will not automatically append the
-normal root path, so you need to add it yourself if you still want
-it. These will be searched in order given, and the first matching file
-served.
-
-=item Static directories
-
-If you want to force some directories to be only static, you can set
-them using paths relative to the root dir, or regular expressions:
-
- MyApp->config->{static}->{dirs} = [
- 'static',
- qr/^(images|css)/,
- ];
-
-=item File extensions
-
-By default, the following extensions are not served (that is, they will
-be processed by Catalyst): B<tmpl, tt, tt2, html, xhtml>. This list can
-be replaced easily:
-
- MyApp->config->{static}->{ignore_extensions} = [
- qw/tmpl tt tt2 html xhtml/
- ];
-
-=item Ignoring directories
-
-Entire directories can be ignored. If used with include_path,
-directories relative to the include_path dirs will also be ignored:
-
- MyApp->config->{static}->{ignore_dirs} = [ qw/tmpl css/ ];
-
-=back
-
-=head3 More information
-
-L<http://search.cpan.org/dist/Catalyst-Plugin-Static-Simple/>
-
-=head3 Serving manually with the Static plugin with HTTP::Daemon (myapp_server.pl)
-
-In some situations you might want to control things more directly,
-using L<Catalyst::Plugin::Static>.
-
-In your main application class (MyApp.pm), load the plugin:
-
- use Catalyst qw/-Debug FormValidator Static OtherPlugin/;
-
-You will also need to make sure your end method does I<not> forward
-static content to the view, perhaps like this:
-
- sub end : Private {
- my ( $self, $c ) = @_;
-
- $c->forward( 'MyApp::View::TT' )
- unless ( $c->res->body || !$c->stash->{template} );
- }
-
-This code will only forward to the view if a template has been
-previously defined by a controller and if there is not already data in
-C<$c-E<gt>res-E<gt>body>.
-
-Next, create a controller to handle requests for the /static path. Use
-the Helper to save time. This command will create a stub controller as
-C<lib/MyApp/Controller/Static.pm>.
-
- $ script/myapp_create.pl controller Static
-
-Edit the file and add the following methods:
-
- # serve all files under /static as static files
- sub default : Path('/static') {
- my ( $self, $c ) = @_;
-
- # Optional, allow the browser to cache the content
- $c->res->headers->header( 'Cache-Control' => 'max-age=86400' );
-
- $c->serve_static; # from Catalyst::Plugin::Static
- }
-
- # also handle requests for /favicon.ico
- sub favicon : Path('/favicon.ico') {
- my ( $self, $c ) = @_;
-
- $c->serve_static;
- }
-
-You can also define a different icon for the browser to use instead of
-favicon.ico by using this in your HTML header:
-
- <link rel="icon" href="/static/myapp.ico" type="image/x-icon" />
-
-=head3 Common problems with the Static plugin
-
-The Static plugin makes use of the C<shared-mime-info> package to
-automatically determine MIME types. This package is notoriously
-difficult to install, especially on win32 and OS X. For OS X the easiest
-path might be to install Fink, then use C<apt-get install
-shared-mime-info>. Restart the server, and everything should be fine.
-
-Make sure you are using the latest version (>= 0.16) for best
-results. If you are having errors serving CSS files, or if they get
-served as text/plain instead of text/css, you may have an outdated
-shared-mime-info version. You may also wish to simply use the following
-code in your Static controller:
-
- if ($c->req->path =~ /css$/i) {
- $c->serve_static( "text/css" );
- } else {
- $c->serve_static;
- }
-
-=head3 Serving Static Files with Apache
-
-When using Apache, you can bypass Catalyst and any Static
-plugins/controllers controller by intercepting requests for the
-C<root/static> path at the server level. All that is required is to
-define a DocumentRoot and add a separate Location block for your static
-content. Here is a complete config for this application under mod_perl
-1.x:
-
- <Perl>
- use lib qw(/var/www/MyApp/lib);
- </Perl>
- PerlModule MyApp
-
- <VirtualHost *>
- ServerName myapp.example.com
- DocumentRoot /var/www/MyApp/root
- <Location />
- SetHandler perl-script
- PerlHandler MyApp
- </Location>
- <LocationMatch "/(static|favicon.ico)">
- SetHandler default-handler
- </LocationMatch>
- </VirtualHost>
-
-And here's a simpler example that'll get you started:
-
- Alias /static/ "/my/static/files/"
- <Location "/static">
- SetHandler none
- </Location>
-
-=head2 Caching
-
-Catalyst makes it easy to employ several different types of caching to
-speed up your applications.
-
-=head3 Cache Plugins
-
-There are three wrapper plugins around common CPAN cache modules:
-Cache::FastMmap, Cache::FileCache, and Cache::Memcached. These can be
-used to cache the result of slow operations.
-
-The Catalyst Advent Calendar uses the FileCache plugin to cache the
-rendered XHTML version of the source POD document. This is an ideal
-application for a cache because the source document changes
-infrequently but may be viewed many times.
-
- use Catalyst qw/Cache::FileCache/;
-
- ...
-
- use File::stat;
- sub render_pod : Local {
- my ( self, $c ) = @_;
-
- # the cache is keyed on the filename and the modification time
- # to check for updates to the file.
- my $file = $c->path_to( 'root', '2005', '11.pod' );
- my $mtime = ( stat $file )->mtime;
-
- my $cached_pod = $c->cache->get("$file $mtime");
- if ( !$cached_pod ) {
- $cached_pod = do_slow_pod_rendering();
- # cache the result for 12 hours
- $c->cache->set( "$file $mtime", $cached_pod, '12h' );
- }
- $c->stash->{pod} = $cached_pod;
- }
-
-We could actually cache the result forever, but using a value such as 12 hours
-allows old entries to be automatically expired when they are no longer needed.
-
-=head3 Page Caching
-
-Another method of caching is to cache the entire HTML page. While this is
-traditionally handled by a front-end proxy server like Squid, the Catalyst
-PageCache plugin makes it trivial to cache the entire output from
-frequently-used or slow actions.
-
-Many sites have a busy content-filled front page that might look something
-like this. It probably takes a while to process, and will do the exact same
-thing for every single user who views the page.
-
- sub front_page : Path('/') {
- my ( $self, $c ) = @_;
-
- $c->forward( 'get_news_articles' );
- $c->forward( 'build_lots_of_boxes' );
- $c->forward( 'more_slow_stuff' );
-
- $c->stash->{template} = 'index.tt';
- }
-
-We can add the PageCache plugin to speed things up.
-
- use Catalyst qw/Cache::FileCache PageCache/;
-
- sub front_page : Path ('/') {
- my ( $self, $c ) = @_;
-
- $c->cache_page( 300 );
-
- # same processing as above
- }
-
-Now the entire output of the front page, from <html> to </html>, will be
-cached for 5 minutes. After 5 minutes, the next request will rebuild the
-page and it will be re-cached.
-
-Note that the page cache is keyed on the page URI plus all parameters, so
-requests for / and /?foo=bar will result in different cache items. Also,
-only GET requests will be cached by the plugin.
-
-You can even get that front-end Squid proxy to help out by enabling HTTP
-headers for the cached page.
-
- MyApp->config->{page_cache}->{set_http_headers} = 1;
-
-This would now set the following headers so proxies and browsers may cache
-the content themselves.
-
- Cache-Control: max-age=($expire_time - time)
- Expires: $expire_time
- Last-Modified: $cache_created_time
-
-=head3 Template Caching
-
-Template Toolkit provides support for caching compiled versions of your
-templates. To enable this in Catalyst, use the following configuration.
-TT will cache compiled templates keyed on the file mtime, so changes will
-still be automatically detected.
-
- package MyApp::View::TT;
-
- use strict;
- use warnings;
- use base 'Catalyst::View::TT';
-
- __PACKAGE__->config(
- COMPILE_DIR => '/tmp/template_cache',
- );
-
- 1;
-
-=head3 More Info
-
-See the documentation for each cache plugin for more details and other
-available configuration options.
-
-L<Catalyst::Plugin::Cache::FastMmap>
-L<Catalyst::Plugin::Cache::FileCache>
-L<Catalyst::Plugin::Cache::Memcached>
-L<Catalyst::Plugin::PageCache>
-L<http://search.cpan.org/dist/Template-Toolkit/lib/Template/Manual/Config.pod#Caching_and_Compiling_Options>
-
-=head1 Testing
-
-Testing is an integral part of the web application development
-process. Tests make multi developer teams easier to coordinate, and
-they help ensure that there are no nasty surprises after upgrades or
-alterations.
-
-=head2 Testing
-
-Catalyst provides a convenient way of testing your application during
-development and before deployment in a real environment.
-
-C<Catalyst::Test> makes it possible to run the same tests both locally
-(without an external daemon) and against a remote server via HTTP.
-
-=head3 Tests
-
-Let's examine a skeleton application's C<t/> directory:
-
- mundus:~/MyApp chansen$ ls -l t/
- total 24
- -rw-r--r-- 1 chansen chansen 95 18 Dec 20:50 01app.t
- -rw-r--r-- 1 chansen chansen 190 18 Dec 20:50 02pod.t
- -rw-r--r-- 1 chansen chansen 213 18 Dec 20:50 03podcoverage.t
-
-=over 4
-
-=item C<01app.t>
-
-Verifies that the application loads, compiles, and returns a successful
-response.
-
-=item C<02pod.t>
-
-Verifies that all POD is free from errors. Only executed if the C<TEST_POD>
-environment variable is true.
-
-=item C<03podcoverage.t>
-
-Verifies that all methods/functions have POD coverage. Only executed if the
-C<TEST_POD> environment variable is true.
-
-=back
-
-=head3 Creating tests
-
- mundus:~/MyApp chansen$ cat t/01app.t | perl -ne 'printf( "%2d %s", $., $_ )'
- 1 use Test::More tests => 2;
- 2 BEGIN { use_ok( Catalyst::Test, 'MyApp' ) }
- 3
- 4 ok( request('/')->is_success );
-
-The first line declares how many tests we are going to run, in this case
-two. The second line tests and loads our application in test mode. The
-fourth line verifies that our application returns a successful response.
-
-C<Catalyst::Test> exports two functions, C<request> and C<get>. Each can
-take three different arguments:
-
-=over 4
-
-=item A string which is a relative or absolute URI.
-
- request('/my/path');
- request('http://www.host.com/my/path');
-
-=item An instance of C<URI>.
-
- request( URI->new('http://www.host.com/my/path') );
-
-=item An instance of C<HTTP::Request>.
-
- request( HTTP::Request->new( GET => 'http://www.host.com/my/path') );
-
-=back
-
-C<request> returns an instance of C<HTTP::Response> and C<get> returns the
-content (body) of the response.
-
-=head3 Running tests locally
-
- mundus:~/MyApp chansen$ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib/ t/
- t/01app............ok
- t/02pod............ok
- t/03podcoverage....ok
- All tests successful.
- Files=3, Tests=4, 2 wallclock secs ( 1.60 cusr + 0.36 csys = 1.96 CPU)
-
-C<CATALYST_DEBUG=0> ensures that debugging is off; if it's enabled you
-will see debug logs between tests.
-
-C<TEST_POD=1> enables POD checking and coverage.
-
-C<prove> A command-line tool that makes it easy to run tests. You can
-find out more about it from the links below.
-
-=head3 Running tests remotely
-
- mundus:~/MyApp chansen$ CATALYST_SERVER=http://localhost:3000/ prove --lib lib/ t/01app.t
- t/01app....ok
- All tests successful.
- Files=1, Tests=2, 0 wallclock secs ( 0.40 cusr + 0.01 csys = 0.41 CPU)
-
-C<CATALYST_SERVER=http://localhost:3000/> is the absolute deployment URI of
-your application. In C<CGI> or C<FastCGI> it should be the host and path
-to the script.
-
-=head3 C<Test::WWW::Mechanize> and Catalyst
-
-Be sure to check out C<Test::WWW::Mechanize::Catalyst>. It makes it easy to
-test HTML, forms and links. A short example of usage:
-
- use Test::More tests => 6;
- BEGIN { use_ok( Test::WWW::Mechanize::Catalyst, 'MyApp' ) }
-
- my $mech = Test::WWW::Mechanize::Catalyst->new;
- $mech->get_ok("http://localhost/", 'Got index page');
- $mech->title_like( qr/^MyApp on Catalyst/, 'Got right index title' );
- ok( $mech->find_link( text_regex => qr/^Wiki/i ), 'Found link to Wiki' );
- ok( $mech->find_link( text_regex => qr/^Mailing-List/i ), 'Found link to Mailing-List' );
- ok( $mech->find_link( text_regex => qr/^IRC channel/i ), 'Found link to IRC channel' );
-
-=head3 Further Reading
-
-=over 4
-
-=item Catalyst::Test
-
-L<Catalyst::Test>
-
-=item Test::WWW::Mechanize::Catalyst
-
-L<http://search.cpan.org/dist/Test-WWW-Mechanize-Catalyst/lib/Test/WWW/Mechanize/Catalyst.pm>
-
-=item Test::WWW::Mechanize
-
-L<http://search.cpan.org/dist/Test-WWW-Mechanize/Mechanize.pm>
-
-=item WWW::Mechanize
-
-L<http://search.cpan.org/dist/WWW-Mechanize/lib/WWW/Mechanize.pm>
-
-=item LWP::UserAgent
-
-L<http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm>
-
-=item HTML::Form
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTML/Form.pm>
-
-=item HTTP::Message
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Message.pm>
-
-=item HTTP::Request
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request.pm>
-
-=item HTTP::Request::Common
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Request/Common.pm>
-
-=item HTTP::Response
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Response.pm>
-
-=item HTTP::Status
-
-L<http://search.cpan.org/dist/libwww-perl/lib/HTTP/Status.pm>
-
-=item URI
-
-L<http://search.cpan.org/dist/URI/URI.pm>
-
-=item Test::More
-
-L<http://search.cpan.org/dist/Test-Simple/lib/Test/More.pm>
-
-=item Test::Pod
-
-L<http://search.cpan.org/dist/Test-Pod/Pod.pm>
-
-=item Test::Pod::Coverage
-
-L<http://search.cpan.org/dist/Test-Pod-Coverage/Coverage.pm>
-
-=item prove (Test::Harness)
-
-L<http://search.cpan.org/dist/Test-Harness/bin/prove>
-
-=back
-
-=head3 More Information
-
-L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::Roles>
-L<http://search.cpan.org/perldoc?Catalyst::Plugin::Authorization::ACL>
-
=head1 AUTHORS
Catalyst Contributors, see Catalyst.pm
the same terms as Perl itself.
=cut
+
=item * B<Overriding the namespace>
-Note that __PACKAGE__->config->{namespace} can be used to override the
+Note that I<< __PACKAGE__->config->(namespace => ... ) >> can be used to override the
current namespace when matching. So:
package MyApp::Controller::Example;
would normally use 'example' as its namespace for matching, but if
this is specially overridden with
- __PACKAGE__->config->{namespace}='thing';
+ __PACKAGE__->config( namespace => 'thing' );
it matches using the namespace 'thing' instead.
use base 'Catalyst::Controller';
# Sets the actions in this controller to be registered with no prefix
# so they function identically to actions created in MyApp.pm
- __PACKAGE__->config->{namespace} = '';
+ __PACKAGE__->config( namespace => '');
sub default : Path {
my ( $self, $context ) = @_;
$context->response->status(404);
The code
- __PACKAGE__->config->{namespace} = '';
+ __PACKAGE__->config( namespace => '' );
makes the controller act as if its namespace is empty. As you'll see
below, an empty namespace makes many of the URL-matching attributes,
namespace as described above.
package MyApp::Controller::Root;
- __PACKAGE__->config->{namespace}='';
+ __PACKAGE__->config( namespace => '');
sub foo : Local { }
Use whichever makes the most sense for your application.
C<__PACKAGE__-E<gt>setup();>:
# Configure SimpleDB Authentication
- __PACKAGE__->config->{'Plugin::Authentication'} = {
+ __PACKAGE__->config(
+ 'Plugin::Authentication' => {
default => {
class => 'SimpleDB',
user_model => 'DB::User',
password_type => 'clear',
},
- };
+ },
+ );
We could have placed this configuration in C<myapp.conf>, but placing
it in C<lib/MyApp.pm> is probably a better place since it's not likely
only change is to the C<password_type> field):
# Configure SimpleDB Authentication
- __PACKAGE__->config->{'Plugin::Authentication'} = {
+ __PACKAGE__->config(
+ 'Plugin::Authentication' => {
default => {
class => 'SimpleDB',
user_model => 'DB::User',
password_type => 'self_check',
},
- };
+ },
+ );
The use of C<self_check> will cause
Catalyst::Plugin::Authentication::Store::DBIC to call the