summaryrefslogtreecommitdiff
path: root/posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org
diff options
context:
space:
mode:
authorFranck Cuny <franckcuny@gmail.com>2016-08-04 11:45:44 -0700
committerFranck Cuny <franckcuny@gmail.com>2016-08-04 11:45:44 -0700
commit585b48b6a605cb71ef99dd767880e1b7ee5bf24e (patch)
treec65377350d12bd1e62e0bdd58458c1044541c27b /posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org
parentUse Bullet list for the index. (diff)
parentMass convert all posts from markdown to org. (diff)
downloadlumberjaph-585b48b6a605cb71ef99dd767880e1b7ee5bf24e.tar.gz
Merge branch 'convert-to-org'
Diffstat (limited to 'posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org')
-rw-r--r--posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org199
1 files changed, 199 insertions, 0 deletions
diff --git a/posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org b/posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org
new file mode 100644
index 0000000..5d0b0ef
--- /dev/null
+++ b/posts/2009-05-13-a-simple-feed-aggregator-with-modern-perl-part-4.org
@@ -0,0 +1,199 @@
+We have the model, the aggregator (and some tests), now we can do a
+basic frontend to read our feed. For this I will create a webapp using
+[[http://www.catalystframework.org][Catalyst]].
+
+[[http://search.cpan.org/perldoc?Catalyst::Devel][Catalyst::Devel]] is
+required for developping catalyst application, so we will install it
+first:
+
+#+BEGIN_SRC perl
+ % cpan Catalyst::Devel
+#+END_SRC
+
+Now we can create our catalyst application using the helper:
+
+#+BEGIN_SRC perl
+ % catalyst.pl MyFeedReader
+#+END_SRC
+
+This command initialise the framework for our application
+*MyFeedReader*. A number of files are created, like the structure of the
+MVC directory, some tests, helpers, ...
+
+We start by creating a view, using
+[[http://search.cpan.org/perldoc?Catalyst::View::TT][TTSite]]. TTSite
+generate some templates for us, and the configuration for this template.
+We will also have a basic CSS, a header, footer, etc.
+
+#+BEGIN_EXAMPLE
+ cd MyFeedReader
+ perl script/myfeedreader_create.pl view TT TTSite
+#+END_EXAMPLE
+
+TTSite files are under *root/src* and *root/lib*. A
+*MyAggregator/View/TT.pm* file is also created. We edit it to make it
+look like this:
+
+#+BEGIN_SRC perl
+ __PACKAGE__->config({
+ INCLUDE_PATH => [
+ MyFeedReader->path_to( 'root', 'src' ),
+ MyFeedReader->path_to( 'root', 'lib' )
+ ],
+ PRE_PROCESS => 'config/main',
+ WRAPPER => 'site/wrapper',
+ ERROR => 'error.tt2',
+ TIMER => 0,
+ TEMPLATE_EXTENSION => '.tt2',
+ });
+#+END_SRC
+
+Now we create our first template, in *root/src/index.tt2*
+
+#+BEGIN_EXAMPLE
+ to <a href="/feed/">your feeds</a>
+#+END_EXAMPLE
+
+If you start the application (using
+=perl script/myfeedreader_server.pl=) and point your browser on
+http://localhost:3000/, this template will be rendered.
+
+We need two models, one for KiokuDB and another one for MyModel:
+
+*lib/MyFeedReader/Model/KiokuDB.pm*
+
+#+BEGIN_SRC perl
+ package MyFeedReader::Model::KiokuDB;
+ use Moose;
+ BEGIN { extends qw(Catalyst::Model::KiokuDB) }
+ 1;
+#+END_SRC
+
+we edit the configuration file (*myfeedreader.conf*), and set the dsn
+for our kiokudb backend
+
+#+BEGIN_EXAMPLE
+ <Model KiokuDB>
+ dsn dbi:SQLite:../MyAggregator/foo.db
+ </Model>
+#+END_EXAMPLE
+
+*lib/MyFeedReader/Model/MyModel.pm*
+
+#+BEGIN_SRC perl
+ package MyFeedReader::Model::MyModel;
+ use base qw/Catalyst::Model::DBIC::Schema/;
+ 1;
+#+END_SRC
+
+and the configuration:
+
+#+BEGIN_EXAMPLE
+ <Model MyModel>
+ connect_info dbi:SQLite:../MyModel/model.db
+ schema_class MyModel
+ </Model>
+#+END_EXAMPLE
+
+We got our view and our model, we can do the code for the controller. We
+need 2 controller, one for the feed, and one for the entries. The Feed
+controller will list them and display entries titles for a given feed.
+The Entry controller will just display them.
+
+*lib/MyFeedReader/Controller/Feed.pm*
+
+#+BEGIN_SRC perl
+ package MyFeedReader::Controller::Feed;
+ use strict;
+ use warnings;
+ use parent 'Catalyst::Controller';
+
+ __PACKAGE__->config->{namespace} = 'feed';
+
+ sub index : Path : Args(0) {
+ my ( $self, $c ) = @_;
+ $c->stash->{feeds}
+ = [ $c->model('MyModel')->resultset('Feed')->search() ];
+ }
+
+ sub view : Chained('/') : PathPart('feed/view') : Args(1) {
+ my ( $self, $c, $id ) = @_;
+ $c->stash->{feed}
+ = $c->model('MyModel')->resultset('Feed')->find($id);
+ }
+
+ 1;
+#+END_SRC
+
+The function =index= list the feeds, while the function =view= list the
+entries for a give feed. We use the chained action mechanism to dispatch
+this url, so we can have urls like this */feed/**
+
+We create our 2 templates (for index and view):
+
+*root/src/feed/index.tt2*
+
+#+BEGIN_EXAMPLE
+ <ul>
+ [% FOREACH feed IN feeds %]
+ <li><a href="/feed/view/[% feed.id %]">[% feed.url %]</a></li>
+ [% END %]
+ </ul>
+#+END_EXAMPLE
+
+*root/src/feed/vew.tt2*
+
+#+BEGIN_EXAMPLE
+ <h1>[% feed.url %]</h1>
+
+ <h3>entries</h3>
+ <ul>
+ [% FOREACH entry IN feed.entries %]
+ <li><a href="/entry/[% entry.id %]">[% entry.permalink %]</a></li>
+ [% END %]
+ </ul>
+#+END_EXAMPLE
+
+If you point your browser to http://localhost:3000/feed/ you will see
+this:
+
+Now the controller for displaying the entries:
+
+#+BEGIN_SRC perl
+ package MyFeedReader::Controller::Entry;
+ use strict;
+ use warnings;
+ use MyAggregator::Entry;
+ use parent 'Catalyst::Controller';
+
+ __PACKAGE__->config->{namespace} = 'entry';
+
+ sub view : Chained('/') : PathPart('entry') : Args(1) {
+ my ( $self, $c, $id ) = @_;
+ $c->stash->{entry} = $c->model('KiokuDB')->lookup($id);
+ }
+
+ 1;
+#+END_SRC
+
+The function *view* fetch an entry from the kiokudb backend, and store
+it in the stash, so we can use it in our template.
+
+*root/src/entry/view.tt2*
+
+#+BEGIN_EXAMPLE
+ <h1><a href="[% entry.permalink %]">[% entry.title %]</a></h1>
+ <span>Posted [% entry.date %] by [% entry.author %]</span>
+ <div id="content">
+ [% entry.content %]
+ </div>
+#+END_EXAMPLE
+
+If you point your browser to an entry (something like
+*http://localhost:3000/entry/somesha256value*), you will see an entry:
+
+Et voila, we are done with a really basic feed reader. You can add
+methods to add or delete feed, mark an entry as read, ...
+
+[[http://git.lumberjaph.net/p5-ironman-myfeedreader.git/][The code is
+available on my git server]].