Differences between revisions 1 and 2
Revision 1 as of 2003-07-05 20:02:42
Size: 5983
Editor: inktomi4-lee
Comment:
Revision 2 as of 2003-07-05 20:25:00
Size: 7649
Editor: inktomi4-lee
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== 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.
Line 4: Line 13:
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.
Line 92: Line 109:
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}}}.

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.

from albatross import *
import addressbook
                                                                                
class App(SimpleSessionFileApp):
    '''AddressBook Albatross application'''
                                                                                
    def __init__(self, base_url = '/', base_dir = '.'):
        # Initialise base class
        SimpleSessionFileApp.__init__(
                self,
                base_url = base_url,
                template_path = base_dir,
                start_page = ListPage.name,
                secret = '-=secret=-',
                session_appid = 'AdressBook',
                session_dir = base_dir + '/sessions')
                                                                                
        # Register page(s)
        for page_class in (ListPage,):
            self.register_page(page_class.name, page_class())
                                                                                
                                                                                
class ListPage:
                                                                                
    name = 'list'
                                                                                
    def page_enter(self, ctx):
        # Sort by last_name by default
        ctx.default_session_var('_sort', 'last_name')
                                                                                
    def page_process(self, ctx):
                                                                                
        if ctx.req_equals('sort'):
            # Store the sort attribute in the session var
            ctx.locals._sort = ctx.locals.sort
                                                                                
        elif ctx.req_equals('clear_filter'):
            # Set the filter string to None
            ctx.locals.filter_string = None
                                                                                
    def page_display(self, ctx):
        # Get the list of people, sorting and filtering as necessary
        ctx.locals.people = addressbook.get_all(
                sort=ctx.locals._sort,
                filter=getattr(ctx.locals, 'filter_string', None))
        ctx.run_template('list.html')
                                                                                
                                                                                
# Create an application instance
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.

class Person:
    '''A person'''
    def __init__(self, id, first_name, last_name, email):
        self.id = id
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
                                                                                
                                                                                
# List of people in the "database"
_people = [
    Person(1, 'Michael', 'Neel', 'a@b.c'),
    Person(2, 'Andrew', 'McNamara', 'd@e.f'),
    Person(3, 'Dave', 'Cole', 'g@h.i'),
    Person(4, 'Matt', 'Goodall', 'j@k.l'),
    Person(5, 'Sheila', 'King', 'm@n.o'),
    Person(6, 'Gregory', 'Bond', 'p@q.r'),
    ]
                                                                                
                                                                                
def get_all(sort=None, filter=None):
    '''
    Get all people in the addressbook that match the optional filter,
    optionally sorting the list by attribute name.
    '''
                                                                                
    # Use the full list to start with
    people = _people
                                                                                
    # Filter the people list to remove any that do not match
    if filter:
        filter = filter.lower()
        people = [person for person in people if matches_filter(person, filter)]                                                                                
    # Sort the remaining list by attribute name
    if sort:
        dsu = [(getattr(person, sort), person) for person in people]
        dsu.sort()
        dsu = [item[1] for item in dsu]
        people = dsu
                                                                                
    return people
                                                                                
                                                                                
def matches_filter(person, filter):
    '''
    Return 1 (True) if the filter text appears in any of the attributes
    of person
    '''
    if person.first_name.lower().find(filter) != -1 or \
        person.last_name.lower().find(filter) != -1 or \
        person.email.lower().find(filter) != -1:
        return 1
    return 0

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