| 1 | Web2Py: |
| 2 | * http://mdp.cti.depaul.edu/examples/static/cookbook.pdf |
| 3 | * http://mdp.cti.depaul.edu/examples/static/web2py_cheatsheet.pdf |
| 4 | |
| 5 | MVC (like Rails) |
| 6 | |
| 7 | Model |
| 8 | Defines databases in: /models/db.py (equivalent of inst/mysql-dbcreate.sql) |
| 9 | |
| 10 | Controller |
| 11 | Python functions in /controllers/module.py |
| 12 | e.g. |
| 13 | def list_records(): |
| 14 | list=t2.itemize(table) |
| 15 | return dict (list=list) |
| 16 | |
| 17 | View |
| 18 | HTML/Javascript templates in /views/module/function.html |
| 19 | - these are normal HTML/JS files with the ability to add in Python code (e.g. variables) surrounded by brackets: {{ interpreted python here }} |
| 20 | - there should be an .html file available for each function in the module (name normally being the same as the function) |
| 21 | - 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 |
| 22 | |
| 23 | CSS/Javascript files are stored in /static (equivalent of www/res) |
| 24 | |
| 25 | Python: |
| 26 | * Slow start |
| 27 | - http://openbookproject.net/thinkcs/python/english2e/ |
| 28 | * Quick start |
| 29 | - http://diveintopython.org/ |
| 30 | * v.Quick start! |
| 31 | Indentation matters (use 4 spaces instead of Tabs) |
| 32 | OOP - everything is an object |
| 33 | |
| 34 | T2 is used for AAA & simplified CRUD (inc Conflict Detection) |
| 35 | http://mdp.cti.depaul.edu/examples/static/t2.pdf |
| 36 | We extend the T2 class in modules/sahana.py |
| 37 | |
| 38 | CRUD |
| 39 | Create Record: |
| 40 | Controller |
| 41 | def add_record(): |
| 42 | form=t2.create(db.table) |
| 43 | return dict(form=form) |
| 44 | View |
| 45 | views/module/add_record.html |
| 46 | {{=form}} |
| 47 | Display Record: |
| 48 | Controller |
| 49 | def display_record(): |
| 50 | item=t2.display(db.table) |
| 51 | return dict(item=item) |
| 52 | View |
| 53 | views/module/display_record.html |
| 54 | {{=item}} |
| 55 | Update Record: |
| 56 | Controller |
| 57 | def display_record(): |
| 58 | form=t2.update(db.table) |
| 59 | return dict(form=form) |
| 60 | View |
| 61 | views/module/add_record.html |
| 62 | {{=form}} |
| 63 | Delete Record: |
| 64 | Controller |
| 65 | def delete_record(): |
| 66 | db(db.table.id==t2.id).delete() |
| 67 | response.confirmation=T("Record deleted") |
| 68 | response.view="module/list_records.html" |
| 69 | View |
| 70 | normally not used (reuse existing list_records view) |
| 71 | |
| 72 | |
| 73 | Populate the side navigation Menus by adding this to each controller: |
| 74 | module='module' |
| 75 | # Current Module (for sidebar title) |
| 76 | module_name=db(db.module.name==module).select()[0].name_nice |
| 77 | # List Modules (from which to build Menu of Modules) |
| 78 | modules=db(db.module.enabled=='Yes').select(db.module.ALL,orderby=db.module.menu_priority) |
| 79 | # List Options (from which to build Menu for this Module) |
| 80 | options=db(db['%s_menu_option' % module].enabled=='Yes').select(db['%s_menu_option' % module].ALL,orderby=db['%s_menu_option' % module].priority) |
| 81 | |
| 82 | Each function needs to return these values to the view: |
| 83 | return dict(module_name=module_name,modules=modules,options=options) |
| 84 | |
| 85 | List output can be made more functional by adding this to your table definitions in models/db.py: |
| 86 | db.table.represent=lambda table: A(table.display_field,_href=t2.action('display_table',table.id)) |
| 87 | Form labels can be set in a translatable manner using: |
| 88 | db.table.field.label=T("label") |
| 89 | Form field can be made to use a TEXTAREA by marking the field as being type 'text': |
| 90 | SQLField('field','text'), |
| 91 | Form field can be made to use a SELECT dropdown by setting the field as a lookup to another table: |
| 92 | SQLField('field',db.othertable), |
| 93 | Set this to use a different field than 'id' in the views (e.g. 'name') using: |
| 94 | db.table.field.requires=IS_NULL_OR(IS_IN_DB(db,'othertable.id','othertable.name')) |
| 95 | Form field being required can be marked using: |
| 96 | db.table.field.comment=SPAN("*",_class="req") |
| 97 | Help for a form field can be set using: |
| 98 | A(SPAN("[Help]"),_class="popupLink",_id="tooltip",_title=T("Help|This is what this field is for.")) |
| 99 | |
| 100 | Conflict Detection: |
| 101 | Add this field to each table which needs protecting (in models/db.py): |
| 102 | SQLField('modified_on','datetime'), # Used by T2 to do edit conflict-detection |
| 103 | |
| 104 | AAA |
| 105 | Controller |
| 106 | Each controller which incldues protected functions needs this: |
| 107 | def login(): |
| 108 | response.view='login.html' |
| 109 | return dict(form=t2.login()) |
| 110 | def logout(): t2.logout(next='login') |
| 111 | def register(): |
| 112 | response.view='register.html' |
| 113 | return dict(form=t2.register()) |
| 114 | Each protected function needs this: |
| 115 | @t2.requires_login('login') |
| 116 | def function(): |
| 117 | |
| 118 | |
| 119 | How to add a new module? |
| 120 | - copy existing & edit! |
| 121 | Model |
| 122 | Add module to db.module: |
| 123 | http://127.0.0.1:8000/sahana/appadmin/select/db?query=db.module.id%3E0 |
| 124 | Create a table to store the module's menu options to /models/db.py |
| 125 | db.module_menu_option |
| 126 | Add tables to /models/db.py |
| 127 | Controller |
| 128 | Add CRUD functions for these tables to /views/module.py |
| 129 | View |
| 130 | Add HTML templates for these functions: /views/module/function.html |
| 131 | |
| 132 | How to do Options fields? |
| 133 | Sahana2 has a generic 'field_options' table for storing Options fields/. |
| 134 | Sahana3 uses a separate table for each lookup list |
| 135 | |
| 136 | |
| 137 | Advanced Tricks: |
| 138 | * Python debugging |
| 139 | - use Web2Py shell: http://www.vimeo.com/879939 |
| 140 | - http://docs.python.org/library/doctest.html |
| 141 | - http://docs.python.org/library/bdb.html |
| 142 | * CSS & Javascript debugging |
| 143 | - use Firebug: http://code.google.com/support/bin/answer.py?answer=77412&topic=12044 |
| 144 | * jQuery: |
| 145 | - http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx |
| 146 | * Ext: |
| 147 | - http://extjs.com/learn/Tutorial:Introduction_to_Ext_2.0 |
| 148 | - http://extjs.com/learn/Manual:Basic_Application_Design |
| 149 | - http://extjs.com/forum/showthread.php?t=26728 |
| 150 | - http://extjs.com/learn/Ext_FAQ_Debugging |