| | 1 | [wiki:DeveloperGuidelines] | S3 |
| | 2 | |
| | 3 | = S3 Framework Extensions for Web2py = |
| | 4 | |
| | 5 | All S3 framework extensions for web2py reside as a Python package in {{{modules/s3}}}: |
| | 6 | |
| | 7 | ||'''Module'''||'''Functionality'''|| |
| | 8 | ||s3aaa||Authentication, Authorization, Accouting|| |
| | 9 | ||s3cfg||Deployment Settings|| |
| | 10 | ||s3gis||GIS Module|| |
| | 11 | ||s3msg||Messaging API|| |
| | 12 | ||s3test|| || |
| | 13 | ||s3tools||Tools|| |
| | 14 | ||s3utils||Utilities|| |
| | 15 | ||s3validators||Custom Validators|| |
| | 16 | ||s3vita||Person Finder Toolkit (VITA)|| |
| | 17 | ||s3widgets||Custom UI Widgets|| |
| | 18 | ||s3xrc||Extensible Resource Controller (S3XRC)|| |
| | 19 | ||s3rest||RESTful API (S3XRC)|| |
| | 20 | ||s3crud||RESTful CRUD Methods (S3XRC)|| |
| | 21 | ||s3search||RESTful Search Methods|| |
| | 22 | ||s3export||Resource Export Toolkit (S3XRC)|| |
| | 23 | ||s3import||Resource Import Toolkit (S3XRC)|| |
| | 24 | ||s3model||Data Model Extensions (S3XRC)|| |
| | 25 | ||s3xml||XML Toolkit (S3XML)|| |
| | 26 | |
| | 27 | == The s3base Namespace == |
| | 28 | |
| | 29 | The names of the S3 package (=classes, functions, constants) are defined in {{{modules/s3/__init__.py}}} - all names which are imported in this file are available under the {{{s3base}}} namespace. |
| | 30 | |
| | 31 | This namespace is imported in {{{models/000_1st_run.py}}}, thus it is available to ''all'' models and controllers - you don't need to import any S3 names separately, and neither do you need to think under which namespace a S3 class or function is available: always simply use the {{{s3base}}} prefix: |
| | 32 | |
| | 33 | {{{ |
| | 34 | gis = s3base.GIS(...) |
| | 35 | resource = s3base.S3Resource(...) |
| | 36 | }}} |
| | 37 | |
| | 38 | For convenience, the names of {{{s3utils}}}, {{{s3widgets}}} and {{{s3validators}}} are also imported into the global namespace, so you do not need a namesace prefix to access them: |
| | 39 | |
| | 40 | {{{ |
| | 41 | mytable.myfield.requires = IS_UTC_DATETIME() |
| | 42 | mywidget = S3CheckboxWidget.widget() |
| | 43 | }}} |
| | 44 | |
| | 45 | == Extending S3 == |
| | 46 | |
| | 47 | If you're going to add things to S3, please do it at the right place: |
| | 48 | |
| | 49 | - Utility functions which are meant to be globally available belong into {{{modules/s3/s3utils.py}}} |
| | 50 | - All other utility functions should either be class methods or should not be globally available |
| | 51 | - New classes should be added to the respective modules |
| | 52 | - New modules should be added as separate files |
| | 53 | |
| | 54 | To make a class, function or constant available in the {{{s3base}}} namespace, you should import it in {{{modules/s3/__init__.py}}}: |
| | 55 | |
| | 56 | {{{ |
| | 57 | from s3xrc import S3ResourceController |
| | 58 | }}} |
| | 59 | |
| | 60 | Note that you need to use the {{{from s3xxx import yyy}}} notation (relative import). |
| | 61 | |
| | 62 | == Importing Modules == |
| | 63 | |
| | 64 | Any submodule in modules/s3 can import names from any other submodule in modules/s3 by simply {{{from s3xxx import yyy}}}, by relative import: |
| | 65 | |
| | 66 | {{{ |
| | 67 | from s3xrc import S3ResourceController |
| | 68 | }}} |
| | 69 | |
| | 70 | If you use the wildcard: |
| | 71 | |
| | 72 | {{{ |
| | 73 | from s3xxx import * |
| | 74 | }}} |
| | 75 | |
| | 76 | then you have to ensure that the name you want to import is listed in the {{{__all__}}} variable inside the respective {{{s3xxx}}} submodule: |
| | 77 | |
| | 78 | {{{ |
| | 79 | __all__ = ["MyClass", "MyOtherClass"] |
| | 80 | }}} |
| | 81 | |
| | 82 | If {{{__all___}}} is not declared inside a submodule, then all names are imported - but this should be avoided. |
| | 83 | |
| | 84 | You can also import names from other modules in the {{{modules}}} directory, by relative import: |
| | 85 | |
| | 86 | {{{ |
| | 87 | from ..pyparsing import ParseBaseException |
| | 88 | }}} |
| | 89 | |
| | 90 | Note the {{{..}}} before the module path. |
| | 91 | |
| | 92 | == Coding Conventions == |
| | 93 | |
| | 94 | Please consider our coding conventions when coding S3 extensions: |
| | 95 | |
| | 96 | - names of top-level functions must be prefixed by {{{s3_}}}, must be all lowercase (no CamelCase!), with words separated by underscores, e.g. {{{s3_my_function}}} |
| | 97 | - names of genuine S3 classes (even if based on web2py classes) must be prefixed by S3, and use CamelCase, e.g. {{{S3ResourceController}}} |
| | 98 | - names of customized web2py classes (which are meant to be used instead of the native web2py class) are ''suffixed'' with S3, e.g. {{{AuthS3}}} |
| | 99 | - constants must be prefixed by S3, all uppercase, with words separated by underscores, e.g. S3_MY_CONSTANT |
| | 100 | - functions inside of classes can be named arbitrarily, however, their names should somehow indicate what they do |
| | 101 | |
| | 102 | - all modules must have a docstring describing the module, the module author(s), the copyright and license |
| | 103 | - the copyright statement must declare the SSF as copyright holder, and the license must be MIT |
| | 104 | - dependencies can be declared with the {{{@requires:}}} statement |
| | 105 | |
| | 106 | {{{ |
| | 107 | """ Utilities |
| | 108 | |
| | 109 | @requires: U{B{I{gluon}} <http://web2py.com>} |
| | 110 | |
| | 111 | @author: Fran Boon <fran[at]aidiq.com> |
| | 112 | @author: Michael Howden <michael[at]aidiq.com> |
| | 113 | @author: Pradnya Kulkarni |
| | 114 | |
| | 115 | @copyright: (c) 2010 Sahana Software Foundation |
| | 116 | @license: MIT |
| | 117 | |
| | 118 | Permission is hereby granted, free of charge, to any person |
| | 119 | obtaining a copy of this software and associated documentation |
| | 120 | files (the "Software"), to deal in the Software without |
| | 121 | restriction, including without limitation the rights to use, |
| | 122 | copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | 123 | copies of the Software, and to permit persons to whom the |
| | 124 | Software is furnished to do so, subject to the following |
| | 125 | conditions: |
| | 126 | |
| | 127 | The above copyright notice and this permission notice shall be |
| | 128 | included in all copies or substantial portions of the Software. |
| | 129 | |
| | 130 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| | 131 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| | 132 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| | 133 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| | 134 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| | 135 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| | 136 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| | 137 | OTHER DEALINGS IN THE SOFTWARE. |
| | 138 | |
| | 139 | """ |
| | 140 | |
| | 141 | }}} |
| | 142 | |
| | 143 | |
| | 144 | - all functions - in classes or top-level - must have docstrings explaining what they are supposed to do |
| | 145 | - the docstring should contain an {{{@author: }}} tag if the author differs from the module author |
| | 146 | - you should add your email address, if you want others to contact you with questions or suggestions |
| | 147 | |
| | 148 | {{{ |
| | 149 | def shn_split_multi_value(value): |
| | 150 | """ |
| | 151 | @author: Michael Howden <michael[at]aidiq.com> |
| | 152 | |
| | 153 | Converts a series of numbers delimited by |, or already in a string into a list |
| | 154 | |
| | 155 | If value = None, returns [] |
| | 156 | |
| | 157 | """ |
| | 158 | |
| | 159 | }}} |
| | 160 | |
| | 161 | - use {{{@status:}}} to indicate the current status of the implementation |
| | 162 | - use {{{@see:}}} to refer to web pages (e.g. Eden wiki pages) |
| | 163 | - see [http://epydoc.sourceforge.net/manual-fields.html] for more docstring tags |