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