Skip to content

UserInterface

Ryo Kawaguchi edited this page Mar 14, 2015 · 2 revisions
« back to DeveloperGuide

Design

This app has a simple purpose: to provide a coordination point for each missing person, where all the people who have or seek information about that person can communicate.

The main UI flow goes like this:

https://sites.google.com/site/zestyping/dropbox/person-finder-ui-flow.png

From the very beginning of the Person Finder project, we decided on a few notable design points:

  • Users make a clear choice between seeking or providing information before doing anything else. The prominence of this decision was motivated by past experience with missing person databases for September 11 and Hurricane Katrina. We learned that it was common for users to be confused about whether they were registering a person they sought, or registering a person they had found. Sometimes this would cause serious problems: a user would enter a record for a person they were looking for, then search and find the record they had just entered, leading them to incorrectly believe the person was found safe. We wanted to avoid this.

  • A search always takes place before data entry, regardless of whether the user is seeking or providing information. During past incidents, duplicate records were common. We wanted to maximize the chance that people looking for the same person, or having information about the same person, would all converge on the same record and get in touch with each other. So we require the user to look at potential duplicates before creating a new record.

  • Information is divided into identifying information and status information by the two-column layout of the pages for viewing and entering information. The two kinds correspond to Person records and Note records in PFIF. This division reflects the differing nature and use of the information:

    • Identifying information is fixed, likely to be known by those seeking, useful for converging on the correct record (e.g. hometown)
    • Status information is changing, not likely to be known by those seeking, useful after having converged on the correct record (e.g. current location)

Rendering

All pages are subclassed from utils.Handler, which contains some convenience methods and an initialize method that runs on every request. The initialize method sets up self.env, a dictionary containing global configuration variables, and self.params, a dictionary containing parsed query parameters from the URL. Some of the variables in env are specific to the subdomain, and others are application-wide. The parsing of the query parameters is controlled by the auto_params dictionary.

The pages are all rendered from Django HTML templates in the app/templates directory, and should be rendered by a call to utils.Handler.render, which passes in the env and params parameters.

Note that all substituted strings in Django templates have to be manually escaped. (We're using Django 0.96, so we don't get the autoescaping features of newer Django versions.) This means inserting |escape after every template parameter, like this: {{first_name|escape}}. Use |escape liberally; always add |escape unless you know you have a specific need to do otherwise. To facilitate security reviews, please keep to the following convention for template variables:

  • Variable names should end in _html if they are known to contain safe HTML.
  • Variable names should end in _js if they are known to contain safe JavaScript.
  • Date variables should be formatted with |date.
  • Boolean variables should be formatted with |yesno.
  • All other variables should be escaped with |escape regardless of whether you think they are safe or not.

Specifying the small=yes query parameter produces a miniature version of the UI intended for embedding (with <iframe>) on other sites.

All of the stylesheets are in static files in the app/static directory.


« back to DeveloperGuide
Clone this wiki locally