Introduction

This is a simple example of an application that displays a list of people in an addressbook. The list can be sorted (by clicking on a table header) and filtered.

Note that the sort attribute is stored in a session variable whereas the filter string is not. That was purely to add a bit of interest to the application.

Running the Application

Put all of the files in an empty directory and create a subdirectory called "sessions" to store session data. Use "al-httpd app.app 8000" to start the application on port 8000.

Source Code

app.py

This is the application's main module. It containts the Albatross application. The App class should be fairly self explanatory (if you read the excellent documentation) but I will describe the ListPage class a little.

ListPage.page_enter() is called the first time the page is requested. The method ensures that the default sort attribute is set, if it did not exist already.

ListPage.page_process() processes requests sent to the page. If the request was a 'sort' (one of the table headers was clicked) then the new sort attribute is copied to the session variable' if the request was a 'clear_filter' then the filter string is reset to None.

ListPage.page_display() is called to display the page. It first retrieves a list of people. The list is sorted by the attribute name in the session variable and filtered by the filter string (if any). It then renders the page by running the template.

   1 from albatross import *
   2 import addressbook
   3                                                                                 
   4 class App(SimpleSessionFileApp):
   5     '''AddressBook Albatross application'''
   6                                                                                 
   7     def __init__(self, base_url = '/', base_dir = '.'):
   8         # Initialise base class
   9         SimpleSessionFileApp.__init__(
  10                 self,
  11                 base_url = base_url,
  12                 template_path = base_dir,
  13                 start_page = ListPage.name,
  14                 secret = '-=secret=-',
  15                 session_appid = 'AdressBook',
  16                 session_dir = base_dir + '/sessions')
  17                                                                                 
  18         # Register page(s)
  19         for page_class in (ListPage,):
  20             self.register_page(page_class.name, page_class())
  21                                                                                 
  22                                                                                 
  23 class ListPage:
  24                                                                                 
  25     name = 'list'
  26                                                                                 
  27     def page_enter(self, ctx):
  28         # Sort by last_name by default
  29         ctx.default_session_var('_sort', 'last_name')
  30                                                                                 
  31     def page_process(self, ctx):
  32                                                                                 
  33         if ctx.req_equals('sort'):
  34             # Store the sort attribute in the session var
  35             ctx.locals._sort = ctx.locals.sort
  36                                                                                 
  37         elif ctx.req_equals('clear_filter'):
  38             # Set the filter string to None
  39             ctx.locals.filter_string = None
  40                                                                                 
  41     def page_display(self, ctx):
  42         # Get the list of people, sorting and filtering as necessary
  43         ctx.locals.people = addressbook.get_all(
  44                 sort=ctx.locals._sort,
  45                 filter=getattr(ctx.locals, 'filter_string', None))
  46         ctx.run_template('list.html')
  47                                                                                 
  48                                                                                 
  49 # Create an application instance
  50 app = App()

list.html

<html>
  <head>
    <title>Address Book</title>
  </head>
  <body>
    <p>Sorted by <al-value expr="_sort" /></p>
    <p>
      <al-form method="post">
        <al-input type="text" name="filter_string" />
        <al-input type="submit" name="filter" value="Filter" />
        <al-input type="submit" name="clear_filter" value="Clear" />
      </al-form>
    </p>
    <table>
      <tr>
        <th><al-a href="sort=first_name">First Name</al-a></th>
        <th><al-a href="sort=last_name">Last Name</al-a></th>
        <th><al-a href="sort=email">Email</al-a></th>
      </tr>
      <al-for iter="iter" expr="people">
        <al-exec expr="person = iter.value()" />
        <tr>
          <td><al-value expr="person.first_name" /></td>
          <td><al-value expr="person.last_name" /></td>
          <td><al-value expr="person.email" /></td>
        </tr>
      </al-for>
    </table>
  </body>
</html>

addressbook.py

This module is a pretend database. It defines a class, Person, a pretend table of data, _people and a function to retrieve the list of people, get_all.

   1 class Person:
   2     '''A person'''
   3     def __init__(self, id, first_name, last_name, email):
   4         self.id = id
   5         self.first_name = first_name
   6         self.last_name = last_name
   7         self.email = email
   8                                                                                 
   9                                                                                 
  10 # List of people in the "database"
  11 _people = [
  12     Person(1, 'Michael', 'Neel', 'a@b.c'),
  13     Person(2, 'Andrew', 'McNamara', 'd@e.f'),
  14     Person(3, 'Dave', 'Cole', 'g@h.i'),
  15     Person(4, 'Matt', 'Goodall', 'j@k.l'),
  16     Person(5, 'Sheila', 'King', 'm@n.o'),
  17     Person(6, 'Gregory', 'Bond', 'p@q.r'),
  18     ]
  19                                                                                 
  20                                                                                 
  21 def get_all(sort=None, filter=None):
  22     '''
  23     Get all people in the addressbook that match the optional filter,
  24     optionally sorting the list by attribute name.
  25     '''
  26                                                                                 
  27     # Use the full list to start with
  28     people = _people
  29                                                                                 
  30     # Filter the people list to remove any that do not match
  31     if filter:
  32         filter = filter.lower()
  33         people = [person for person in people if matches_filter(person, filter)]                                                                                
  34     # Sort the remaining list by attribute name
  35     if sort:
  36         dsu = [(getattr(person, sort), person) for person in people]
  37         dsu.sort()
  38         dsu = [item[1] for item in dsu]
  39         people = dsu
  40                                                                                 
  41     return people
  42                                                                                 
  43                                                                                 
  44 def matches_filter(person, filter):
  45     '''
  46     Return 1 (True) if the filter text appears in any of the attributes
  47     of person
  48     '''
  49     if person.first_name.lower().find(filter) != -1 or \
  50         person.last_name.lower().find(filter) != -1 or \
  51         person.email.lower().find(filter) != -1:
  52         return 1
  53     return 0

None: Data_Presentation (last edited 2011-02-15 06:05:18 by localhost)