wiki:DeveloperGuidelines

Version 2 (modified by Fran Boon, 16 years ago) ( diff )

--

Web2Py:

MVC (like Rails)

Model

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

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)
  • 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)

Python:

T2 is used for AAA & simplified CRUD (inc Conflict Detection) http://mdp.cti.depaul.edu/examples/static/t2.pdf We extend the T2 class in modules/sahana.py

CRUD Create Record:

Controller

   def add_record():
       form=t2.create(db.table)
       return dict(form=form)

View

views/module/add_record.html

     {{=form}}

Display Record:

Controller

   def display_record():
       item=t2.display(db.table)
       return dict(item=item)

View

views/module/display_record.html

     {{=item}}

Update Record:

Controller

   def display_record():
       form=t2.update(db.table)
       return dict(form=form)

View

views/module/add_record.html

     {{=form}}

Delete Record:

Controller

   def delete_record():
   db(db.table.id==t2.id).delete()
   response.confirmation=T("Record deleted")
   response.view="module/list_records.html"

View

normally not used (reuse existing list_records view)

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 adding this to your table definitions in models/db.py:

db.table.represent=lambda table: A(table.display_field,_href=t2.action('display_table',table.id))

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:

SQLField('field',db.othertable),

Set this to use a different field than 'id' in the views (e.g. 'name') using:

db.table.field.requires=IS_NULL_OR(IS_IN_DB(db,'othertable.id','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|This is what this field is for."))

Conflict Detection: 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

AAA

Controller

Each controller which incldues protected functions needs this:

   def login():
       response.view='login.html'
	   return dict(form=t2.login())
   def logout(): t2.logout(next='login')
   def register():
	   response.view='register.html'
	   return dict(form=t2.register())
  Each protected function needs this:
   @t2.requires_login('login')
   def function():

How to add a new module?

  • copy existing & edit! Model

Add module to db.module:

http://127.0.0.1:8000/sahana/appadmin/select/db?query=db.module.id%3E0

Create a table to store the module's menu options to /models/module.py

db.module_menu_option

Add tables to /models/module.py

db.module_table

Controller

Add CRUD functions for these tables to /views/module.py

View

Add HTML templates for these functions: /views/module/function.html

How to do Options fields? Sahana2 has a generic 'field_options' table for storing Options fields/. Sahana3 uses a separate table for each lookup list

Advanced Tricks:

Note: See TracWiki for help on using the wiki.