The first link on the index page is Look at all people. So let's create an action that will display everyone in our database, along with their addresses (if any). We'll also show links to relevant actions such as "edit name", "add address", and "delete person". The eventual goal is to have a page that looks something similar to the following screenshot:
The page is a little busy, but it conveys all the information that we want to know. (You'll also notice that Catalyst and Perl can handle Unicode data flawlessly.)
The first thing we need to do is to create a Person
Controller for managing people. This Controller will have add, delete, and list actions for each person. (The list action actually shows every person, which is convenient even if the grammar isn't perfect.)
Let us generate a Controller for Person
using the helpers, as follows:
perl script/addressbook_create.pl controller Person
It should look like the following (minus comments):
package AddressBook::Controller::Person; use Moose; use namespace::autoclean; BEGIN {extends 'Catalyst::Controller'; } sub index :Path :Args(0) { my ( $self, $c ) = @_; $c->response->body('Matched AddressBook::Controller::Person in Person.'), } __PACKAGE__->meta->make_immutable; 1; Let's change the sub index controller method to the following sub list : Local { my ($self, $c) = @_; my $people = $c->model('AddressDB::People'), $c->stash->{people} = $people; } 1;
Here, the local list
action gets all the People
out of the database and stores them in $people
(and then in $c->stash->{people}
) and we're done.
That's all the Controller needs to do to create a page like the one in the last screenshot. Now, we just need the list.tt2
template inside root/src/person/list.tt2:
[% META title = 'People' %] [% IF people.count > 0 %] <p>Here are people that I know about:</p> <ul> [% WHILE (person = people.next) %] <li> [% person.name | html %] <a href = "[% c.uri_for("/address/add/$person.id") | html %]">Add address</a> <a href = "[% c.uri_for("/person/edit/$person.id") | html %]">Edit</a> <a href = "[% c.uri_for("/person/delete/$person.id") | html %]">Delete</a> [% SET addresses = person.addresses %] <ul> [% FOREACH address = addresses %] <li> <b>[% address.location | html %]</b> <a href = "[% c.uri_for("/address/edit/$address.id") | html %]">Edit</a> <a href = "[% c.uri_for("/address/delete/$address.id") | html %]">Delete</a> <br /> <address> [% address.postal | html | html_line_break %] </address> Phone: [% address.phone | html %]<br /> Email: [% address.email | html %]<br /> </li> [% END %] </ul> </li> [% END %] </ul> [% ELSE %] <p>No people yet!</p> [% END %] <p><a href ="[% c.uri_for("/person/add") | html %]"> Add a new person... </a></p> </li>
This looks fairly complex, but it's mostly HTML that makes the data from the database look nice. The bulk of the code consists of a WHILE
loop that iterates over each Person
in the database. Once we have a Person
object, we can print out the first name, last name, and some links to pages where we can edit and delete people and addresses (we'll create these pages later). After that, we get an array of addresses associated with this person (from the relationship we added to the schema earlier in the chapter). We iterate over each element in that array and print out the location, postal address, phone number, and e-mail address associated to that address. When there are no more addresses, we return to the WHILE
loop and get the next person
in the database. This continues until everything in the database has been printed.
To see this in action, start up the server, add some new people and addresses to the database (via the sqlite3
utility), and watch them appear on the page at http://localhost:3000/person/list
.
18.119.133.160