Moodle's AMD modules load JavaScript asynchronously and isolate dependencies using RequireJS. This guide covers module structure, injecting Moodle services, localization, and building production-ready minified output using Grunt.

SOP: Writing and Building AMD Modules in Moodle

This guide will walk you through creating, localizing, and building asynchronous module definition (AMD) JavaScript modules in Moodle, as well as how to pull in core Moodle services (like the notification system) from your AMD code.

1. What is AMD in Moodle?

Moodle uses RequireJS to load JavaScript modules asynchronously. An AMD module is a JavaScript file that:

  • Declares its dependencies via a define([...], function(...) { … }) call.
  • Exports one or more functions (often a single init entry point).
  • Can be minified and concatenated into production-ready code.

By using AMD, modules only load when needed and avoid polluting the global namespace.

2. Folder Layout

Inside your plugin (e.g. mod/assessmentform/), you should have:

mod/assessmentform/
├── amd/
│   ├── src/             ← Your unbuilt source files
│   │   └── survey_init.js
│   └── build/           ← Moodle's build step will place minified files here
│       └── survey_init.min.js
└── view.php             ← Calls your AMD module via js_call_amd()
  • amd/src/Place your human-readable modules here.
  • amd/build/After running the build, minified code will live here. Commit the build outputs so your plugin works without requiring Node on the production server.

3. Writing Your AMD Module

In amd/src/survey_init.js, you might have:

define([
    'jquery',
    'core/notification',
    'core/str',            // for translations
    'survey-core',
    'survey-js-ui'
], function($, notification, str, Survey) {

    return {
        init: function(args) {
            // 1. Localization
            var texts = args.str || {};
            // str.get_string('key','mod_yourplugin') can also be used.

            // 2. Load and render your SurveyJS
            $.getJSON(args.jsonUrl).done(function(def) {
                var survey = new Survey.Model(def);
                survey.render(document.getElementById(args.containerId;

                survey.onComplete.add(function(sender) {
                    // Build payload...
                    $.ajax({
                        url: args.postUrl,
                        method: 'POST',
                        data: JSON.stringify({ /* ... */ }),
                        contentType: 'application/json',
                        dataType: 'json',
                    }).done(function(response) {
                        notification.addNotification({
                            message: texts.responsesavedsuccess || 'Saved successfully!',
                            type: 'success'
                        });
                        // redirect ...
                    }).fail(function() {
                        notification.addNotification({
                            message: texts.responsefailed || 'Save failed.',
                            type: 'error'
                        });
                    });
                });
            }).fail(function() {
                $('#'+args.containerId)
                  .html('<div class="alert alert-danger">Error loading form.</div>');
            });
        }
    };
});

Key points

  • define([...], function(...) { … })List the module IDs you depend on. Moodle’s loader will map these to the right files.
  • core/notificationExposes notification.addNotification({message, type}).
  • core/strOffers str.get_string(key, component) for on-the-fly translations.
  • js_call_amd() in PHPPass an associative array of arguments from PHP into your JS entry-point.

4. Injecting Moodle Services

Just list them in your dependency array:

define([
    'jquery',
    'core/notification',
    'core/str',
    'core/ajax',
    // ...your other libraries...
], function($, notification, str, Ajax) {
    // You now have `notification`, `str` and `Ajax.call()` available.
});
  • core/ajaxUse Moodle’s AJAX wrapper:
  • Ajax.call([{ methodname: 'mod_yourplugin_do_something', args: { foo: 1 }}])[0].then(function(result){ … }).catch(function(err){ notification.exception(err); });

5. Localization

  • In your language file (lang/en/mod_assessmentform.php):
  • $string['responsesavedsuccess'] = 'Assessment saved successfully for {$a->fullname}.';$string['responsefailed'] = 'Error saving assessment.';
  • Pass them into JS when you call your AMD module:
  • $PAGE->requires->js_call_amd( 'mod_assessmentform/survey_init', 'init', [ 'str' => [ 'responsesavedsuccess' => get_string('responsesavedsuccess','mod_assessmentform'), 'responsefailed' => get_string('responsefailed','mod_assessmentform'), ], // …other args… ]);
  • In JS, access args.str.responsesavedsuccess.

6. Building (Minifying) Your AMD

Moodle provides a Grunt setup out of the box. At your plugin root:

  • Install tools (one-time per project):
  • npm install --global grunt-clinpm install
  • Build all AMD modules (including yours):
  • grunt amd
  • This reads every amd/src/*.js in all plugins, minifies them, and writes to amd/build/*.min.js.
  • You can also target just your plugin:
  • grunt amd:mod_assessmentform
  • Commit the contents of amd/build/ into your plugin’s repository.

If you prefer a standalone build, you can drop a Gruntfile.js at your plugin root that only references your AMD folder. Moodle’s core Gruntfile already handles this; there’s no extra setup needed.

7. Summary Checklist

  • Create amd/src/yourmodule.js with a define([...], ...).
  • Load it in PHP with:
  • $PAGE->requires->js_call_amd('mod_yourplugin/yourmodule','init',[$args]);
  • Use injected services:
  • core/notificationnotification.addNotification(...)
  • core/strstr.get_string(...)
  • core/ajaxAjax.call(...)
  • Build with npm install && grunt amd and commit amd/build/*.min.js.
  • Test on your dev site, then deploy.

With this workflow in place, you can rapidly iterate your JS in amd/src/ and then generate production-ready, minified AMD modules via Moodle’s standard Grunt toolchain.

Solin specializes in Moodle plugin development and AMD module authoring.

Contact us