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



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.


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

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


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

Add an import statement to models/

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

class S3VehicleModel(S3Model):
        Vehicle Management

    names = ["vms_vehicle",

    def model(self):

        T = current.T
        db = current.db

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

        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,
                                        requires = IS_NOT_EMPTY()

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


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

if not settings.has_module(module):
    raise HTTP(404, body="Module disabled: %s" % module)

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

    return s3_rest_controller()

Additional options are described here: s3_rest_controller

A basic navigation menu will be constructed by default for each view page, and a menu item for the module's landing page will be added to the top menu bar or its More menu.

For custom menus, see Menus


Create a directory for your view pages: views/<MODULE NAME>

Within that directory, add HTML templates for index.html and any custom views. A simple index.html is:

{{extend "layout.html"}}
<div id='home'>
{{=T("Manage Vehicles")}}

NB Only index.html is required to start with since the RESTful controller normally re-uses standard views.

A custom view for a resource named <MODULE NAME>_<RESOURCE> will be found automatically if the view page is named <RESOURCE>_<METHOD>.html

DeveloperGuidelines DeveloperGuidelines

Note: See TracWiki for help on using the wiki.