The shortest Ajax+Catalyst tutorial in the world

Published · Friday, 6 March 2009 (Updated · 7 March 2010)

And the most terse. I might add explanations later; for now, it’s just sing-along. Crucial or notable bits of XHTML/JS are in bold or highlighted. Click on command lines to see results or further needed input/action.

jinx@jasper[1]~>catalyst.pl MyApp
created "MyApp"
created "MyApp/script"
created "MyApp/lib"
created "MyApp/root"
created "MyApp/root/static"
created "MyApp/root/static/images"
created "MyApp/t"
created "MyApp/lib/MyApp"
created "MyApp/lib/MyApp/Model"
created "MyApp/lib/MyApp/View"
created "MyApp/lib/MyApp/Controller"
created "MyApp/myapp.conf"
created "MyApp/lib/MyApp.pm"
created "MyApp/lib/MyApp/Controller/Root.pm"
created "MyApp/README"
created "MyApp/Changes"
created "MyApp/t/01app.t"
created "MyApp/t/02pod.t"
created "MyApp/t/03podcoverage.t"
created "MyApp/root/static/images/catalyst_logo.png"
created "MyApp/root/static/images/btn_120x50_built.png"
created "MyApp/root/static/images/btn_120x50_built_shadow.png"
created "MyApp/root/static/images/btn_120x50_powered.png"
created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
created "MyApp/root/static/images/btn_88x31_built.png"
created "MyApp/root/static/images/btn_88x31_built_shadow.png"
created "MyApp/root/static/images/btn_88x31_powered.png"
created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
created "MyApp/root/favicon.ico"
created "MyApp/Makefile.PL"
created "MyApp/script/myapp_cgi.pl"
created "MyApp/script/myapp_fastcgi.pl"
created "MyApp/script/myapp_server.pl"
created "MyApp/script/myapp_test.pl"
created "MyApp/script/myapp_create.pl"
jinx@jasper[2]~>cd MyApp
jinx@jasper[3]~/MyApp>./script/myapp_create.pl view TT TT
 exists "/Users/jinx/MyApp/script/../lib/MyApp/View"
 exists "/Users/jinx/MyApp/script/../t"
created "/Users/jinx/MyApp/script/../lib/MyApp/View/TT.pm"
created "/Users/jinx/MyApp/script/../t/view_TT.t"
jinx@jasper[4]~/MyApp>./script/myapp_create.pl view JSON JSON
 exists "/Users/jinx/MyApp/script/../lib/MyApp/View"
 exists "/Users/jinx/MyApp/script/../t"
created "/Users/jinx/MyApp/script/../lib/MyApp/View/JSON.pm"
created "/Users/jinx/MyApp/script/../t/view_JSON.t"
jinx@jasper[5]~/MyApp>emacs lib/MyApp/Controller/Root.pm
# Edit index() and add ajax() as shown-

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;
    $c->detach( $c->view("TT") );
}

my @fake_model =
    (
      "OH HAI, I CAN HAZ AJAKS?",
      "I haz a buckit.",
      "They be stealin' my bucket!",
      "I can has cheezburger?",
      "IZ LOLCATALIST!",
      "<a href='http://docs.jquery.com/Ajax'>docs.jquery.com/Ajax</a>",
      "You better getz <a href='http://getfirebug.com/'>BUGZEZ ON FIRE</a>",
      "Ashly rulz!",
     );

sub ajax :Local {
    my ( $self, $c ) = @_;
    my $quote = $fake_model[rand @fake_model];
    $c->stash(quote => $quote);
    $c->detach( $c->view("JSON") );
}
jinx@jasper[6]~/MyApp>emacs root/index.tt
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"
  xml:lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Basic Document</title>
<style type="text/css" media="screen">
  /* style stub for you */
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"
  type="text/javascript"></script>
</head>

<body>

<div class="content">
<h1>Random quotes via Ajax… well, Ajaj really</h1>

<noscript><h2>You should account for a lack of
  JS even if just to announce it’s needed</h2></noscript>

<p id="convenient">
Click me for a quote!
</p>

<div class="reuseable">
</div>

<script type="text/javascript">//<![CDATA[
jQuery(function($) {
  $("#convenient")
    .css({cursor:"pointer"})
    .click(function(){
           $.ajax({
                   type: "GET"
                  ,url: "[% c.uri_for("ajax") %]"
                  ,dataType: "json"
                  ,cache: false
                  ,success: function(json){
                               var $pq = $("<span>" + json.quote + "</span>");
                               $pq.hide();
                               if ( $(".reuseable").children().size() > 0 )
                                      $(".reuseable").append(" &middot; ");
                               $(".reuseable").append($pq);
                               $pq.fadeIn();
                            }
                   });
     });
});
//]]> </script>

</div>

</body>
</html>
jinx@jasper[7]~/MyApp>./script/myapp_server.pl -d -r -k
[debug] Debug messages enabled
[debug] Statistics enabled
[debug] Loaded plugins:
.----------------------------------------------------------------------------.
| Catalyst::Plugin::ConfigLoader  0.22                                       |
| Catalyst::Plugin::Static::Simple  0.20                                     |
'----------------------------------------------------------------------------'

[debug] Loaded dispatcher "Catalyst::Dispatcher"
[debug] Loaded engine "Catalyst::Engine::HTTP::Restarter"
[debug] Found home "/Users/jinx/MyApp"
[debug] Loaded Config "/Users/jinx/MyApp/myapp.conf"
[debug] Loaded components:
.-----------------------------------------------------------------+----------.
| Class                                                           | Type     |
+-----------------------------------------------------------------+----------+
| MyApp::Controller::Root                                         | instance |
| MyApp::View::JSON                                               | instance |
| MyApp::View::TT                                                 | instance |
'-----------------------------------------------------------------+----------'

[debug] Loaded Private actions:
.----------------------+--------------------------------------+--------------.
| Private              | Class                                | Method       |
+----------------------+--------------------------------------+--------------+
| /default             | MyApp::Controller::Root              | default      |
| /end                 | MyApp::Controller::Root              | end          |
| /ajax                | MyApp::Controller::Root              | ajax         |
| /index               | MyApp::Controller::Root              | index        |
'----------------------+--------------------------------------+--------------'

[debug] Loaded Path actions:
.-------------------------------------+--------------------------------------.
| Path                                | Private                              |
+-------------------------------------+--------------------------------------+
| /                                   | /default                             |
| /                                   | /index                               |
| /ajax                               | /ajax                                |
'-------------------------------------+--------------------------------------'

[info] MyApp powered by Catalyst 5.71000
You can connect to your server at http://jasper.local:3000


digg stumbleupon del.icio.us reddit Fark Technorati Faves

Catalyst+Ajax: How to get a preview pane for a textarea which even supports live previewing of JavaScript »
« Catalyst related articles »