PylonsHQ.

Layout: Fixed-width

Getting started with AJAX

Unknown macro: {metadata-list}
Name Getting started with AJAX
Space Pylons CookBook
Section  
Page Getting started with AJAX
Version 1.0
Status Draft
Curator Graham Higgins
Reviewed False
Author(s)  

Getting started with AJAX

Introduction

In here i will show how easy it is to do ajax with Pylons. We will create a simple ping controller allowing you to ping the server in an asynchronous way and display the result handled by the scriptaculous effects library. I assume you have already installed Pylons. (This tutorial has been updated to use mako templating language and some minor fixes)

For simplicity's sake we will just start a new project allowing you to copy-n-paste the code snippets below in order to create something fancy!

1
2
3
paster create -t pylons pingsite
  cd pingsite
  paster serve --reload development.ini

Create the ping controller

First create the ping controller with paster from within your project directory like this:

1
paster controller ping

Modifying the controller

Ok, now we want to actually have our ping controller display something. Edit controllers/ping.py to something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import logging
import datetime

from pingsite.lib.base import *

log = logging.getLogger(__name__)

class PingController(BaseController):
    def index(self):
        return render('/ping.mako')
        
    def pong(self):
        return ("<center>pong!<br/>%s<br/></center>" % 
            (datetime.datetime.now()) )

Now if you go to "http://localhost:5000/ping/pong" you should see your pong reply including a timestamp. Neat huh? But when you try to just open "http://localhost:5000/ping" you will get a server error. Why? Well, it is because we call a template which doesn't exist – yet.

So let's create the template templates/ping.mako:

1
2
3
Hello, welcome to the wonderful ping! controller! 

<div id="pongbox"></div>

Now if we go back to "http://localhost:5000/ping" it should be displaying our friendly message. Cute.

Adding the juices

Making the javascripts accessible

Ok so far it's been really simple. But well, we didn't do anything special yet. Now lets add some javascripts. Pylons comes shipped with the prototype and scriptaculous javascripts. This in combination with the AJAX helpers makes adding AJAX features to your code a breeze!

Telling the browser where to find the javascripts

To tell the client browsers where to find the javascript files, we could change our ping.mako template by adding a few script headers. We would need to do this for every template we create. It is way more elegant to make use of Mako template inheritance and just edit templates/base.mako like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# -*- coding: utf-8 -*-
<html>
  <head>
    ${self.head_tags()}
    ${h.javascript_include_tag(builtins=True)}
  </head>
  <body>
    ${next.body()}
  </body>
</html>

<%def name="head_tags()">
    <title>Override Me!</title>
</%def>

The WebHelpers' javascript_include_tag, when passed the builtins option, would generate the following HTML for us:

1
2
<script src="/javascripts/prototype.js" type="text/javascript"></script>
    <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>

These builtin javascripts are automatically published for you at those locations in your web app. You can overload them via your web app's public directory; in case you want to use different versions. Defining the head_tags() function in templates that inherit from this one allows for additional javascript or CSS files to be included for specific parts of your site.

Making use of the webhelpers

Ok the juices have been added, lets make them flow! All we need to do to set the whole process in motion is editing our ping.mako template to make use of all the MOJO Pylons has. Do it like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# -*- coding: utf-8 -*-
<%inherit file="base.mako" />

<%def name="head_tags()">
    <title>ping example</title>
</%def>

Hello, welcome to the wonderful
${h.link_to_remote("ping!", dict(update="pongbox", url=h.url_for(action='pong')))} 
controller! 

<div id="pongbox"></div>

Ok, now reload "http://localhost:5000/ping" and see what happens. The word 'ping!' has magically changed into a link. Click it! Now isn't that amazing! Actually it amazed me so much that i spent a whole afternoon just clicking the 'ping' word. All we needed to do is call the function link_to_remote from the rails helpers et voila the correct javascript gets generated.

If it sends you to a different page with only the pong output, and doesn't do anything AJAXy, MAKE SURE YOU HAVE JAVASCRIPT ENABLED (d'oh!).

But wait! There is more! We haven't even shown off how easy it is to add scriptaculous effects. Change ping.mako to this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# -*- coding: utf-8 -*-
<%inherit file="base.mako" />

<%def name="head_tags()">
    <title>ping example</title>
    ${h.javascript_include_tag(builtins=True)}
</%def>

Hello, welcome to the wonderfull 
${h.link_to_remote("ping!", dict(update="pongbox", 
url=h.url_for(action='pong'), complete=h.visual_effect('Highlight', "pongbox", duration=1)))} 
controller! 

<div id="pongbox"></div>

Try some other effects like: Shake, Puff (see the list of combination effects at scriptaculous) or create your own! Take a look at the scriptaculous helpers and see how easy it is to create your own draggable items for example.

Have Fun!
Nicholas

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 22, 2008

    Tomasz Narloch says:

    Link to: "combination effects at scriptaculous" not work!!! Maybe "http://github...

    Link to: "combination effects at scriptaculous" not work!!!
    Maybe "http://github.com/madrobby/scriptaculous/wikis" will be correctly.

  2. Jul 19, 2008

    bb says:

    nice. thx. note that for 0.9.2, in the templates, you need to change h.xxx to h....

    nice. thx.
    note that for 0.9.2, in the templates, you need to change h.xxx to h.rails.xxx to make it work.

  3. Jan 20, 2009

    Matt Doar says:

    Very useful introduction. Worked nicely for me with 0.9.6.2

    Very useful introduction. Worked nicely for me with 0.9.6.2

  4. Oct 04, 2009

    Rich Pixley says:

    Hm... "AttributeError: 'module' object has no attribute 'javascript_include_tag...

    Hm... "AttributeError: 'module' object has no attribute 'javascript_include_tag'"


Powered by Pylons - Contact Administrators