== 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. {{{ #!python 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 === {{{ Address Book

Sorted by

First Name Last Name Email
}}} === 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}}}. {{{ #!python 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 }}}