If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.


From MoodleDocs
(Redirected from NEWMODULE Documentation)

Welcome to Moodle development!

This is a tutorial to help you learn how to write plugins for Moodle from start to finish, while showing you how to navigate the most important developer documentation along the way.

PRE-REQUISITES: We assume you are fairly comfortable with PHP in general and that you are able to install a database and web server on your local machine.

If you need to learn PHP, you can see one PHP tutorial at, another at and several videos in YouTube at


What's in the box

If you download Moodle source code or clone it from git, you will see a bunch of files and folders. This code consists of Moodle core (that consists of the Very core and Core components), third party libraries and plugins. Their mixed locations can be quite confusing at first but as you start working with it it will become more clear. Moodle developers should avoid modifications of the third party libraries (unless required) and core can never call methods defined in plugins. See also Communication Between Components

Setting up your development environment

The Moodle development framework

What type of plugin are you developing?

  • Moodle has lots of different types of plugins.
  • There are 24 different categories of plugin listed on the moodle plugin database. Before starting check here to see if someone else has not already created what you are looking for. Perhaps you could contribute to their plugin instead of creating a new one.


Let's make a plugin

The skeleton of your plugin

The code of a plugin is organised into multiple different files and directories within a single root directory. All plugins follow the same directory and file structure.


  • Plugin files - Provides a list of required and common plugins files along with their location and purpose.

Basic page structure

The link below explains how to create and display a simple page in Moodle.


Multiple languages support

Moodle has a mechanism for displaying given text string in multiple languages, depending on the user's preferred language and the site configuration. Plugin authors must define all the text strings used by the plugin in the default English language. That is then used as a reference for translations to other languages.

Moodle file structure

Automatic Class Loading

Automatic class loading helps us to automatically include class files as and when they are required instead of manually including them everytime. Moodle supports automatic class loading. See the link below for the explanation of rules associated with it -


Automatic class loading


You can add a lot of features to your plugin by providing certain callbacks that Moodle expects to be present in your plugin's lib.php file. A detailed list can be found at -



Plugin types

Moodle supports a wide range of plugin types. The complete list and location to place these plugins can be found at -


Plugin types

Core APIs

Moodle provides apis for a plugin to interact with core and other external systems. For example you don't have to manually do any SQL queries, Moodle provides it's own DDL and DML layers. The link below lists all major core apis in Moodle -


Core APIs

Browser accessible pages

Any php file in your plugin will either be browser accessible or be an internal file.

For browser accessible pages you must include config.php with code something similar to this -


For internal files the code should use the following -

defined('MOODLE_INTERNAL') || die();

Add basic content to your page

  • Content for a page is added through renderers.
  • Renderers are typically stored in the "classes/output" directory.
  • Putting content in renderers allows themers to override the visual display of the content.
  • Very basic information is presented using the html_writer class.


Content with templates

  • In most cases when displaying content, templates should be used.
  • templates are stored in the "templates" directory. The templates use mustache files.
  • Mustache files allow for more generic html with placeholders inserted, that inserts the data (context) at run time.


Adding your plugin into Moodle's navigation

  • The moodle navigation system has hooks which allows plugins to add links to the navigation menu.
  • Hooks are located in lib.php. Try to keep lib.php as small as possible as this file is included on every page. Put classes and functions elsewhere.
  • Course navigation extension example:
function tool_devcourse_extend_navigation_course($navigation, $course, $coursecontext) {
    $url = new moodle_url('/admin/tool/devcourse/index.php');
    $devcoursenode = navigation_node::create('Development course', $url, navigation_node::TYPE_CUSTOM, 'Dev course', 'devcourse');


Database queries

  • Moodle has a generic database query library. Behind this library are additional libraries which allow Moodle to work with MySQL, PostgreSQL, Oracle, SQL Server, and Maria DB.
  • Where possible it is advisable to use the predefined functions rather than write out SQL. Writing SQL has a greater chance of not working with one of the supported databases.
  • The return of the select functions tends to be an object or an array of objects.

Example call to retrieve data from the course table.

global $DB;
$courses = $DB->get_records('course', null, '', 'id, category, fullname, shortname');

Example of data returned from the above code.

    [43] => stdClass Object
            [id] => 43
            [category] => 1
            [fullname] => XX -Test 5
            [shortname] => xxt5

    [5] => stdClass Object
            [id] => 5
            [category] => 1
            [fullname] => With the glossary
            [shortname] => wtg

    [39] => stdClass Object
            [id] => 39
            [category] => 1
            [fullname] => XX - Test 1
            [shortname] => xxt1


Creating your own database tables

  • We create our database tables in Moodle using the XMLDB editor. This is located in the administration block "Site administration | Development | XMLDB editor".
  • The {plugin}\db directory needs to have write access for the XMLDB editor to be most effective.
  • XMLDB editor creates an install.xml file in the db directory. This file will be loaded during the install to create your tables.
  • XMLDB editor will produce php update code for adding and updating moodle database tables.

The XMLDB main page.


Upgrade code generated by the XMLDB



Supporting access permissions: roles, capabilities and contexts

  • Capabilities are controlled in "access.php" under the "db" directory.
  • This file has an array of capabilities with the following:
    • name
    • possible security risks behind giving this capability.
    • The context that this capability works in.
    • The default roles (teacher, manager, student, etc) that have this capability.
    • Various other information.
  • These capabilities are checked in code to allow access to pages, sections, and abilities (saving, deleting, etc).


Adding web forms

  • Moodle has it's own forms library.
  • The forms lib includes a lot of accessibility code, and error checking, by default.
  • Moodle forms can be displayed in JavaScript using 'fragments'.


Maintaining good security

  • Use the sesskey when directing to pages to do actions.
  • Use the appropriate filters when retrieving parameters


Handling files

  • Files are conceptually stored in file areas.
  • Plugins can only access files from it's own component.


Adding Javascript

  • Moodle is currently using jquery and AMD (Asynchronous Module Definition).
  • JavaScript files are located in the "amd/src" directory.
  • Use grunt to build your JavaScript.
  • Include your JavaScript in php files as follows:
  • Can also be included in mustache templates.


Adding events and logging

  • All logging in moodle is done through the events system.
  • New events should be located in the "classes/event" directory.
  • It is possible to create observers and subscribe to events.



Accessibility is an important consideration while developing a plugin to make sure your plugin is accessible to all users and doesn't discriminate against users with disablities. This often is a mandated requirement in many countries. The links below explain common practices that we follow at Moodle to make the interface more accessible.


Web Services and AJAX

  • Moodle web services uses the external functions API.
  • The recommended way to make AJAX requests is to use the ajax AMD file which uses the external functions API.
  • External functions should be located in the "classes/external.php" file.
  • A list of services should be included in "db/services.php". This file is required to register the web services with Moodle.
  • The services list is an array which contains:
    • classname Name of the external class.
    • methodname The name of the external function.
    • classpath system path to the external function file.
    • description Description of the function
    • type Create, read, update, delete
    • ajax Can this function be used with ajax?
    • capabilities Capabilities required to use this function.


Using caching to improve performance

  • The main cache used by moodle is the Moodle Universal Cache (MUC).
  • The MUC has several cache definitions -
    • Request cache
    • Session cache
    • Application


Supporting backup and restore

  • Supporting backup and restore requires creating several files in the 'backup/moodle2' directory.
  • Back requires a class to extend the backup_task of some sort. There may be a specific plugin task to extend.
  • Restore requires a class to extend the restore_task of some sort. There may be a specific plugin task to extend.
  • The restore steps lib defines the structure of the plugin to be restored.
  • The backup steps lib defines steps, settings, attributes, etc.


Supporting automated testing

  • Moodle has two types of automated testing: php unit tests, and behat tests.
  • Unit tests are for testing functions.
  • Behat tests runs through scenarios.
    • Behat tests follows a script and navigates through moodle pages.
  • unit tests should be located in the "tests" directory.
  • behat tests should be located in the "tests/behat" directory.
  • Tests located in these directories will be run through when a full test run is initiated.
  • behat tests are actually feature files and end with the extension ".feature".


Publishing your plugin

Adding your plugin to

  • publish your plugins at
  • Publishing plugins on the moodle site leads you through a bunch of steps that need to be completed in order for the plugin to be approved and published.
  • Plugins will be run through a pre-checker to give suggestions about possible issues with the code.

Supporting your plugin


Finishing this tutorial:

  1. About one or two screens for each section with a very generic overview for beginners, containing links to relevant docs WITH COMMENTS ABOUT QUALITY, USEFULNESS, CAVEATS etc.
  2. Go through all the linked pages and make sure they are current and accurate.
  3. Add a worked example to this page, so that each section has suggestions about things to add to the admin tool being built as an exercise. If the code is long, it could be placed on separate pages. A good reference for style is Mobile_support_for_plugins and Blocks.

See also

  • See this (july 2017) forum thread about Getting Started with Moodle Development.
  • See this (may 2017) forum thread about Getting Started with Moodle Development.
  • MoodleBites for Developers - completely online courses Level 1 and Level 2 are designed to get new developers up-to-speed with Moodle development, and are run online by HRDNZ (Certified Moodle Partner since 2006).

See also these older tutorials:

Any questions?

If you have any questions, you're welcome to post in the General developer forum on