The demographics package takes care of person-specific data, for example information about the name of the person (INameInfo), or contact information for a person. These different informational aspects are presented in a menu of “tabs” on the top of the screen when viewing or editing a person.
The demographics package has facilities to display this information in a browsable, batched table form.
The demographics package also has a facility to index this information so that it can be searched. Search results can be browsed.
The person class is subclassed from demographics.person.person.Person. New data is added to the person class using dumb data objects that implement schemas. These data objects need to have a location, as they will have their own views attached to them. This is managed in schooltool.demographics.person. The schemas are defined in schooltool.demographics.interfaces.
Formlib-driven edit and display forms are hooked up to the dumb data classes. This is managed in schooltool.demographics.browser.personform.
The container (IPersonContainer) has attached to it with a zc.table driven view. This view defines the columns visible in the table (including sortability of such columns). This is arranged in schooltool.demographics.browser.table.
The container also has a search page attached to it. The catalog and its indexes are defined in schooltool.demographics.utility. Also there is the implementation of the ISearch interface, which provides the data that is cataloged. The search screen itself is in schooltool.demographics.browser.table.
The demographics package tries to be friendly to customization. If a customization of schooltool wants to install a different Person subclass, it can do so by setting up a different PersonFactory utility. See utility.py for how the demographics package does it.
In general some of the tricky bits have to do with the rendering of things in the context of the parent, not the attribute. This is a drawback of the composition approach in this case. The actualContext method on views – informs the view code to use a different context object for the rendering of the action menu (usually __parent__).
The schooltool.demographics.browser.personform.AttributeMenu not only shows the menu in the context of the parent object, but also creates different relative links for each different object that’s participating in the menu (in this case, different persons). It also highlights the menu we’re currently looking at.
The add form in schooltool.demographics.browser.personform is based on the add form in schooltool.person.browser, but adds an extra required field to it (last_name).
The demographics package chooses subclassing and composition to add new information items to person objects. Compared to a strategy using annotations, or a strategy using a single object implementing multiple schemas (INameInfo, ISchoolData, etc) this has various benefits and drawbacks. Advantages of the attribute strategy are:
Of course there are also valid arguments to be made for the use of annotations, or for the storage of all the attributes on the person object itself. It is as usual in software a matter of tradeoffs. In my (Martijn’s) opinion however, given these arguments, the attributes approach seems a reasonable one to at least try out in the demographics package.