Module File Structure

Applies to: Jamroom 7.0+ Last verified: 2026-10-24
  • Files and folders

    A module is a folder in modules/. Only include.php is required. These names have a set meaning:

    File or folder What it's for
    include.php Required. _meta() and _init(), and the module's helper functions
    config.php Global Config settings: (module)_config()
    quota.php Quota Config settings: (module)_quota_config()
    schema.php Database tables and DataStore: (module)_db_schema()
    views/(view).php One view function per file, for yoursite.com/(module url)/(view)
    index.php Views, the older way: several view functions in one file
    profile.php or profile/(view).php Views shown inside a profile: yoursite.com/(profile)/(module url)/...
    templates/ Smarty templates
    lang/en-US.php Language strings
    css/, js/ CSS and JavaScript, registered in _init()
    img/ Images: replaceable on the module's Images tab
    icon.png The module's icon in the ACP, 128 × 128 pixels
    changelog.txt Version history
    tests/ Unit tests, for the Unit Test module
  • include.php

    _meta() returns the module's details; _init() registers what the module does (see The _init() Function):

    function xxFoo_meta()
    {
        return array(
            'name'        => 'Foo',
            'url'         => 'foo',
            'version'     => '1.0.0',
            'developer'   => 'Your Name, ©' . date('Y'),
            'description' => 'What the module does',
            'category'    => 'profiles',
            'license'     => 'mpl'
        );
    }
    
    function xxFoo_init()
    {
        return true;
    }
    • url: the module's default URL. Admins can change it on the Info tab, so templates get it with {jrCore_module_url}.
    • category: the ACP category the module is listed in, such as profiles, tools, site or users.
    • Other keys include requires (modules it needs, such as 'jrAction:2.5.0') and doc_url (a link to its documentation).
  • Views

    A view handles a URL. yoursite.com/foo/hello runs view_xxFoo_hello(), from views/hello.php (or index.php):

    <?php
    defined('APP_DIR') or exit();
    
    function view_xxFoo_hello($_post, $_user, $_conf)
    {
        jrCore_page_banner('Hello');
        jrCore_page_custom('<p>Hello, ' . jrCore_entity_string($_user['user_name']) . '</p>');
        return jrCore_page_display(true);
    }
  • $_post has the URL parts and form values, $_user the current user, $_conf the settings. Forms that create and update items use the views create / create_save and update / update_save.

    Views inside a profile go in profile.php, as profile_view_xxFoo_(view)($_profile, $_post, $_user, $_conf); profile_view_xxFoo_default() handles the module's main profile page.

  • config.php

    Global settings appear on the module's Global Config tab and are read as $_conf['xxFoo_(name)']:

    function xxFoo_config()
    {
        $_tmp = array(
            'name'     => 'greeting',
            'type'     => 'text',
            'default'  => 'Hello',
            'validate' => 'printable',
            'label'    => 'Greeting',
            'help'     => 'The greeting shown on the hello page'
        );
        jrCore_register_setting('xxFoo', $_tmp);
        return true;
    }
  • A registered setting is stored the first time it's seen. To remove one you no longer use, call jrCore_delete_setting('xxFoo', 'greeting').

  • quota.php

    Settings per quota appear on the Quota Config tab, through jrProfile_register_quota_setting() in xxFoo_quota_config(). They're read from the profile as quota_xxFoo_(name).

    The usual Allowed on Profile checkbox comes from registering quota support in _init():

    jrCore_register_module_feature('jrCore', 'quota_support', 'xxFoo', 'on');
  • Its value is quota_xxFoo_allowed (on or off). Pass an array as a fifth argument with label and help to change its wording.

  • schema.php

    xxFoo_db_schema() creates the module's tables. It runs on install and on every Integrity Check, so changes to it are applied there:

    function xxFoo_db_schema()
    {
        // A DataStore - every key starts with "foo_"
        jrCore_db_create_datastore('xxFoo', 'foo');
    
        // An ordinary table
        $_tmp = array(
            "log_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY",
            "log_time INT(10) UNSIGNED NOT NULL DEFAULT '0'",
            "log_text VARCHAR(255) NOT NULL DEFAULT ''"
        );
        jrCore_db_verify_table('xxFoo', 'log', $_tmp);
        return true;
    }
  • Templates

    Template Used for
    index.tpl yoursite.com/(module url), when no view handles it
    item_index.tpl The module's page on a profile
    item_list.tpl The default template of {jrCore_list module="xxFoo"}
    item_detail.tpl One item on a profile: yoursite.com/(profile)/(module url)/(id)/(title)
    item_action.tpl The item's entry in the Timeline
    item_search.tpl The item in search results
    email_(name)_subject.tpl, email_(name)_message.tpl Emails, for jrCore_parse_email_templates()

    Render a template from PHP with jrCore_parse_template('name.tpl', $_data, 'xxFoo'). Skins can override any of them: see Changing How a List Looks.

  • lang/en-US.php

    $lang[1] = 'greeting';
    $lang[2] = 'Hello there!';
  • Templates show a string with {jrCore_lang module="xxFoo" id="2" default="Hello there!"}, PHP with jrUser_load_lang_strings(). Strings are copied into the database on install, and new ones are added on an Integrity Check; changes to existing strings are made on the module's Language tab.

  • css, js and img

    Register CSS and JavaScript files in _init(). They're combined and compressed into the site's single CSS and JS file:

    jrCore_register_module_feature('jrCore', 'css', 'xxFoo', 'xxFoo.css');
    jrCore_register_module_feature('jrCore', 'javascript', 'xxFoo', 'xxFoo.js');
  • Images in img/ are shown with {jrCore_image module="xxFoo" image="name.png"}. See The Image System.

Tags