Notes from a Newbie Experiment 01: Simple Dynamic Content and Links
Notes from a Newbie document the creation and deployment of yardbirdfanclub.org with Perl Catalyst on shared hosting. They are intended for a Perl Catalyst Newbie who would like to study the creation and deployment of a Perl Catalyst application.
In these notes I begin to explore what it might take to create a blog application.
- What Can I Do With A Database?
- What Will It Take To Create A Blog With Catalyst And MySQL?
- Simple Dynamic Content and Links
What Can I Do With A Database?
Using what I learned in Catalyst::Tutorial and other perldocs, I want to learn to design and use a simple database in a Catalyst application of my own design, and deploy it on the Internet.
What Will It Take To Create A Blog With Catalyst And MySQL?
Wondering but not really caring if there are better ways to create blogs with Perl Catalyst, I decide to explore what it might take to create a database and use it to blog.
I ask myself:
- What do you want your pages to look like?
- What database details will you need to use and understand?
I worked through Catalyst::Manual::Tutorial.
I farted around with DBIx::Class::Manual but found these the most useful, they explain how to use a database specifically with Catalyst:
- Catalyst::Manual::Tutorial::03_MoreCatalystBasics
- Catalyst::Manual::Tutorial::04_BasicCRUD
- Catalyst::Manual::Tutorial::05_Authentication
- Catalyst::Manual::Tutorial::06_Authorization
- Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler
These were especially helpful too:
- DBIx::Class::Row
- DBIx::Class::ResultSource
- DBIx::Class::ResultSet
- DBIx::Class::Relationship
- HTML::FormHandler::Manual::Tutorial
- HTML::FormHandler::Manual::Catalyst
Viewing Perl documentation with a web browser works pretty good, I use Perldoc::Server.
I know very little HTML or CSS, just a little from the Internet and a CSS book I worked through. Same goes for Perl, I studied a couple Perl books and am strictly an entry-level Perl Catalyst Newbie.
With meager skills I set out to create and deploy a meager blog with Perl Catalyst and MySQL, not very original but it's the best I came up with.
blogs.perl.org
I've not used or seen many blogs, but I like the design of blogs.perl.org. I wondered if I might be able to create one similarly?
Simple Dynamic Content and Links
Simple-minded as I am, I ask myself how the blogs.perl.org blog titles are made into links?
Create MySQL Database
What might a blog database table contain?
- id (primary key)
- userid (foreign key)
- title
- content
You may be wondering about the userid column, what am I using it for?
After doing some experiments, I will create my Yardbird Catalyst application starting with authentication and authorization as explained in:
- Catalyst::Manual::Tutorial::05_Authentication
- Catalyst::Manual::Tutorial::06_Authorization
Anticipating not only user and blog tables but a blog_comment table as well, the userid foreign key will give the Yardbird application access to a blog author's name and other personal info via the blog table. The userid foreign key also enables the ability to cascade edit and delete, greatly decreasing coding effort while increasing reliability.
What happens when a member of The YARDBIRD Fan Club no-longer wants to be a member? Will I want to delete the user but keep the user's blog entries and comments? No way, be done with them, but how? This is where the cascade edit/delete feature comes in. When a user is removed I also want that user's blog entries and comments to be deleted too.
What would you rather do, search for and delete each blog entry and comment individually, or have the application delete them automatically for you?
The blog table's foreign key userid provides the means for blog rows to automatically be (cascade) deleted when corresponding user's are deleted.
The blog table's foreign key userid also allows the application to access user table information, such as a blog author's name, through the blog table. This is very important!
I want to keep this example simple so I won't declare userid to be a foreign key yet, but I will do so later.
yardbird00.sql
CREATE TABLE blog (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
userid INT UNSIGNED NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO blog (id, userid, title, content) VALUES (1, 1, 'title id: 1 userid: 1', 'content id: 1 userid: 1');
INSERT INTO blog (id, userid, title, content) VALUES (2, 1, 'title id: 2 userid: 1', 'content id: 2 userid: 1');
INSERT INTO blog (id, userid, title, content) VALUES (3, 1, 'title id: 3 userid: 1', 'content id: 3 userid: 1');
mysql> create database yardbird00;
> mysql -uusername -ppassword
mysql> create database yardbird00;
mysql> quit;
> mysql -uusername -ppassword yardbird00 < yardbird00.sql
> mysql -uusername -ppassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| yardbird00 |
+--------------------+
mysql> use yardbird00;
mysql> show tables;
+----------------------+
| Tables_in_yardbird00 |
+----------------------+
| blog |
+----------------------+
mysql> describe blog;
+---------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| userid | int(10) unsigned | NO | | NULL | |
| title | text | NO | | NULL | |
| content | text | NO | | NULL | |
+---------+------------------+------+-----+---------+----------------+
mysql> select * from blog;
+----+--------+-----------------------+-------------------------+
| id | userid | title | content |
+----+--------+-----------------------+-------------------------+
| 1 | 1 | title id: 1 userid: 1 | content id: 1 userid: 1 |
| 2 | 1 | title id: 2 userid: 1 | content id: 2 userid: 1 |
| 3 | 1 | title id: 3 userid: 1 | content id: 3 userid: 1 |
+----+--------+-----------------------+-------------------------+
mysql> quit;
Create Catalyst Application
> catalyst.pl Yardbird
Yardbird> perl Makefile.PL
Yardbird> script/yardbird_create.pl view TT TT
Yardbird> script/yardbird_create.pl model DB DBIC::Schema \
Yardbird> Yardbird::Schema create=static dbi:mysql:yardbird00 username password
Yardbird/root/index.tt:
hello world
Yardbird/lib/Yardbird/Controller/Root.pm:
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
$c->detach($c->view("TT"));
}
Run the application:
Yardbird> script/yardbird_server.pl -r
The browser gives:
Use Database in Catalyst Application
Yardbird/lib/Yardbird/Controller/Root.pm:
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
my $rs = $c->model('DB::Blog')->search({});
my $blog = $rs->next;
$c->stash->{t1} = $blog->title;
$c->stash->{c1} = $blog->content;
$blog = $rs->next;
$c->stash->{t2} = $blog->title;
$c->stash->{c2} = $blog->content;
$blog = $rs->next;
$c->stash->{t3} = $blog->title;
$c->stash->{c3} = $blog->content;
$c->detach($c->view("TT"));
}
Yardbird/root/index.tt:
<h1>Take A Ride</h1>
<p>[% t1 %]</p>
<p>[% c1 %]</p>
<p>[% t2 %]</p>
<p>[% c2 %]</p>
<p>[% t3 %]</p>
<p>[% c3 %]</p>
The browser gives:
Make Content and Links Dynamic
Links
Yardbird/lib/Yardbird/Controller/Root.pm:
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
my $rs = $c->model('DB::Blog')->search({});
my $blog = $rs->next;
$c->stash->{t1} = $blog->title;
$c->stash->{c1} = $blog->content;
$c->stash->{id1} = $blog->id;
$blog = $rs->next;
$c->stash->{t2} = $blog->title;
$c->stash->{c2} = $blog->content;
$c->stash->{id2} = $blog->id;
$blog = $rs->next;
$c->stash->{t3} = $blog->title;
$c->stash->{c3} = $blog->content;
$c->stash->{id3} = $blog->id;
$c->detach($c->view("TT"));
}
sub blog :Path('blog') :Args(1) {
my ( $self, $c, $id ) = @_;
$c->stash->{id} = $id;
$c->detach($c->view("TT"));
}
Yardbird/root/index.tt:
<h1>Take A Ride...</h1>
<p><a href="[% c.uri_for_action('/blog', id1) %]">[% t1 %]</a></p>
<p>[% c1 %]</p>
<p><a href="[% c.uri_for_action('/blog', id2) %]">[% t2 %]</a></p>
<p>[% c2 %]</p>
<p><a href="[% c.uri_for_action('/blog', id3) %]">[% t3 %]</a></p>
<p>[% c3 %]</p>
Yardbird/root/blog.tt:
<h1>...On The Wild Side.</h1>
<p>[% id %]</p>
The browser gives:
Selecting the first title gives:
Improve Code
Yardbird/lib/Yardbird/Controller/Root.pm:
package Yardbird::Controller::Root;
use Moose;
use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller' }
__PACKAGE__->config(namespace => '');
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
$c->stash(blog_entries => [$c->model('DB::Blog')->search({})]);
$c->detach($c->view("TT"));
}
sub blog :Path('blog') :Args(1) {
my ( $self, $c, $id ) = @_;
$c->stash(blog_entry => $c->model('DB::Blog')->search({id => $id}));
$c->detach($c->view("TT"));
}
sub default :Path {
my ( $self, $c ) = @_;
$c->response->body( 'Page not found' );
$c->response->status(404);
}
sub end : ActionClass('RenderView') {}
__PACKAGE__->meta->make_immutable;
1;
Yardbird/root/index.tt:
<h3>Take A Ride...</h3>
[% FOREACH blog_entry IN blog_entries %]
<p><a href="[% c.uri_for_action('/blog', blog_entry.id) %]">[% blog_entry.title %]</a></p>
<p>[% blog_entry.content %]</p>
[% END %]
Yardbird/root/blog.tt:
<h3>On The Wild Side.</h3>
<p>blog_entry.id: [% blog_entry.id %]</p>
<p>blog_entry.title: [% blog_entry.title %]</p>
<p>blog_entry.content: [% blog_entry.content %]</p>
The browser gives:
Selecting the third title gives:
We have finished the difficult part, it will get much easier now.
Leave a comment