Mojo and Mojolicious Handbook
This is an alternative, temporary documentation resource for Mojolicious, a fast and light stand-alone perl Model-View-Controller framework. It is meant as a temporary stand-in and resource for Mojolicious::Guides - Mojolicious Guide To The Galaxy.
A MVC web framework provides application interfaces for web server and client interaction, content generation services and data models. Its design is centered on the concept of separation of concerns, making it easy to deal with the data, the logic and the presentation separately instead of mixing data, code and web page bits into an indigestible soup.
To summarize the mission of Mojolicious as a modern perl MVC web framework, it is best to start with a quote from Sebastiean Riedel, the author of Mojo and Mojolicious:
Back in the early days of the web there was this wonderful Perl library called CGI, many people only learned Perl because of it. [...] Mojolicious is a new attempt at implementing this idea using state of the art technology.
Mojolicious is not only a fast and light alternative but full-featured web MVC frameworks, it offers a "lite" mode that makes developing web tools and replacing existing CGI scripts a breeze.
It is as simple (or simpler) to deploy as CGI.pm
and has no out-of-perl-core dependencies but can use certain features provided by add-on modules from CPAN if they are install. It also offers scaffolding (generation of application files from templates) to make starting a new project even easier.
Mojolicious can be deployed as a stand-alone server, CGI
or FCGI
application, Apache mod_perl
handler, a PSGI application etc., and it offers support for all the basic elements of modern dynamic web programming: serving of static files, dispatching requests from an URL to a controller (application class) and action (application method) using routes and building responses with an advanced built-in templating system (or any other templating system of your choice).
You should install the Mojolicious framework and use the supplied documentation and commands to learn and experiment while reading this handbook. You can use the last release on CPAN:
$ sudo cpanp install Mojolicious
If you want to use the latest version, however, installing from the source repository is better:
$ git clone git://github.com/kraih/mojo.git
$ cd mojo
$ perl Makefile.PL
$ make && make test && sudo make install
You can try out the framework by modifying the example application provided by the generate
command. Simply type this on the command line:
$ mojolicious generate lite_app ml_test
$ ./mltest daemon --reload
$ <web-broser-of-choce> http://localhost:3000/
$ <edit code and reload page, server auto-reloads when you save chages>
When you are ready to look at a full application, you can extract the components of the script with the inflate
command or start a new project with full-blown scaffolding and interace:
$ ./mltest inflate
or
$ mojolicious generate app MyTest
$ cd MyTest
$ ./script/mytest daemon --reload
Mojolicious is currently (2010) under rapid development, so you want to keep with the action and update your installation and your application.
If you are using CPAN, this should update you to the last CPAN release:
$ sudo cpanp install Mojolicious
If you installed from GitHub, this is a quick way to update:
$ cd <path-to>/mojo
$ git pull
$ make clean
$ perl Makefile.PL
$ make && make test && sudo make install
(If you have deleted the clone of the repository, simply repeat the installation procedure.)
Read ahead for more ...
While using the Mojolicious documentation, it is worth keeping in mind the following facts:
Most of the manual pages in the distribution are reference-only: they do not describe the framework and how to use it, but the interfaces (APIs) and implementation details for developers. They are for people who can follow the code. Notable exceptions are Mojolicious::Lite, which includes a tutorial, and Mojolicious:Guides, the end-user documentation, which is quite usable at this time (2010), but still being written.
Using concise style, arguments and return values are implied in the example provided:
my $encoding = $renderer->encoding; $renderer = $renderer->encoding('koi8-r');
This example means that calling the
encoding
method on a renderer object with no arguments will return the current encoding, but with an argument will set the value and return the renderer again.In fact, this is the usual method interface in Mojolicious since it allows chaining method calls on the object and avoids returning a value you should probably already have. If you want the traditional approach where a set method returns the value set, you can always do:
my $encoding = $renderer->encoding('koi8-r')->encoding;
See also Mojolicious on CPAN (http://search.cpan.org/~kraih/Mojolicious/), Mojolicious home at http://www.mojolicious.org/ and Sebastian Riedel's site at http://labs.kraih.com/.
There are also presentation slides in English by Anatoly Sharifulin http://www.slideshare.net/sharifulin/mojolicious-the-web-in-a-box.
You should look at some end user documentation and essential reference in
Mojolicious
distribution:- Mojolicious::Lite
-
Introduction to the simplified application interfaces with full examples.
- Mojolicious::Guides
-
The end-user documentation. See Mojolicious::Guides::Routing for documentation and examples for the use of Mojolicious and " routing, see for rendering and templating documentation and examples. contains many recipies, manly for deplayment in different environments, and is a must if you want to be ready to deploy your application. See for a concise reference on reserved stash values and environement variables used by the framework."
- Mojolicious::Commands
-
Command-line interface, but command-line commands also give help by appending a 'help' to the commandline.
- Mojo::Template, Mojolicious::Plugin::EpRenderer
-
Templating subsystem, see Mojolicious::Guides::Rendering first.
- MojoX::Routes
-
See SYNOPSIS for examples and syntax after reading Mojolicious::Guides::Routing.
It is well worth to read and understand the reference manual page of Mojo::Base, the base class for Mojo/Mojolicious projects that provides the general
new
method and highly optimized attributes for Mojo objects, and Mojo::ByteStream with its versatile portable text and bytestream manipulation functions and the simplifiedb()
syntax.Full examples, blogs and other resources:
- Bootylicious
-
A one-file blog engine on Mojolicious: http://getbootylicious.org/
- Showmetheco.de blog
-
vti
's blog: http://vti.showmetheco.de/ - Pastelicious
-
A simple nopaste service build as a
Mojolicious::Lite
application: http://showmetheco.de/ - v6test
-
A IPv6 stack testing application with a NoSQL back-end (quite heavy-weight, using KiokuDB, an object-graph store engine built on Moose, to access mongoDB): http://www.v6test.develooper.com/couch
Mojolicious is composed of a full HTTP 1.1 Client/Server framework and basic application framework building functionality in the Mojo
namespace, a number of advanced services that compose the core of Mojolicious
framework in MojoX
namespace and the framework itself with its default and "lite" bindings in Mojolicious
namespace.
The presentation here is very simplified and presented from the point of view of the application programmer, with as little detail on the server/implementation side as possible. See "COMPONENTS OF MOJOLICIOUS" for a more detailed description.
The HTTP Server is the starting point of the application. For each HTTP request, it creates a Mojo::Transaction object, usually referred to as tx
, with two Mojo::Message objects as attributes req
and res
, for request and response. The two objects encapsulate the whole complexity of HTTP requests, including headers, contents with their MIME types and encodings, upload files, body (POST) and path (REST) parameters, cookies etc.
When the request part of the transaction is processed sufficiently, the server calls the transaction handler method of the application (called simply handler
). The application is now free to process the request and build a suitable response, for example a web page, an error code or a redirect. This is a flexible base on top of which any web framework can be built, and Mojolicious is one such framework built on top of Mojo HTTP 1.1 stack and a number of MojoX extensions.
A Mojolicious application essentially subclasses Mojolicious, providing setup code in the method startup
to be called once at startup of every application instance, while most of the Mojolicious functionality and defaults (default controllers, MIME type database) is set up in the object creation method new
and can be accessed via the application object.
The start script sets the application namespace (in $ENV{MOJO_APP}
) and passes control to the server, which in turn calls the handle
method for every successfully constructed transaction request and processes the transaction in the following steps:
load session, if there is one
run the application's static dispatcher, by default for
public/
run the application's routes dispatcher, using routes set up in
setup()
[by dispatcher] run the application's controller::action, if found by routes dispatcher
[by controller] perform application logic, setting values in
$stash
[by controller] call render(), using renderer, stash and templates to construct the response
process errors and not-found states
store session state
The routes dispatcher is where most of the application is connected: the dispatcher will find the best match for request URI and select a controller and an action (a class and a method in your application.
In the case of example application as produced by generate app
$r->route('/:controller/:action/:id')->to('example#welcome', id => 1)
calls
<app_name>::Example->welcome()
The path data and additional context are all stored in $stash
, a hash used for transaction-specific non persistent data storage and exchange, and made accessible to your application controller to performs whatever functions needed and store more data on the stash.
It is your controller's job to implement any connections with external data sources (the "model" from MVC paradigm). If you need any start-up initialization, you can perform it in the application's startup()
method.
The last stage in the pipeline is to convey the results back to the HTTP stash: the process is called rendering. Your controller can render directly, using either render_text()
or render_data
(where the MIME type has to be set XXX), but most often the built-in renderer MojoX::Renderer will be used and data will be passed to it using the stash.
The renderer by default tries to use a template called <controller>/<action>
, so <example/welcome>
in this case. The file has two extensions: the first is the format of the result (ie. html
), and will be used to select the correct MIME-type, while the second is the format of the template (by default .ep
). The format extensions is processed by looking up a list of "handlers", usually provided by plugins, and by default including .txt
, .ep
, .epl
, .json
and .pod
.
Most of the time, the layout is in the Mojoliciuos built-in .ep
format, which is small, fast and versatile, but fully described "RENDERERS AND TEMPLATES". It has many features, including helpers that can provide additional services, such as translation.
After the renderer is finished, the control is passed back to the HTTP stack and it serves the response to the client.
Complicated? It looks much simpler when you are writing an application, since all of this complexity is abstracted away and safely kept behind defaults. All you need to do is set up your routes and write your controllers/actions, models and views (templates).
Dispatching is the process of mapping the HTTP request to a specific action an executing that action to satisfy the request. This can be achieved simply by finding and serving the correct file - what we call static dispatching - or by finding and calling the correct method in the application.
In Mojolicious, the two approaches are implemented as static and routes dispatcher and the framework in fact attempts a static dispatch for each request, only trying a routes dispatch if it cannot satisfy the reqeuest simply with a file.
MojoX::Dispatcher::Static
Routes and under in Mojolicious::Lite
Automation, controller/methods
Ladders
Existing dispatchers, writing your own dispatcher
XXX This should contain user documentation on controller and action writing, and simple rendering (render_text()
, render_data()
), except more complicated things, such as models.
Forget-me-not: stash, parameters
->url_for()
and ->redirect_to()
Details, gotchas
Implementing stuff on that
XXX This should contain user documentation on rendering with .ep and .epl, statsh interaction, mime types for layouts and results, helpers and handlers, additional renderes etc.
render_text() for binary data
XXX using files from controllers or renderers, not static dispatching
uploads
as data, dispatching is covered in a previous section!
mime types
encodings
issues with locking and updating
Mojolicious is not designed with any particular data model in mind. Perl currently has a number of ORM (object-relational-mapping) implementations, ie. DBIx::Class, Class::DBI, Rose::DB::Object, ObjectDB, and you can use other kinds of models, such as DB::CouchDB, tied variables, flat file storage/retrieval etc.
Without setting any preference or precedence, we will use DBIx::Class with a SQLite
for backend to present working examples.
In a MVC implementation, the usual structure of the application isolates the three components as much as possible to ensure separation of concerns (ie. clean interfaces) and to make it easier to change one component of the application. In addition, most models based on existing ORM layers make changing the backend implementation (the database used) very simple, providing even more flexibility to your application.
The controller is what the majority of the Mojolicious framework is all about - routing the data from the model (any data source you need) to the view (usually using a templating system). The cleanest way to achieve this is to use the model in the controller and export the data to the templating system via the stash.
If you find yourself accessing the model directly from the templating system, you will end up with ugly templates and complicated accident-prone application. The stash is your friend, use the stash!
writing tests
basics: warnings, strict, perltidy, note on Mojolicious::Lite defaults
controlling verbosity
log levels
Explanation of plugin architecture and interception points.
Extending Mojolicious for your application is often best achieved by writing a plugin and loading it in your application. See "Extending Mojolicious with Plugins" for more information.
in an application
with -Mojo
using Mojo::DOM
XXX Introductions
When preparing a project for release into production, you should make sure it is stable and functional to avoid disappointing users and causing unnecessary mainteinance overhead.
You should prepare a set of test to make sure the application is acutally working in it current environment as expected.
To make sure the environment remains stable, you should install Mojolicious directly in its working environment:
$ cd <mojolicious-source-distro>
$ perl Makefile.PL PREFIX=<app-deployment-dir>/lib
$ make test && make install
The @INC
handling is now managed by the same mechanism that finds your application files.
XXX check if this actually works order-wise
XXX Kind souls will supplement this with advice on running effectively under different environments.
getting set-up with an asynchronous poll()
Issues with blocking database connections: XXX discussion on IRC, no definitive argument and explanation receive.
prefork
This section is an overview of the implementation, with more detail than needed for just simple application development. It is intended as a supplement to reading the code and the reference documentation. It might be outdated or simply wrong.
XXX Long, but unfinished ...
Mojolicious is logically divided into three namespaces:
Mojo
-
Mojo
contains a web development framework, a framework for building simple web applications and web application frameworks.Mojo
implements a full web server and client stack with all the necessary supporting infrastructure, including templates, but does not define any dispatchers and application logic (controllers).It is meant to serve as base to be extended by users, used for minimal applications and use as framework for more full-blown web frameworks, such as Mojolicious itself.
MojoX
-
MojoX
is the namespace for extensions toMojo
. This is the namespace used by user-developed extensions found on CPAN and GitHub.Inside the
Mojolicious
distribution, this namespace is populated with classes that extendMojo
with sessions, dispatchers and controllers and an implementation of the routes dispatching system. Mojolicious
-
Mojolicious
is the namespace of the Mojolicious web application framework itself. It is based onMojo
and sessions, dispatchers, controllers and routes dispatching fromMojoX
. It presents two application interfaces, Mojolicious for full blown applications with multiple files and controller classes, using template directory structures, and Mojolicious::Lite, a simplified interface with a single controller class where the whole application is expressed in a single file.
Mojo::Base: a base class with attributes
Mojo::Base is a simple base class for Mojo projects. It provides highly optimized essential services used in other Mojo and Mojolicious classes. Most classes in Mojolicious are based on Mojo::Base.
Understanding Mojo::Base and attributes is crucial for understanding Mojolicious code, since this facility is used throughout the framework.
Mojo::Base implements two services, an object constructor and object attribute infrastructure, expressed as two methods:
new
-
A basic object constructor. You can pass it either a hash or a hash reference with attribute values to set up default attributes at construction.
attr
-
Create attributes. An array reference can be used to create more than one attribute with a single call. An optional second argument that must be either a constant or a sub reference can be used to set a default value. The sub reference will be excuted at accessor read time if there's no set value.
Mojo::Base is optimized for performance, since well implemented attributes can be used throughout the framework and must be very fast. For this reason, attribute access is optimized by compiling custom code (a bit lispish, but very efficient). Essentially attribute lookup turns into execution of an anonymous subroutine. If all the contents of the subroutine are static, the access can be highly optimized by perl runtime.
To set up attribute, call the att
method on the class:
package CreditCard;
use base 'Mojo::Base';
__PACKAGE__->attr('holder'); #use __PACKAGE__ instead of package name
$card->attr('good_thru'); # declare new attribute
$card->attr('valid_from' => '02-10'); # with default value
$card->attr('valid_from' => sub { ... }); # executed at read time
unless overruled by setting a value
$card->attr([ qw/type card_name/ ]); # declare multiple
$card->attr([ qw/type card_name/ ] => 'Visa'); # default value for all
package Main;
my $card = CreditCard->new(); #or, with defaults as a list or a has reference
my $card = CreditCard->new(holder => 'A. N. User', type => 'Visa');
my $card = CreditCard->new({holder => 'A. N. User', type => 'Visa'});
Note that it is not possible to add attributes to an existing object, attributes are properties of the class. If you try to access and attribute that has not been defined, you will get the following error:
Can't locate object method "type" via package "CreditCard" at <filename> line <no>
In addition, since the values are not hold in a data structure but are compiled in the code, it is not possible to dump them easily.
Setting and accessing the attributes is easy:
$card->name('A. N. User'); # returns $card, not value
print 'Card holder: ' . $card->name . "\n"; # returns value
# chaining the call
print 'Default holder :' . $card->name('A. N. User')->name; . "\n"
Since the default value for an attribute can be either a constant or a sub reference, it is not possible to initialize an attribute to an array or a has reference directly. You need to do it using an anonymous sub:
package EtcPassword;
use base 'Mojo::Base';
__PACKAGE__->attr('users' => sub { [] }); # defaults to en empty array ref
__PACKAGE__->attr('users' => sub { [ qw/jane john jules jimmy/ ] });
# or a populated one
__PACKAGE__->attr('user_homes' => sub { {} }); # defaults to empty hash ref
You can set an attribute to a reference and use dereferencing semantics to query the data:
print join(', ', @{$p->users}); # print all element of the array
print $p->users->[0]; # print first element
print $p->users->[1] = 'johannes'; # set second element
Please note that the same rules does not apply when using the constructor or the accessor, using a subroutine there stores a CODE
reference, and using the value itself is perfectly legal:
$p = EtcPassword->new;
$p->users([ qw/jane john jules jimmy/ ]);
# or just:
$p = EtcPassword->new(users => [ qw/jane john jules jimmy/ ] );
The anonymous subroutine semantics of accessor setup makes it perfect for setting up use-relationships with other objects, since the accessor is set up at class initialization time, but the subroutine is only executed in the instance when the accessor is first used.
For example, this is how Mojolicious application instance sets up a types object:
Mojolicious.pm:
__PACKAGE__->attr(types => sub { MojoX::Types->new });
At first access (but not before, so memory may be conserved if the object is never used), a new MojoX::Types instance will be created and its reference stored in the accessor. From that point on, it can be accessed from the application object like any other attribute, chaining accessors and methods as you go:
# check a type using object's method:
$self->types->type('html');
# change a type using object's method:
$self->types->type(html => 'text/html; charset=utf-8');
# get all types using an accessor:
my $types_hashref = $self->types->types;
In most cases, a cubclass of Mojo::Base does not need to implement its own constructor, relying instead no the parent constructor.
If your class needs initialization, it must still call the parent class constructor to perform attribute initialization.
The parent constructor performs blessing to your class for you, but you need to return the reference. If you wish to retain the constructor semantics, you should also pass the arguments to new()
to the implementation in Mojo::Base:
package Something;
use base 'Mojo::Base';
__PACKAGE__->attr('name' => 'a thing');
sub new {
my $self = shift->SUPER::new(@_); # call parent class, with arguments
# ... init ...
return $self; # return the blessed reference
}
See Mojo::Base for reference documentation and more examples.
A number of Mojo classes implement basic services and are not usually needed directly in application code: Mojo::Asset for management of data and files in the HTTP implementation (also performing file streaming without loading the whole file), Mojo::Date implementing HTTP 1.1. dates, Mojo::Exception for exception handling with context information, Mojo::Loader for class loading and plugin framework, Mojo::Log for general logging, Mojo::Path, an URL path container, Mojo::Stateful, an abstract base class for state keeping objects, and many more.
Most of these classes will not be used directly by the web developer, but will be used either by other classes or through some additional syntactic layer (syntax sugar).
A number of classes in Mojo implement generally useful services and are often used both in the framework itself and in applications.
Mojo::ByteStream provides portable text and bytestream manipulation functions, such as encoding and decoding, simple searching (my $position = $b->contains('string')
), line-by-line reading (my $line = $b->get_line
), quoting (including quoted printable), HTML and XML escaping, URL escaping, URL sanitizing and stringification (my $string = $b->to_string
).
Mojo::ByteStream is a frequently-used class, so it can export its constructor as b()
. This syntax sugar in combination with method chaining facilitates the use considerably:
use Mojo::ByteStream 'b';
$value = b($value)->decode($charset)->to_string;
is the same as:
use Mojo::ByteStream ;
$bs = Mojo::ByteStream->new($value);
$bs->decode($charset)
$value = $bs->to_string;
See Mojo::ByteStream for complete reference documentation.
Mojo::JSON is a minimalistic implementaton of RFC 4627 (http://www.ietf.org/rfc/rfc4627), aka JSON (http://www.json.org/.
JSON (JavaScript Object Notation) is a lightweight data-interchange format, supported by most JavaScript libraries and scripting languages. It is easy for humans and for machines. JSON is a text format that is completely language independent but uses familiar conventions and is much easier to parse and generate than XML, making JSON an ideal data-interchange language for the web.
JSON is built on two structures:
A collection of name/value pairs, mapped to perl an ordered list of values, mapped to perl arrays. Mojo::JSON does not support blessed references.
In Mojolicious, JSON is supported as an output format by the rendering subsystem (the json
rendering handler, see MojoX::Renderer and as a configuration language via a plugin (Mojolicious::Plugin::JsonConfig).
If you wish to receive and parse JSON messages, ie. in an AJAX or WebSocket context, you will need to use Mojo::JSON directly in your controller.
JSON format should look familiar enough:
JSON Perl
[1, -2, 3] [1, -2, 3]
{"foo": "bar"} {foo => 'bar'}
See Mojo::JSON for reference documentation, JSON web page at http://www.json.org/ for more info and RFC 4627 (http://www.ietf.org/rfc/rfc4627) for a formal specification.
Mojo contains an efficient versatile perlish templating system, implemented in Mojo::Template. See Mojo::Template for templating reference documentation and some examples.
The templating system is used not only for web templates, but also for services such as code/scaffolding generation and the like. Templates get compiled into a perl function call and are very efficient.
For web applications, the templating implementation is wrapped with additional services and functionality, implemented as a plugin: Mojolicious::Plugin::EpRenderer.
The plugin, enabled by default, registers the templating engine as the handler for *.ep
(embedded perl) files (handlers explained in "Renderer, Handlers, Helpers, Templating engines").
There is an older, simpler version with less fuctionality (Mojolicious::Plugin::EplRenderer, registers as handler for *.epl
(embedded perl lite) files).
See "Templates in Mojolicious" for documentation on web templating and examples.
Mojo::Commands is the interactive command line interface to the Mojo framework. It will automatically detect available commands in the Mojo::Command namespace (or others if so instructed). Commands are implemented by subclassing Mojo::Command.
The command subsystem is normally started at the end of the application startup script by calling (in Mojo
or Mojolicious
):
Mojo::Commands->start;
In Mojolicious::Lite-based applications, the command subsystem is started with a call to the exported function shagadelic(<args>)
, which calls Mojolicious::Lite->start(@_)
, setting up the environment and starting up the command system (inherited from Mojolicious).
(If you are underage and have problems calling shagadelic()
, you can call app->start()
, which is, in fact, the same.)
The command system provides on-line help (help
), application framework generation services (generate
), information/utility commands (version
, test
, generate makefile|psgi
, for Mojolicious
applications also routes
and for Mojolicious::Lite inflate
) and start-up commands (daemon
, daemon_prefork
, cgi
, fastcgi
, get
). See "MOJOLICIOUS IN PRODUCTION" for advice on choosing a suitable mode for running your application in production environment.
Mojolicious command system is fully documented in Mojo::Commands. Use the help system to get full information on available options:
mojo[licious]
mojo[licious] help
mojo[licious] help <command>
mojo[licious] generate
mojo[licious] generate help
To create a simple application and start it in auto reload mode (so that it reloads itself if you edit the files), use:
mojolicious generate app AppName
cd AppName
./script/appname daemon --reload
<load the page at the address provided>
<edit application files>
<reload page>
Since Mojolicious::Lite applications are contained in a single file, in the case of a "lite" application, this becomes simply:
mojolicious generate lite_app appname
./appname daemon --reload
<load the page at the address provided>
<edit application script>
<reload page>
Mojo implements a full HTTP 1.1 client and servers stack, with support for IPv4 and WebSockets, abilities to listen on multiple addresses and ports and optional support for IPv6, and SSL (if suitable perl modules are installed).
The stack is implemented in several classes that act together and interact with the application:
- Mojo::Server
-
Mojo::Server is an abstract HTTP server base class with different implementations:
- Mojo::Server::Daemon
-
Mojo::Server::Daemon is an asynchronous IO HTTP 1.1 And WebSocket Server.
- Mojo::Server::Daemon
-
Mojo::Server::Daemon is an asynchronous IO HTTP 1.1 And WebSocket Server.
- Mojo::Server::Daemon::Prefork
-
Mojo::Server::Daemon::Prefork is a preforking version of the HTTP 1.1 And WebSocket Server.
- Mojo::Server::Daemon::CGI
-
Mojo::Server::Daemon::CGI is a simple and portable CGI (common gateway interface) implementation of the application server.
- Mojo::Server::Daemon::FastCGI
-
Mojo::Server::FastCGI is a portable pure-Perl FastCGI implementation.
- Mojo::IOLoop
-
Mojo::IOLoop is a minimalistic event loop for TCP clients and servers. It optionally supports alternative polling implementations (IO::KQueue, IO::Epoll and connection types (IPv6 with IO::Socket::INET6, TSL with IO::Socket::SSL). The support is automatically activated if the support modules are installed on the system.
- Mojo::Transaction
-
The server's application interface is centered around the concept of a transaction (usually represented as
$tx
variable or->tx
attribute inMojo
code and accessed through a controller$c
with a->tx attribute
inMojolicious
code). Mojo::Transaction is an abstract base class with two implementations, the HTTP transaction Mojo::Transaction:HTTP and the WebSocket transaction Mojo::Transaction::WebSocket.Mojo::Transaction and most of the classes it uses are implementations of Mojo::Stateful, an abstract base class for state keeping objects.
Mojo::Transaction uses request and response message objects and together with them encapsulates the state of the connection and transaction in the server as it is driven by Mojo::IOLoop.
- Mojo::Message
-
Mojo::Message is an abstract base class for HTTP 1.1 messages with two implementations for HTTP request (Mojo::Message::Request and response Mojo::Message::Response).
Messages use a number of other classes:
- Mojo::Headers
-
Mojo::Headers is a container and parser for HTTP headers.
- Mojo::Content
-
Mojo::Content is an abstract base class for HTTP 1.1 content with implementations for multi-part and single content models (Mojo::Content::MultiPart, Mojo::Content::Single).
- Mojo::URL
-
Mojo::URL implements a subset of RFC 3986 (http://www.ietf.org/rfc/rfc3986), for Uniform Resource Locators, and is based on Mojo::Path. It provides interfaces for processing, accessing and constructing URLs. It represents URL in request.
It is also accessible at the application level, where the request and response URLs are normally accessed indirectly through syntactic sugar of
->url_for()
and->redirect_to()
in default controller.See Mojo::URL, also "url_for" in Mojolicious::Controller and "redirect_to" in Mojolicious::Controller for reference documentation.
See description of
->url_for()
and->redirect_to()
with examples in "CONTROLLERS AND ACTIONS". - Mojo::Parameters
-
Mojo::Parameters is a container for form parameters and is used in the request object of the transaction and for parameter parsing of URLs.
-
Mojo::Cookie is an abstract base class for HTTP 1.1 cookies with implementations for request and response (Mojo::Cookie::Request, Mojo::Cookie::Response).
- Mojo::Upload
-
Mojo::Upload is a container for uploads.
- Support classes:
-
- Mojo::Filter::Chunked
-
Mojo::Filter::Chunked implements HTTP 1.1 chunked transfer encoding.
- Mojo::Date
-
Mojo::Date implements HTTP 1.1 date and time functions according to RFC2616.
- Mojo::Log
-
Mojo::Log is a simple logger for Mojo projects.
- Mojo::Asset
-
Mojo::Asset is an abstract base class for assets with implementations for file and memory assets (Mojo::Asset::File and Mojo::Asset::Memory).
HTTP Client (ie., User Agent) is implemented using the same components (and some others, such as Mojo::CookieJar. It also supports full featured asynchronious IO HTTP 1.1 and WebSocket connections with optional IPv6, TLS, "epoll" and "kqueue" support. The client supports get
, head
, put
, post
and delete
HTTP "verbs".
See "USING MOJO HTTP CLIENT" for further information.
The API (application interface) to the server stack in Mojo is encapsulated in the transaction. The server is driven by IO loop using call-backs set up by the server at its initialization, while the state of the transaction is kept in the transaction object and its request and response objects.
This is a low-level interface, to be used while extending the framework or writing plugins. Applications should be using a higher-level interface provided by Mojolicious or a suitable plugin. The interface is fully documented in Mojo::Transaction. To fully understand the interactions with Mojo::Transaction
, see also Mojo::Stateful and the implementation of its interface and state machine in Mojo::Transaction
.
The transaction object provides access to the local connection, remote connection, request (with request type, URL, parameters, cookies, content, uploads and direct access to request environment) and response (with response code, message and cookies).
Some of the more important attributes of Mojo::Transaction:
connection
-
my $connection = $tx->connection; $tx = $tx->connection($connection);
Connection identifier on socket. XXX add what this usually is.
local_address
,local_port
-
my $local_address = $tx->local_address; $tx = $tx->local_address($address); my $local_port = $tx->local_port; $tx = $tx->local_port($port); my $remote_address = $tx->remote_address; $tx = $tx->remote_address($address); my $remote_port = $tx->remote_port; $tx = $tx->remote_port($port);
Some of the more important methods in Mojo::Transaction:
req
,res
-
my $req = $tx->req; my $res = $tx->res;
Transaction request and response.
is_websocket
-
my $is_websocket = $tx->is_websocket;
Check if the connection is a WebSocket.
See Mojo::Transaction for server/IOloop-interaction methods).
The request and response interfaces are usually accessed through the transaction's ->req
and ->res
methods. Some of them are available both on request and response, some of them are specific. To mark the use, ->{msg}
(for message), ->req
and ->res
will be used. Please note that ->{msg}
is not actually valid syntax.
Request/response attributes:
method
-
my $method = $tx->req->method; $req = $tx->req->method('GET');
HTTP request method or "verb", XXX ie. one of "GET", "HEAD", "POST", "PUT", "DELETE".
url
-
my $url = $tx->req->url; $req = $tx->req->url(Mojo::URL->new);
HTTP request URL, defaults to a Mojo::URL object.
content
,headers
-
my $content = $tx->req->content; $req = $tx->req->content(Mojo::Content::Single->new); my $headers = $tx->req->headers; $req = $tx->req->header(Mojo::Headers->new);
Access to content and headers of a request.
params
andquery_params
-
my $params = $tx->req->params; # GET and POST my $params = $tx->req->query_params; # GET only
All
GET
(and forparams
alsoPOST
) parameters, defaulting to a Mojo::Parameters object. env
-
my $env = $tx->req->env; $req = $tx->req->env({});
Direct access to the environment hash if available.
default_charset
-
my $charset = $tx->req->default_charset; $req = $tx->req->message->default_charset('UTF-8');
Default charset used for form data parsing.
Request/response XXX methods:
body
-
my $string = $tx->{msg}->body; $message = $tx->{msg}->body('Hello!'); $counter = 1; $message = $tx->{msg}->body(sub { my $self = shift; my $chunk = ''; $chunk = "hello world!" if $counter == 1; $chunk = "hello world2!\n\n" if $counter == 2; $counter++; return $chunk; });
Helper for simplified content access.
body_params
-
my $params = $tx->{msg}->body_params;
Access to
POST
parameters. XXX difference with above attributes? body_size
-
my $size = $tx->{msg}->body_size;
Size of the body.
to_string
-
XXX
build
,build_headers
,build_body
-
my $string = $tx->{msg}->build; my $string = $tx->{msg}->build_headers; my $string = $tx->{msg}->build_body;
Render the whole message, headers or body.
-
my $cookie = $tx->{msg}->cookie('foo'); my @cookies = $tx->{msg}->cookie('foo');
Access a request/response cookie. XXX explain list context
-
my $cookies = $tx->{msg}->cookies; $req = $tx->{msg}->cookies(Mojo::Cookie::Request->new); $req = $tx->{msg}->cookies({name => 'foo', value => 'bar'});
Access request/response cookies. XXX expand, also on Mojo::Cookie::Request, perhaps just in the cookie section.
param
-
my $param = $tx->req->param('foo');
Access
GET
andPOST
parameters, defaults to a Mojo::Parameters object. XXX expand upload
,uploads
-
my $upload = $tx->req->upload('foo'); my @uploads = $tx->req->upload('foo'); my $uploads = $tx->req->uploads;
Access specific or all file uploads. Actually implemented in Mojo::Message, so the methods are available also on response object. XXX
proxy
-
my $proxy = $tx->req->proxy; $req = $tx->req->proxy('http://foo:[email protected]:3000'); $req = $tx->req->proxy(Mojo::URL->new('http://127.0.0.1:3000'));
Proxy URL for message.
is_secure
-
my $secure = $tx->req->is_secure;
Check if connection is secure.
XXX Add some examples here ... And references to later sections.
See Mojo::Message, Mojo::Message::Request and Mojo::Message::Response for full reference documentation.
Mojo is a framework foundation (or meta-framework, pick your moniker), so it does not define a high-level interface to the transaction. Instead, it provides an abstract method ->handler
that your application can implement to handle the transaction.
$tx = $mojo->handler($tx);
The handler is the main entry point to your application or framework and will be called for each new transaction. An application or framework built on Mojo
should implement its transaction handling interface by implementing a ->handler
method.
Mojo also implements the ->start
method for application start. It sets up $ENV{MOJO_APP}
environment variable and starts the application command system (see "Command System") which performs the actual application start and handover to an implementation of Mojo::Server:
Mojo->start;
Mojo->start('daemon'); # start in daemon mode: Mojo::Server::Daemon
Mojo also implements a number of attributes, such as ->client
to access a full featured HTTP 1.1 client for use in your applications, ->home
that stringifies to the path of the home directory of your application and ->log
to access the logging layer of your application.
See Mojo for reference documentation.
MojoX
introduces a number of new concepts:
- dispatcher
-
Dispatcher finds the correct action for the given request.
MojoX
implements two dispatchers, MojoX::Dispatcher::Static for serving static types, and MojoX::Dispatcher::Routes for dynamic dispatching based on the routes concept (see "Dispatching with Routes" for explanation).The static dispatcher is simple: it has three attributes:
type
, a MIME-type database (MojoX::Types) to map files to proper MIME types,prefix
to remove from the requested URL androot
to add to the request path to generate the correct file system path. It is accessed by two general methods,dispatch($c)
is called with a controller object and is the normal way to call the dispatcher, whileserve($c, '/path/to/file')
can be used to serve a specific file for a request.The routes dispatcher merits its own section: "Routes Dispatcher"
- controller
-
Controller is the web application developer side of the "controller" from the Model-View-Controller paradigm: it defines interfaces to access the transaction and support systems to connect to the view (rendering, in Mojolicious). MojoX::Controller is actually an abstract base class for MojoX::Session::Cookie::Controller (with cookie and session support) and MojoX::Dispatcher::Routes::Controller to integrate with routes.
The routes controller merits its own section: "Routes Controller"
- stash
-
The stash is a request-scoped hash for data used by controller, renderer and their components to produce content. It is used as a general data-passing mechanism between these elements and is automatically populated by parameters, route named parameters etc. It is a non-blessed hash reference shared between controller, renderer and its handlers/helpers.
- renderer
-
The renderer is implemented in MojoX::Renderer. It turns the data in the stash into content suitable for serving to the client. It has a flexible architecture, supporting multiple handlers (template/file format engines) and helpers (sub-engines).
The renderer also merits its own section: Routes Dispatcher and Controller "Renderer, Handlers, Helpers, Templating engines"
The routes dispatcher is usually instantiated and set up in the application start up code (see "Mojolicious Application Interface" for examples in the context of a Mojolicious application):
my $r = MojoX::Dispatcher::Routes->new;
$r->route('/:controller/:action/:id')->to('example#welcome', id => 1);
The task of the dispatcher itself is simply to find a combination of class and method in the application namespace to fulfill the requirements of the controller/action specification in the routes request. The route matching itself is peformed by its base class, MojoX::Routes. The dispatcher has a simple interface. It defines three attributes:
namespace
-
namespace
is the namespace to search for controllers controller_base_class
-
controller_base_class
is the base class used to identify controllers: objects without this class in their inheritance trees will not be accepted as valid controllers. -
hidden
is an array of methods and attributes that are hidden from the dispatcher and are not considered as valid candidates for actions.
It has only two public methods, hide
as a helper to add to the hidden
attribute and dispatch
, the entry point to the dispatching process:
$dispatcher->dispatch($c);
It has a number of internal methods implementing class and method generation and walking of the stack of routes as represented by MojoX::Routes::Match, a Routes visitor class.
It also implements embedded application detection and dispatching to/from embedded applications. See "Embedding Applications" for more information.
The actual routes semantic is defined in MojoX::Routes, the base class of the routes dispatcher.
XXX interface with explanations, and very interesting explanations these will be
The controller, usually written as $c
in the examples, is the base class for most of the application code, since routes dispatcher dispatches requests to controller (an application class) and action (its method). So you should think of the controller more in the terms of the $self
object in your application's actions:
warn "The argument for 'month' was " . $self->param('month');
my $month = $self->param('month');
$self->render_text("The month param was $month.");
XXX controller interface here
Controller and Action
Mojolicious is based on the Mojo framework foundation / meta-framework and extends its interface.
XXX this is not clear and needs cleanup:
The core of the transaction interface is its implementation of the ->handler
method, which sets up the environment for Mojolicious applications.
XXX full Mojolicious interface here:
A Mojolicious application is initialized by a call to the main application package method startup
at server start, usually used to set-up routes and perhaps initialize the model:
package Test;
use strict;
use warnings;
use base 'Mojolicious';
# This method will run once at server start
sub startup {
my $self = shift;
# Routes
my $r = $self->routes;
# Default route
$r->route('/:controller/:action/:id')
->to(controller => 'example', action => 'welcome', id => 1);
}
1;
(This is where the $ENV{MOJO_APP}
environment variable, set up by the application script is used by the command system to locate the right package.)
When Mojolicios application is called with a transaction, the Mojolicious handler
instantiates the default controller class (usually Mojolicious::Controller, with a rather contorted inheritance tree of isa
MojoX::Dispatcher::Routes::Controller isa
MojoX::Session::Cookie::Controller isa MojoX::Controller), set with the controller_class
attribute) with attributes for the application (app
), stash (stash
) and the transaction tx
) and call ->process
on the class.
Then the default controller and its dispatcher know how to find the right application controller and action for each request and maps them to the application's package and its method:
->to(controller => 'example', action => 'welcome') # Test::Example->welcome
Usually, the controller is a subclass of the default controller with all its functionality (renderers, handlers, templating engines, helpers etc.:
package Test::Example;
...
use base 'Mojolicious::Controller';
XXXX
by calling process()
, an ideal entry point for subclassing:
sub process { shift->dispatch(@_) }
XXXX
, a request is first subject to dispatching, where the proper action is found based on the URL path of the request. There are two dispatchers: first MojoX::Dispatcher::Static is called, a simple dispatcher for static files, by default serving up files found under public/
. If the static dispatcher fails, MojoX::Dispatcher::Routes is tried.
XXXX
Mojolicious::Lite Application Interface
XXX Explain how it is implemented; How we have only one controller; How exactly we parse for templates; How bridges come to be ...
CONTRIBUTING TO Mojolicious
Mojolicious is developed using a GitHub repository (http://github.com/kraih/mojo). Developer communicate primarily on IRC (#[email protected]
) and using a Google groups mailing list (http://groups.google.com/group/mojolicious).
If you want to submit a patch, the best way to do it is to set up a repository on GitHub (forking is offered at the repository-to-be-forked after you have logged in, more info at http://help.github.com/forking/) and set it up to track the upstream. The set-up is different from what you would do if it was your project, since you pull from upstream and push to your own repository. This is how you can do that:
$ git clone [email protected]:<your-name-here>/mojo.git #private URL!
$ cd mojo
$ git remote add upstream git://github.com/kraih/mojo.git
Then you should clone the repository locally using git
, branch it and make your changes in a new branch:
$ git branch <meaningful-feature-or-bug-name>
$ git checkout <meaningful-feature-or-bug-name>
This is the time to do your work. Do not forget to prepare suitable tests (see bellow) and update/create reference documentation. When finished, this is how you publish your changes:
$ git add <your-files>
$ git commit -m <meaningful-name>
$ git push
Now you should use the Pull Request facility at GitHub to notify the developers, and probably say so on IRC or the mailing list. This approach will permit the core developers to merge in your changes.
At the same time, you will be able o track the upstream in your master branch:
$ git checkout master # back to the master branch
$ git fetch upstream master
$ git merge upstream/master
The fetch/merge combo can be expressed also as:
$ git pull upstream master
You can optimize this by changing the default set-up and add this to the .git/config
file in your repository:
[branch "master"]
remote = upstream
merge = master
No you can fetch and merge upstream into your master simply by saying:
$ git pull upstream
To start a new patch, repeat the branching and check-out process above.
Note: Needing to use a new branch for every commit-set is admittedly unusual, but upstream will likely squash and modify your commits before applying, so merging them back will be an non-trivial process, and your history will become unnecessarily complicated.
git
will take care of efficiency and facilitate the process for you. There is plenty of documentation for new git
users with the package, on git
site at http://git-scm.com/ and at GitHub: http://help.github.com/.
When contributing to the framework, you will need to have different versions of the distribution accessible, either to compare or benchmark or to use a stable release for your own projects and applications while working on a new feature.
You should be familiar with the possibilities, but to make things simple, let us review the options:
You can run "directly from the source tree" (assuming bash):
$ PERL5LIB=./lib:$PERL5LIB script/mojolicious <command>
To make this permanent:
$ export PERL5LIB=`pwd`/lib:$PERL5LIB
$ export PATH=`pwd`/script:$PATH
To make this sensible, you should use make to create blib
and then do:
$ WORKDIR=/path/to/repository/blib
$ export PERL5LIB=$WORKDIR/lib:$PERL5LIB
$ export PATH=$WORKDIR/script:$PATH
You might still get issues due to the fact that both your development and the released versions are available in the search path. The only way to solve this problem is to have both installed in non-standard locations.
A refresher:
$ mkdir ~/usr ~/devel
$ cd <distro_workdir>
$ perl Makefile.PL PREFIX=$HOME/usr
$ make test && make install
$ cd ../<devel_workdir>
$ perl Makefile.PL PREFIX=$HOME/devel
$ make test && make install
$ # writing interesting scripts to set up environment
$ # left as an exercice for the reader
Please do not forget that Mojolicious is developed with an agile development model and much effort is invested into having as complete testing coverage as possible. For that reason, bug reports and feature patches generally require suitable tests. If you can produce a test for a bug you have found, the chances of getting a quick fix are much better.
Submitting a test is best done with the same method or, alternatively, you can send the file to the mailing list or use nopaste
(perhaps http://mojopaste.com/ or http://showmetheco.de/) on the #mojo
IRC channel.
In addition, you should follow the Mojo coding guidelines, as described in Mojolicious::Guides::CodingGuidelines.
(If you are hopeless when you realize that a Futurama (or The Simpsons) quote is needed for each file, do not despair: http://www.google.si/search?q=futurama+quotes, for example http://www.thatwasfunny.com/category/cartoons/futurama. Try not to repeat existing quotes in the code.)
Extending Mojo and Mojolicious: MojoX and Mojolicious Plugins
The proper way to extend the framework depends on the kind of extension in question. The developer needs to remember that Mojo is the framework for framework development, to be extended in the MojoX namespace, while Mojolicious is an implementation of a web framework on top of Mojo with some MojoX extensions.
Therefore, if the extensions bring in functionality that is not strictly specific to Mojolicious, it should be implemented as a Mojo extension in MojoX namespace. If it can be used under Mojolicious, a plugin wrapper based on Mojolicious::Plugin should be added to facilitate the integration in Mojolicious and Mojolicious::Lite applications.
If the extension functions strictly in the context of Mojolicious, it should be implemented as a Mojolicious Plugin.
Please note that besides plugin hooks, plugins can integrate with renderers by adding handlers and helpers and with routes by adding conditions:
# Mojolicious/Plugin/I18n.pm:
$app->renderer->add_helper(l => sub { shift->stash->{i18n}->localize(@_) });
#Mojolicious/Plugin/PodRenderer.pm
$app->renderer->add_handler( pod => sub { ... } );
#Mojolicious/Plugin/AgentCondition.pm
$app->routes->add_condition( agent => sub { ... } );
See Mojolicious::Plugin for reference. Plugins shipped with Mojolicious have a number of advanced examples.
Most of the following subsections should eventually find their proper home in the proper section of the handbook. They are here as a work in progress, and some will remain as useful tips.
See Mojolicious::Guides::FAQ and Mojolicious::Guides::Cookbook for more info.
Templates have an encoding
attribute, which, luckily, is set to UTF-8
by default.
XXX No idea how to use it. A helper would be nice.
For XXX templates in __DATA__ sections, the file encoding is in effect, so do not forget to use use utf8;
if you plan to use Unicode in your templates.
- Sebastiean Riedel
-
For achieving it all
- Jan Jona Javoršek
-
For noncomprehending comprehensively
- Anatoly Sharifulin
-
For understanding, both meanings
- Вячеслав Тихановский [Viacheslav Tykhanovskyi]
-
For being patently patient
- Mirko Westermeier
-
For trying and telling
- Everyone at
#[email protected]
-
For clues and contributions
Hey! The above document had some coding errors, which are explained below:
- Around line 192:
-
Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.
Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.
Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.
Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.
Unterminated L<...> sequence
- Around line 2225:
-
Non-ASCII character seen before =encoding in 'Javoršek'. Assuming UTF-8