wiki:DeveloperGuidelines

Version 37 (modified by Fran Boon, 13 years ago) ( diff )

Change bottom section to list to make more usable

Install a Development Environment

InstallationGuidelinesDeveloper

Python

Indentation matters (use 4 spaces instead of Tabs)

Web2Py

This is an MVC environment (like Rails & Django).

Web2Py can work at several different levels of abstraction.
The Sahana 3 (S3) framework is mainly built on the simplified T2 level, however sometimes we need more control therefore need to drop down a level or two.

Web2py also includes a T3 level of abstraction, but we're not using that currently.

Model

Defines databases in: /models/module.py (equivalent of inst/mysql-dbcreate.sql)

The Models are loaded 1st within Web2Py processing, before the controllers. So you can import any global modules/set any global variables here. The Models are imported in alphabetical order, so we load the files which other modules depend on 1st, hence naming them with an underscore: _db.py, _gis.py

Controller

Python functions in /controllers/module.py

e.g.

   def list_records():
       list=t2.itemize(table)
       return dict (list=list)

View

HTML/Javascript templates in /views/module/function.html

  • these are normal HTML/JS files with the ability to add in Python code (e.g. variables) surrounded by brackets: {{ interpreted python here }}
  • there should be an .html file available for each function in the module (name normally being the same as the function)
  • these normally inherit from views/layout.html which also includes the Javascript from views/web2py_ajax_t2.html
  • if there is no view defined then a default view will be displayed, which will show the values of all the data it can see, but not be formatted nicely

CSS/Javascript files are stored in /static (equivalent of www/res)

Sahana3 Framework

We have built an S3 framework as a higher level of abstraction on top of T2.
This should be used by modules where possible, but if more power is needed then drop down a level of two (to T2, to base Web2Py or to raw Python).

T2 is used for:

  • AAA
  • simplified CRUD
  • Conflict Detection)

We extend the T2 class in modules/sahana.py

Populate the side navigation Menus by adding this to each controller:

module='module'
# Current Module (for sidebar title)
module_name=db(db.module.name==module).select()[0].name_nice
# List Modules (from which to build Menu of Modules)
modules=db(db.module.enabled=='Yes').select(db.module.ALL,orderby=db.module.menu_priority)
# List Options (from which to build Menu for this Module)
options=db(db['%s_menu_option' % module].enabled=='Yes').select(db['%s_menu_option' % module].ALL,orderby=db['%s_menu_option' % module].priority)

Each function needs to return these values to the view:

return dict(module_name=module_name,modules=modules,options=options)

List output can be made more functional by this .represent 'widget':

def shn_list_item(table,resource,action,display='table.name',extra=None):
    if extra:
        items=DIV(TR(TD(A(eval(display),_href=t2.action(resource,[action,table.id]))),TD(eval(extra))))
    else:
        items=DIV(A(eval(display),_href=t2.action(resource,[action,table.id])))
    return DIV(*items)

You can use it in models/module.py like:

db.or_organisation.represent=lambda table:shn_list_item(table,resource='organisation',action='display')
db.person.represent=lambda table:shn_list_item(table,resource='person',action='display',display='table.full_name')
db.gis_projection.represent=lambda table:shn_list_item(table,resource='projection',action='display',extra='table.epsg')

Form labels can be set in a translatable manner using:

db.table.field.label=T("label")

Form field can be made to use a TEXTAREA by marking the field as being type 'text':

SQLField('field','text'),

Form field can be made to use a SELECT dropdown by setting the field as a lookup to another table...linked to the 'uuid' field to allow Database Synchronization, but displaying a more user-friendly field (such as 'name'):

SQLField('field',length=64),

db.table.field.requires=IS_NULL_OR(IS_IN_DB(db,'othertable.uuid','othertable.name'))

Form field being required can be marked using:

db.table.field.comment=SPAN("*",_class="req")

Help for a form field can be set using:

A(SPAN("[Help]"),_class="popupLink",_id="tooltip",_title=T("Help Title|This is what this field is for."))

Different Flash styles can be set via:

session.error=T("Unsupported format!")
redirect(URL(r=request,f=resource))

or (in a Multiple Table form.accepts):

response.error=T("Form invalid!")

Supported styles are:

  • .warning
  • .error
  • .information
  • .confirmation (Standard T2 Flash messages are usually of this sort so we class them in the same way)

jQuery Widgets

DeveloperGuidelinesDeletableList

Options fields

Sahana2 has a generic 'field_options' table for storing Options fields.

Sahana3 uses a separate table for each lookup list.

Conflict Detection

Sahana is a multi-user system so there is a potential for multiple users to be editing the same record at once.
We use T2 to handle this for us.

Add this field to each table which needs protecting (in models/db.py):

SQLField('modified_on','datetime'), # Used by T2 to do edit conflict-detection

This field is also used in Database Synchronization


Translations of this page

Note: See TracWiki for help on using the wiki.