# NAME Prancer # SYNOPSIS When using as part of a web application: ===> foobar.yml session: state: driver: Prancer::Session::State::Cookie options: session_key: PSESSION store: driver: Prancer::Session::Store::Storable options: dir: /tmp/prancer/sessions static: path: /static dir: /srv/www/resources ===> myapp.psgi #!/usr/bin/env perl use strict; use warnings; use Plack::Runner; # this just returns a PSGI application. $x can be wrapped with additional # middleware before sending it along to Plack::Runner. my $x = MyApp->new("/path/to/foobar.yml")->to_psgi_app(); # run the psgi app through Plack and send it everything from @ARGV. this # way Plack::Runner will get options like what listening port to use and # application server to use -- Starman, Twiggy, etc. my $runner = Plack::Runner->new(); $runner->parse_options(@ARGV); $runner->run($x); ===> MyApp.pm package MyApp; use strict; use warnings; use Prancer qw(config); sub initialize { my $self = shift; # in here we can initialize things like plugins # but this method is not required to be implemented return; } sub handler { my ($self, $env, $request, $response, $session) = @_; sub (GET + /) { $response->header("Content-Type" => "text/plain"); $response->body("Hello, world!"); return $response->finalize(200); }, sub (GET + /foo) { $response->header("Content-Type" => "text/plain"); $response->body(sub { my $writer = shift; $writer->write("Hello, world!"); $writer->close(); return; }); } } 1; If you save the above snippet as `myapp.psgi` and run it like this: plackup myapp.psgi You will get "Hello, world!" in your browser. Or you can use Prancer as part of a standalone command line application: #!/usr/bin/env perl use strict; use warnings; use Prancer::Core qw(config); # the advantage to using Prancer in a standalone application is the ability # to use a standard configuration and to load plugins for things like # loggers and database connectors and template engines. my $x = Prancer::Core->new("/path/to/foobar.yml"); print "Hello, world!; # DESCRIPTION Prancer is yet another PSGI framework that provides routing and session management as well as plugins for logging, database access, and template engines. It does this by wrapping [Web::Simple](https://metacpan.org/pod/Web::Simple) to handle routing and by wrapping other libraries to bring easy access to things that need to be done in web applications. There are two parts to using Prancer for a web application: a package to contain your application and a script to call your application. Both are necessary. The package containing your application should contain a line like this: use Prancer; This modifies your application package such that it inherits from Prancer. It also means that your package must implement the `handler` method and optionally implement the `initialize` method. As Prancer inherits from Web::Simple it will also automatically enable the `strict` and `warnings` pragmas. As mentioned, putting `use Prancer;` at the top of your package will require you to implement the `handler` method, like this: sub handler { my ($self, $env, $request, $response, $session) = @_; # routing goes in here. # see Web::Simple for documentation on writing routing rules. sub (GET + /) { $response->header("Content-Type" => "text/plain"); $response->body("Hello, world!"); return $response->finalize(200); } } The `$request` variable is a [Prancer::Request](https://metacpan.org/pod/Prancer::Request) object. The `$response` variable is a [Prancer::Response](https://metacpan.org/pod/Prancer::Response) object. The `$session` variable is a [Prancer::Session](https://metacpan.org/pod/Prancer::Session) object. If there is no configuration for sessions in any of your configuration files then `$session` will be `undef`. You may implement your own `new` method in your application but you **MUST** call `$class->SUPER::new(@_);` to get the configuration file loaded and any methods exported. As an alternative to implemeting `new` and remembering to call `SUPER::new`, Prancer will make a call to `->initialize` at the end of its own implementation of `new` so things that you might put in `new` can instead be put into `initialize`, like this: sub initialize { my $self = shift; # this is where you can initialize things when your package is created return; } By default, Prancer does not export anything into your package's namespace. However, that doesn't mean that there is not anything that it _could_ export were one to ask: use Prancer qw(config); Importing `config` will make the keyword `config` available which gives access to any configuration options loaded by Prancer. The second part of the Prancer equation is the script that creates and calls your package. This can be a pretty small and standard little script, like this: my $myapp = MyApp->new("/path/to/foobar.yml") my $psgi = $myapp->to_psgi_app(); `$myapp` is just an instance of your package. You can pass to `new` either one specific configuration file or a directory containing lots of configuration files. The functionality is documented in `Prancer::Config`. `$psgi` is just a PSGI app that you can send to [Plack::Runner](https://metacpan.org/pod/Plack::Runner) or whatever you use to run PSGI apps. You can also wrap middleware around `$app`. my $psgi = $myapp->to_psgi_app(); $psgi = Plack::Middleware::Runtime->wrap($psgi); # CONFIGURATION Prancer needs a configuration file. Ok, it doesn't _need_ a configuration file file. By default, Prancer does not require any configuration. But it is less useful without one. You _could_ always create your application like this: my $app = MyApp->new->to_psgi_app(); How Prancer loads configuration files is documented in [Prancer::Config](https://metacpan.org/pod/Prancer::Config). Anything you put into your configuration file is available to your application. There are two special configuration keys reserved by Prancer. The key `session` will configure Prancer's session as documented in [Prancer::Session](https://metacpan.org/pod/Prancer::Session). The key `static` will configure static file loading through [Plack::Middleware::Static](https://metacpan.org/pod/Plack::Middleware::Static). To configure static file loading you can add this to your configuration file: static: path: /static dir: /path/to/my/resources The `dir` option is required to indicate the root directory for your static resources. The `path` option indicates the web path to link to your static resources. If no path is not provided then static files can be accessed under `/static` by default. # CREDITS This module could have been written except on the shoulders of the following giants: - The name "Prancer" is a riff on the popular PSGI framework [Dancer](https://metacpan.org/pod/Dancer) and [Dancer2](https://metacpan.org/pod/Dancer2). [Prancer::Config](https://metacpan.org/pod/Prancer::Config) is derived directly from [Dancer2::Core::Role::Config](https://metacpan.org/pod/Dancer2::Core::Role::Config). Thank you to the Dancer/Dancer2 teams. - [Prancer::Database](https://metacpan.org/pod/Prancer::Database) is derived from [Dancer::Plugin::Database](https://metacpan.org/pod/Dancer::Plugin::Database). Thank you to David Precious. - [Prancer::Request](https://metacpan.org/pod/Prancer::Request), [Prancer::Request::Upload](https://metacpan.org/pod/Prancer::Request::Upload), [Prancer::Response](https://metacpan.org/pod/Prancer::Response), [Prancer::Session](https://metacpan.org/pod/Prancer::Session) and the session packages are but thin wrappers with minor modifications to [Plack::Request](https://metacpan.org/pod/Plack::Request), [Plack::Request::Upload](https://metacpan.org/pod/Plack::Request::Upload), [Plack::Response](https://metacpan.org/pod/Plack::Response), and [Plack::Middleware::Session](https://metacpan.org/pod/Plack::Middleware::Session). Thank you to Tatsuhiko Miyagawa. - The entire routing functionality of this module is offloaded to [Web::Simple](https://metacpan.org/pod/Web::Simple). Thank you to Matt Trout for some great code that I am able to easily leverage. # COPYRIGHT Copyright 2013, 2014 Paul Lockaby. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. # SEE ALSO - [Plack](https://metacpan.org/pod/Plack) - [Web::Simple](https://metacpan.org/pod/Web::Simple)