Moodle App Plugins Upgrade Guide
- Moodle App Overview
- Moodle App Development Guide
- Moodle App Plugins Development Guide
- Moodle App Remote Themes
- Moodle App Customisation
- Setting up your development environment
- Using the Moodle App in a browser
- Moodle App Translation
- Moodle App FAQ
- Moodle App Development Process
- Moodle App Release Notes
Upgrade from previous versions:
- See all Moodle App pages
- See pages for Moodle App Ionic 5 (current)
- See pages for Moodle App Ionic 3 (legacy)
- See pages Moodle App Ionic 1 (legacy)
- See pages for Moodle App Phonegap (legacy)
For user documentation see Moodle Mobile
| Important:
This content of this page has been updated and migrated to the new Moodle Developer Resources. The information contained on the page should no longer be seen up-to-date. Why not view this page on the new site and help us to migrate more content to the new site! |
Starting with version 3.9.5, the Moodle App uses Ionic 5. As usual, we tried not to change our APIs and components to prevent breaking existing plugins. Unfortunately, Ionic 5 comes with a lot of breaking changes, especially related to templates. This means that plugins need to be adapted in order to look good in the new versions of the app.
Please note that if your plugin doesn't use Ionic components nor JavaScript, it's possible that you don't have to adapt it. However, we recommend you to test the plugin with new versions of the app to check if everything works correctly.
Ionic changes
Previous versions of the app used Ionic 3, so the update involved an increase in two versions and Ionic changed a lot of their components, directives and utilities.
You can read the official Ionic migration documentation. Even if your plugins are not Ionic applications themselves, you can find information about components and other changes.
One relevant change is that all functions related to modals are now asynchronous. This means that if your plugin is displaying a modal in JavaScript, you’ll probably need to adapt your code.
Another important change is that text inside of <ion-item> should always be placed inside of an <ion-label>, otherwise it might not look good in some cases. For example:
<!-- Ionic 3 -->
<ion-item>My text</ion-item>
<!-- Ionic 5 -->
<ion-item><ion-label>My text</ion-label></ion-item>
Finally, all Ionic directives are now components, like <ion-label> or <ion-avatar>. This means that these directives cannot be used in combination with another component. Some common cases that will need to be modified:
<!-- Ionic 3 -->
<ion-label core-mark-required="true">...</ion-label>
<ion-avatar core-user-avatar ...>
<!-- Ionic 5 -->
<ion-label><span core-mark-required="true">...</span></ion-label>
<core-user-avatar ...>
You can now use ES6
The minimum platform requirements for Cordova and Ionic increased, and so it also affected the Moodle App. The new version requires Android 5.1 with WebView 61+, which means that the JavaScript for the app can now be compiled to ES6.
Please notice that you cannot use async/await, as they aren't part of ES6 and Android WebView 61 doesn't support them.
One issue that can break your plugin’s JavaScript is extending classes. In Ionic 3, when your plugin extends a class it's actually getting a function. In Ionic 5, your plugin will receive a JavaScript class and can be extended using class syntax:
Here's an example to create a subclass of CoreContentLinksModuleIndexHandler:
// Ionic 3
function AddonModCertificateModuleLinkHandler() {
that.CoreContentLinksModuleIndexHandler.call(this, that.CoreCourseHelperProvider, 'mmaModCertificate', 'certificate');
this.name = 'AddonModCertificateLinkHandler';
}
AddonModCertificateModuleLinkHandler.prototype = Object.create(this.CoreContentLinksModuleIndexHandler.prototype);
AddonModCertificateModuleLinkHandler.prototype.constructor = AddonModCertificateModuleLinkHandler;
// Ionic 5
class AddonModCertificateModuleLinkHandler extends this.CoreContentLinksModuleIndexHandler {
constructor() {
super('mmaModCertificate', 'certificate');
this.name = 'AddonModCertificateLinkHandler';
}
}
Changes in the app’s code
We’ve also done some changes to the code of the app. Most of these changes probably don’t affect your plugin, but you should still check this out just in case:
<core-icon>is now deprecated, please use<ion-icon>instead. Right now you can use font-awesome icons withion-icon. However, it still hasn’t been decided whether font awesome will be used in Moodle 4.0 or not, so font-awesome may be removed from the app in the future.- To “cross out” an icon using
ion-iconyou need to useclass="icon-slash"instead ofslash="true". - The function
syncOnSitesfromCoreSyncBaseProvidernow expects to receive a function with the parameters already bound:
// Ionic 3
syncOnSites('events', this.syncAllEventsFunc.bind(this), [force], siteId);
// Ionic 5
syncOnSites('events', this.syncAllEventsFunc.bind(this, force), siteId);
- All the delegates that previously supplied an injector parameter to its handlers no longer do that. For example, the function
getComponent()inCoreUserProfileFieldDelegateused to receive an injector as a parameter, but now it won’t receive any parameter. - All the delegates that previously supplied a
NavControllerparameter to its handlers no longer do that. For example, the functionopenCourse()inCoreCourseFormatDelegateno longer receive theNavControllerparameter. - The handlers registered in
CoreCourseOptionsDelegatenow need to return the propertiespageandpageParamsinstead ofcomponentandcomponentData. Please notice this only affects your plugin if you’re creating the handler yourself using JavaScript code. - The handlers registered in
CoreUserDelegatehave changed a bit. Please notice this only affects your plugin if you’re creating the handler yourself using JavaScript code.- Handlers can now define a
cacheEnabledproperty (falseby default) to cacheisEnabledForUsercalls. - In the function
isEnabledForUser, thenavOptionsandadmOptionsparameters have been removed. isEnabledForUseris now optional and defaults totrue.- They can implement a new function called
isEnabledForCourse; this function will receive thenavOptionsandadmOptionsparameters. If it's not defined, it'll default totrue.
- Handlers can now define a
- The function
prefetchPackagein theCoreCourseActivityPrefetchHandlerBasehas changed. If you were using this class to implement your own prefetch handler you might need to update its code. CoreInitDelegatehas been deleted. Now the initialisation of the app is done via Angular’sAPP_INITIALIZER. Please notice thatAPP_INITIALIZERcannot and shouldn’t be used by plugins.- The function
getAdditionalDownloadableFilesin question types now needs to return a list ofCoreWSExternalFile, it no longer accepts a list of strings. - Files stored to be uploaded later using
CoreFileUploaderProviderno longer have anofflineproperty, now they’re just instances ofFileEntry. ionViewCanLeavefunction has been renamed tocanLeave.- The
onchangemethod of theNetworkservice is now calledonChange.
Supporting both Ionic 3 and Ionic 5
Your plugin should still support Ionic 3 so it works in devices that haven’t updated the app yet. This can be done by checking the value of appversioncode sent by the app. Here you can find an example applied to the choicegroup plugin: Choicegroup plugin.
As you can see in that repository, the JS and the templates are duplicated in order to have one file to support Ionic 3 and another file to support Ionic 5. In this example, they are called "ionic3" and "latest", but you can structure this as you prefer. You can also have a single file with different HTML depending on the appversioncode. That’s up to you.
Is there any example I can look at?
If you used the app’s code as an example to build your plugin, you can do the same. There are also some plugins that have been updated, for example you can see the following PRs on the choicegroup plugin:
- https://github.com/ndunand/moodle-mod_choicegroup/pull/149
- https://github.com/ndunand/moodle-mod_choicegroup/pull/150
You can also look at the Moodle App Plugins Development Guide, it has been updated to reflect how to write plugins for the latest version of the app.
Before 3.5
Before 3.5, the app was written using Ionic 1 and Moodle plugins could add mobile support by writing an Angular JS/Ionic module, compiling it to a zip, and including it in the plugin.
Nowadays, you need to install the Moodle App Additional Features plugin to make these plugins compatible with the latest versions of Moodle.
You can read about Remote add-ons for more details.