$c->log->info( 'done!' );
}
-You should also be aware that roles in C<< $c-E<gt>setup >> are applied
+You should also be aware that roles in C<< $c->setup >> are applied
after the last plugin with all the benefits of using a single
L<with()|Moose/"with (@roles)"> statement in an ordinary L<Moose> class.
Your class is automatically made immutable at the end of the current file.
-CAVEAT: Using roles in C<< $c-E<gt>setup >> was implemented in Catalyst
+CAVEAT: Using roles in C<< $c->setup >> was implemented in Catalyst
version 5.80004. In prior versions you might get away with
after 'setup_plugins' => sub{ with(
but this is discouraged and you should upgrade to 5.80004 anyway,
because it fixes a few important regressions against 5.71
-CAVEAT: Using roles in C<< $c-E<gt>setup >> will not currently allow
+CAVEAT: Using roles in C<< $c->setup >> will not currently allow
you to pass parameters to roles, or perform conflict resolution.
Conflict detection still works as expected.
=head2 ACCESSORS
-Most of the request-specific attributes like C<$c-E<gt>stash>,
-C<$c-E<gt>request> and C<$c-E<gt>response> have been converted to
+Most of the request-specific attributes like C<< $c->stash >>,
+C<< $c->request >> and C<< $c->response >> have been converted to
L<Moose> attributes but without type constraints, attribute helpers or
builder methods. This ensures that Catalyst 5.8 is fully backwards
compatible to applications using the published API of Catalyst 5.7 but
your C<use Catalyst> statement . However, you can also enable it using
environment variable, so you can (for example) get debug info without
modifying your application scripts. Just set C<CATALYST_DEBUG> or
-C<E<lt>MYAPPE<gt>_DEBUG> to a true value.
+C<< <MYAPP>_DEBUG >> to a true value.
=head2 Sessions
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>.
+C<< $c->res->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
=head2 Component Configuration
At creation time, the class configuration of your component (the one
-available via C<$self-E<gt>config>) will be merged with possible
+available via C<< $self->config >>) will be merged with possible
configuration settings from the applications configuration (either
directly or via config file). This is done by Catalyst, and the
correctly merged configuration is passed to your component's
This gives us a process() method and we can now just do
$c->forward('MyApp::View::TT') to render our templates. The base class
makes process() implicit, so we don't have to say
-C<$c-E<gt>forward(qw/MyApp::View::TT process/)>.
+C<< $c->forward(qw/MyApp::View::TT process/) >>.
sub hello : Global {
my ( $self, $c ) = @_;
by L<Catalyst::Action::RenderView>.
Also, be sure to put the template under the directory specified in
-C<$c-E<gt>config-E<gt>{root}>, or you'll end up looking at the debug
+C<< $c->config->{root} >>, or you'll end up looking at the debug
screen.
=head4 Models
will find and load it automatically at compile-time; you can
C<forward> to the module, which can only be done to Catalyst
components. Only Catalyst components can be fetched with
-C<$c-E<gt>model('SomeModel')>.
+C<< $c->model('SomeModel') >>.
Happily, since many people have existing Model classes that they
would like to use with Catalyst (or, conversely, they want to
data. If omitted, Catalyst will try to auto-detect the directory's
location. You can define as many parameters as you want for plugins or
whatever you need. You can access them anywhere in your application via
-C<$context-E<gt>config-E<gt>{$param_name}>.
+C<< $context->config->{$param_name} >>.
=head3 Context
For both C<:LocalRegex> and C<:Regex> actions, if you use capturing
parentheses to extract values within the matching URL, those values
-are available in the C<$c-E<gt>req-E<gt>captures> array. In the above
+are available in the C<< $c->req->captures >> array. In the above
example, "widget23" would capture "23" in the above example, and
-C<$c-E<gt>req-E<gt>captures-E<gt>[0]> would be "23". If you want to
+C<< $c->req->captures->[0] >> would be "23". If you want to
pass arguments at the end of your URL, you must use regex action
keys. See L</URL Path Handling> below.
the method, so that a private C<bar> method in your
C<MyApp::Controller::Catalog::Order::Process> controller must, if
called from elsewhere, be reached with
-C<$c-E<gt>forward('/catalog/order/process/bar')>.
+C<< $c->forward('/catalog/order/process/bar') >>.
=back
}
A C<forward> does not create a new request, so your request object
-(C<$c-E<gt>req>) will remain unchanged. This is a key difference between
+(C<< $c->req >>) will remain unchanged. This is a key difference between
using C<forward> and issuing a redirect.
You can pass new arguments to a C<forward> by adding them
-in an anonymous array. In this case C<$c-E<gt>req-E<gt>args>
+in an anonymous array. In this case C<< $c->req->args >>
will be changed for the duration of the C<forward> only; upon
-return, the original value of C<$c-E<gt>req-E<gt>args> will
+return, the original value of C<< $c->req->args >> will
be reset.
sub hello : Global {
L<Catalyst::Runtime>, L<Catalyst::Response>, and
L<Catalyst::Request>)
-C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
+C<< $c->response->body >> sets the HTTP response (see
L<Catalyst::Response>), while
-C<$c-E<gt>welcome_message> is a special method that returns the welcome
+C<< $c->welcome_message >> is a special method that returns the welcome
message that you saw in your browser.
The ":Path :Args(0)" after the method name are attributes which
$c->stash(template => 'hello.tt');
}
-This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are
+This time, instead of doing C<< $c->response->body() >>, you are
setting the value of the "template" hash key in the Catalyst "stash", an
area for putting information to share with other parts of your
application. The "template" key determines which template will be
displayed at the end of the request cycle. Catalyst controllers have a
default "end" action for all methods which causes the first (or default)
-view to be rendered (unless there's a C<$c-E<gt>response-E<gt>body()>
+view to be rendered (unless there's a C<< $c->response->body() >>
statement). So your template will be magically displayed at the end of
your method.
$c->stash({template => 'hello.tt', foo => 'bar',
another_thing => 1});
-Any of these formats work, but the C<$c-E<gt>stash(name =E<gt> value);>
+Any of these formats work, but the C<< $c->stash(name => value); >>
style is growing in popularity -- you may wish to use it all the time
(even when you are only setting a single value).
=item *
-the C<$c-E<gt>debug> method on the C<$c> Catalyst context object
+the C<< $c->debug >> method on the C<$c> Catalyst context object
=item *
You can also configure components in your application class. For
example, Edit C<lib/MyApp.pm> and you should see the default
-configuration above the call to C<_PACKAGE__-E<gt>setup> (your defaults
+configuration above the call to C<< _PACKAGE__->setup >> (your defaults
could be different depending on the version of Catalyst you are using):
__PACKAGE__->config(
Change this to match the following (insert a new
-C<__PACKAGE__-E<gt>config> below the existing statement):
+C<< __PACKAGE__->config >> below the existing statement):
__PACKAGE__->config(
name => 'MyApp',
If you need to create the database more than once, you probably want to
issue the C<rm myapp.db> command to delete the database before you use
-the C<sqlite3 myapp.db E<lt> myapp01.sql> command.
+the C<< sqlite3 myapp.db < myapp01.sql >> command.
Once the C<myapp.db> database file has been created and initialized, you
can use the SQLite command line environment to do a quick dump of the
Open C<lib/MyApp/Controller/Books.pm> and un-comment the model code we
left disabled earlier so that your version matches the following
-(un-comment the line containing C<[$c-E<gt>model('DB::Book')-E<gt>all]>
+(un-comment the line containing C<< [$c->model('DB::Book')->all] >>
and delete the next 2 lines):
=head2 list
$c->stash(template => 'books/list.tt2');
}
-B<TIP>: You may see the C<$c-E<gt>model('DB::Book')> un-commented above
-written as C<$c-E<gt>model('DB')-E<gt>resultset('Book')>. The two are
-equivalent. Either way, C<$c-E<gt>model> returns a
+B<TIP>: You may see the C<< $c->model('DB::Book') >> un-commented above
+written as C<< $c->model('DB')->resultset('Book') >>. The two are
+equivalent. Either way, C<< $c->model >> returns a
L<DBIx::Class::ResultSet> which handles queries
against the database and iterating over the set of results that is
returned.
-We are using the C<-E<gt>all> to fetch all of the books. DBIC supports
+We are using the C<< ->all >> to fetch all of the books. DBIC supports
a wide variety of more advanced operations to easily do things like
filtering and sorting the results. For example, the following could be
used to sort the results by descending title:
C<setenv DBIC_TRACE 1>).
B<NOTE:> You can also set this in your code using
-C<$class-E<gt>storage-E<gt>debug(1);>. See
+C<< $class->storage->debug(1); >>. See
L<DBIx::Class::Manual::Troubleshooting> for details (including options
to log to a file instead of displaying to the Catalyst development
server log).
<span class="error">[% error_msg %]</span>
If we set either message in the Catalyst stash (e.g.,
-C<$c-E<gt>stash-E<gt>{status_msg} = 'Request was successful!'>) it will
+C<< $c->stash->{status_msg} = 'Request was successful!' >>) it will
be displayed whenever any view used by that request is rendered. The
C<message> and C<error> CSS styles can be customized to suit your needs
in the C<root/static/css/main.css> file we create below.
The C<many_to_many> relationship bridge is optional, but it makes it
easier to map a book to its collection of authors. Without it, we would
have to "walk" through the C<book_author> table as in
-C<$book-E<gt>book_author-E<gt>first-E<gt>author-E<gt>last_name> (we will
+C<< $book->book_author->first->author->last_name >> (we will
see examples on how to use DBIx::Class objects in your code soon, but
-note that because C<$book-E<gt>book_author> can return multiple authors,
+note that because C<< $book->book_author >> can return multiple authors,
we have to use C<first> to display a single author). C<many_to_many>
allows us to use the shorter
-C<$book-E<gt>author-E<gt>first-E<gt>last_name>. Note that you cannot
+C<< $book->author->first->last_name >>. Note that you cannot
define a C<many_to_many> relationship bridge without also having the
C<has_many> relationship in place.
JOIN author author ON author.id = me.author_id WHERE ( me.book_id = ? ): '5'
Also note in C<root/src/books/list.tt2> that we are using "| html", a
-type of TT filter, to escape characters such as E<lt> and E<gt> to <
+type of TT filter, to escape characters such as < and > to <
and > and avoid various types of dangerous hacks against your
application. In a real application, you would probably want to put "|
html" at the end of every field where a user has control over the
same name as your controller action, allowing you to save the step of
manually specifying the template name in each action. For example, this
would allow us to remove the
-C<$c-E<gt>stash-E<gt>{template} = 'books/list.tt2';>
+C<< $c->stash->{template} = 'books/list.tt2'; >>
line of our C<list> action in the Books controller.
Open C<lib/MyApp/Controller/Books.pm> in your editor and comment out
this line to match the following (only the
-C<$c-E<gt>stash-E<gt>{template}> line has changed):
+C<< $c->stash->{template} >> line has changed):
=head2 list
URL as before.
B<NOTE:> If you use the default template technique, you
-will B<not> be able to use either the C<$c-E<gt>forward> or the
-C<$c-E<gt>detach> mechanisms (these are discussed in Chapter 2 and
+will B<not> be able to use either the C<< $c->forward >> or the
+C<< $c->detach >> mechanisms (these are discussed in Chapter 2 and
Chapter 9 of the Tutorial).
B<IMPORTANT:> Make sure that you do B<not> skip the following section
=head2 Return To A Manually Specified Template
-In order to be able to use C<$c-E<gt>forward> and C<$c-E<gt>detach>
+In order to be able to use C<< $c->forward >> and C<< $c->detach >>
later in the tutorial, you should remove the comment from the statement
in C<sub list> in C<lib/MyApp/Controller/Books.pm>:
}
Here we print a log message and store the DBIC ResultSet in
-C<$c-E<gt>stash-E<gt>{resultset}> so that it's automatically available
+C<< $c->stash->{resultset} >> so that it's automatically available
for other actions that chain off C<base>. If your controller always
needs a book ID as its first argument, you could have the base method
capture that argument (with C<:CaptureArgs(1)>) and use it to pull the
-book object with C<-E<gt>find($id)> and leave it in the stash for later
+book object with C<< ->find($id) >> and leave it in the stash for later
parts of your chains to then act upon. Because we have several actions
that don't need to retrieve a book (such as the C<url_create> we are
working with now), we will instead add that functionality to a common
request).
Also notice that we are using a more advanced form of C<uri_for> than we
-have seen before. Here we use C<$c-E<gt>controller-E<gt>action_for> to
+have seen before. Here we use C<< $c->controller->action_for >> to
automatically generate a URI appropriate for that action based on the
method we want to link to while inserting the C<book.id> value into the
appropriate place. Now, if you ever change C<:PathPart('delete')> in
=item *
If you are referring to a method in the current controller, you can use
-C<$self-E<gt>action_for('_method_name_')>.
+C<< $self->action_for('_method_name_') >>.
=item *
If you are referring to a method in a different controller, you need to
include that controller's name as an argument to C<controller()>, as in
-C<$c-E<gt>controller('_controller_name_')-E<gt>action_for('_method_name_')>.
+C<< $c->controller('_controller_name_')->action_for('_method_name_') >>.
=back
}
Now, any other method that chains off C<object> will automatically have
-the appropriate book waiting for it in C<$c-E<gt>stash-E<gt>{object}>.
+the appropriate book waiting for it in C<< $c->stash->{object} >>.
=head2 Add a Delete Action to the Controller
trouble.
We can improve the logic by converting to a redirect. Unlike
-C<$c-E<gt>forward('list'))> or C<$c-E<gt>detach('list'))> that perform a
+C<< $c->forward('list')) >> or C<< $c->detach('list')) >> that perform a
server-side alteration in the flow of processing, a redirect is a
client-side mechanism that causes the browser to issue an entirely new
request. As a result, the URL in the browser is updated to match the
Although the sample above only shows the C<content> div, leave the rest
of the file intact -- the only change we made to the C<wrapper.tt2> was
to add "C<|| c.request.params.status_msg>" to the
-C<E<lt>span class="message"E<gt>> line. Note that we definitely want
+C<< <span class="message"> >> line. Note that we definitely want
the "C<| html>" TT filter here since it would be easy for users to
modify the message on the URL and possibly inject harmful code into the
application if we left that off.
We defined the search string as C<$title_str> to make the method more
flexible. Now update the C<list_recent_tcp> method in
C<lib/MyApp/Controller/Books.pm> to match the following (we have
-replaced the C<-E<gt>search> line with the C<-E<gt>title_like> line
+replaced the C<< ->search >> line with the C<< ->title_like >> line
shown here -- the rest of the method should be the same):
=head2 list_recent_tcp
has nothing to do with the SimpleDB offered in Amazon's web services
offerings -- here we are only talking about a "simple" way to use your
DB as an authentication backend.) Open C<lib/MyApp.pm> and place the
-following text above the call to C<__PACKAGE__-E<gt>setup();>:
+following text above the call to C<< __PACKAGE__->setup(); >>:
# Configure SimpleDB Authentication
__PACKAGE__->config(
Although the sample above only shows the C<content> div, leave the rest
of the file intact -- the only change we made to replace "||
c.request.params.status_msg" with "c.flash.status_msg" in the
-C<E<lt>span class="message"E<gt>> line.
+C<< <span class="message"> >> line.
=head2 Try Out Flash
=head1 LOG STATEMENTS
-Folks in the former group can use Catalyst's C<$c-E<gt>log> facility.
+Folks in the former group can use Catalyst's C<< $c->log >> facility.
(See L<Catalyst::Log> for more detail.) For example, if you add the
following code to a controller action method:
One solution is to allow the database specification to be overridden
with an environment variable. For example, open
C<lib/MyApp/Model/DB.pm> in your editor and change the
-C<__PACKAGE__-E<gt>config(...> declaration to resemble:
+C<< __PACKAGE__->config(... >> declaration to resemble:
my $dsn = $ENV{MYAPP_DSN} ||= 'dbi:SQLite:myapp.db';
__PACKAGE__->config(
=item *
If the form has been submitted and passes validation, we skip creating a
-new book and just use C<$form-E<gt>model-E<gt>update> to update the
+new book and just use C<< $form->model->update >> to update the
existing book.
=item *
If the form is being displayed for the first time (or has failed
validation and it being redisplayed), we use
-C<$form-E<gt>model-E<gt>default_values> to populate the form with data
+C<< $form->model->default_values >> to populate the form with data
from the database.
=back
Then, edit C<root/src/books/list.tt2> and add a new link below the
existing "Delete" link that allows us to edit/update each existing book.
-The last E<lt>tdE<gt> cell in the book list table should look like the
+The last <td> cell in the book list table should look like the
following:
...
You can limit the replacement operation by selecting text first (depending
on your version of Emacs, you can either use the mouse or experiment with
commands such as C<C-SPC> to set the mark at the cursor location and
-C<C-E<lt>> and C<C-E<gt>> to set the mark at the beginning and end of the
+C<< C-< >> and C<< C-> >> to set the mark at the beginning and end of the
file respectively.
Also, Stefan Kangas sent in the following tip about an alternate
=item *
Create the database and a user for the database (note that we are
-using "E<lt>catalystE<gt>" to represent the hidden password of
+using "<catalyst>" to represent the hidden password of
"catalyst"):
$ sudo -u postgres createuser -P catappuser