wiki:DeveloperGuidelinesNewModule

Version 60 (modified by Pat Tressel, 11 years ago) ( diff )

--

DeveloperGuidelines

How to add a new module

The Eden Book has a tutorial for adding a new module. However, it is simplified from the normal way modules are included in Eden. Especially, the model file differs. This page shows the structure of an Eden module, and deliberately omits details, which are described elsewhere.

Settings

Add your module to settings.modules in private/templates/<template>/config.py if it is for a specific template.

Add it to private/templates/default/config.py to provide an example of how your module should be entered in settings.modules.

Model

Create a file modules/s3db/<MODULE NAME>.py

Add an import statement to models/00_tables.py:

import s3db.<MODULE NAME>

For each major "resource" in your module, add a class that is a subclass of S3Model. The class must define a model() method that defines the tables for that resource. The class can define multiple tables, for other resources associated with the major resource. For instance, if you have a major resource representing a vehicle, you might want a table to represent types of vehicles, so users can add new types without changing the code. The main table for specific vehicles and the table for types can go in the same model class.

To avoid namespace clashes, use your module name as a prefix for table names. Follow with underscore and the name of the resource your table represents: <MODULE NAME>_<RESOURCE>. Resource names should be unique.

E.g. if building a Vehicle Management System with module name vms, with individual vehicles and vehicle types:

__all__ = ["S3VehicleModel",
           "vms_vehicle",
           "vms_vehicle_type",
          ]

class S3VehicleModel(S3Model):
    """
        Vehicle Management
    """

    names = ["vms_vehicle",
             "vms_vehicle_type",
            ]

    def model(self):

        T = current.T
        db = current.db

        tablename = "vms_vehicle_type"
        represent = S3Represent(lookup=tablename)
        table = s3db.define_table(tablename,
                                  Field("name",
                                        requires = IS_NOT_EMPTY()
                                       ),
                                  *s3_meta_fields())

        crud_strings[tablename] = Storage(
            title_create = T("Add Vehicle Type"),
            title_display = T("Vehicle Type Details"),
            title_list = T("List Vehicle Types"),
            title_update = T("Edit Vehicle Type"),
            title_search = T("Search Vehicle Types"),
            subtitle_create = T("Add New Vehicle Type"),
            subtitle_list = T("Vehicle Types"),
            label_list_button = T("List Vehicle Types"),
            label_create_button = T("Add Vehicle Type"),
            label_delete_button = T("Delete Vehicle Type"),
            msg_record_created = T("Vehicle Type added"),
            msg_record_modified = T("Vehicle Type updated"),
            msg_record_deleted = T("Vehicle Type deleted"),
            msg_list_empty = T("No Vehicle Types currently defined"))

        tablename = "vms_vehicle"
        represent = S3Represent(lookup=tablename)
        table = s3db.define_table(tablename,
                                  Field("name",
                                        requires = IS_NOT_EMPTY()
                                       ),
                                  Field("type",
                                        requires=IS_ONE_OF(db,
                                                           "vms_vehicle_type.id",
                                                           represent),
                                       )
                                  *s3_meta_fields())

        crud_strings[tablename] = Storage(
            title_create = T("Add Vehicle"),
            title_display = T("Vehicle Details"),
            title_list = T("List Vehicles"),
            title_update = T("Edit Vehicle"),
            title_search = T("Search Vehicles"),
            subtitle_create = T("Add New Vehicle"),
            subtitle_list = T("Vehicles"),
            label_list_button = T("List Vehicles"),
            label_create_button = T("Add Vehicle"),
            label_delete_button = T("Delete Vehicle"),
            msg_record_created = T("Vehicle added"),
            msg_record_modified = T("Vehicle updated"),
            msg_record_deleted = T("Vehicle deleted"),
            msg_list_empty = T("No Vehicles currently registered"))

Controller

Create a file: /controllers/<MODULE NAME>.py

Add controller functions for your resources, and an index() function for your controller's landing page:

module = request.controller

def index():
    """ Module Home Page """

    module_name = settings.modules[module].name_nice
    response.title = module_name

    return dict(module_name=module_name)

def vehicle():
    """ RESTful CRUD controller """

    resource = request.function
    return s3_rest_controller(module, resource)

Additional options are described here: s3_rest_controller

Add a menu:

# Options Menu (available in all Functions' Views)
response.menu_options = [
    [T("Home"), False, URL(f="index")],
    [T("Add Vehicle"), False, URL(f="vehicle", args="create")],
    [T("List Vehicles"), False, URL(f="vehicle")],
    [T("Search Vehicles"), False, URL(f="vehicle", args="search")]
]

Views

Add HTML templates for any custom functions: /views/<MODULE NAME>/<FUNCTION NAME>.html

NB Only index.html is required to start with since the RESTful controller normally re-uses standard views.
If Custom Views are wanted they are detected automatically if files are found in /views/<MODULE NAME>/<RESOURCE>_<METHOD>.html


DeveloperGuidelines

Note: See TracWiki for help on using the wiki.