Note:

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

Moodle 4.0 developer update: Difference between revisions

From MoodleDocs
Line 1: Line 1:
{{Moodle 4.0}}This page will highlight the important changes that are coming in Moodle 4.0 for developers. Including how the UX improvements impact custom themes, relevant API changes, and what you can do as developer to prepare for the 4.0 release.
{{Moodle 4.0}}This page will highlight the important changes that are coming in Moodle 4.0 for developers. Including how the UX improvements impact custom themes, relevant API changes, and what you can do as developer to prepare for the 4.0 release.
== UX and theme changes ==
== UX and theme changes ==
The 4.0 theme changes can be classified as changes to improve navigation, changes for the course creation project and general UI improvements for Moodle 4.0 and newer only.
==== Navigation project changes ====
A new layout has been added that pushes the blocks region offscreen called the drawers layout. This layout has a fixed width of 800px for the main content area and page buttons to open / close the drawers. Files:
/theme/boost/layouts/drawers.php
/theme/boost/templates/drawers.mustache
In case a page uses “fake blocks” the drawer region will be opened automatically on first visit.
Child themes implementing this layout should update the theme config.php and configure the ‘drawers’ layout from theme boost for pages like ‘course’ and ‘incourse’
Pages that should not use the drawers layout are the admin pages or other pages that require more horizontal space in the main content area.
===== Primary / secondary navigation =====
The top navbar now includes the new '''primary navigation''', this navigation used to be in the page navdrawer region. If custommenu items are configured in the global theme settings they will be added to the primary navigation.
The main content area shows tabs for secondary navigation with a maximum of 5 items being rendered in this ‘more’ menu. A new UI component has been created to render menus like this. Files:
/lib/templates/moremenu.mustache
===== Navigation project Upcoming changes =====
====== Edit switch. ======
[https://tracker.moodle.org/browse/MDL-71610 MDL-71610]
On theme boost the “Turn editing on” and  “Customise this page” buttons have been replaced by an edit switch in the top navbar. Theme Classic will keep using the old buttons. Child themes can choose to use the edit switch if the theme config.php is using this variable
$THEME->haseditswitch = true;
==== Create a course project changes ====
The new course index feature can be themed using a set of scss variables. Use them to change the look and feel instead of adding custom css
/theme/boost/scss/moodle/courseindex.scss
===== Create a course project upcoming changes =====
[https://tracker.moodle.org/browse/MDL-71691 MDL-71691]
The activities in a course are rendered using a new activity UI component. The activities will use a new renderable and can be customised using a single mustache template
The icons used for activities have been redesigned and use a monochrome svg icon. If contrib plugins provide an icon-mono.svg in their pix folder this icon will be rendered. For example :
mod/quiz/pix/icon-mono.svg
The background colour for this icon can be styled using css in a plugin styles.css. Please use one of the theme variables for your icon background using:
.modtype_myplugin .inlineiconsvg {
    background-color: var(--activitytypea);
}
To customize all icon colours use this scss array and add it to the  ‘Raw initial SCSS’ in the theme Boost advanced settings page
The complete array can be overridden using the ‘Raw initial SCSS’ in the theme settings page
$activity-icon-colors: (
    "typea": #5D63F6,
    "typeb": #11A676,
    "typec": #EB66A2,
    "typed": #F7634D,
    "typee": #399BE2,
    "typef": #A378FF
)
==== General UI improvements upcoming changes ====
===== Login page =====
[https://tracker.moodle.org/browse/MDL-69371 MDL-69371]
The login page has been redesigned and allows the admin to configure a background image for the login page only in the theme settings page. This change is available in both Boost and Classic. The login page still has all the features with an improved layout.
===== The page footer =====
[https://tracker.moodle.org/browse/MDL-71965 MDL-71965]
The page footer button is only visible when clicking a help button at the bottom right of the screen
===== User initials as profile picture placeholder =====
[https://tracker.moodle.org/browse/MDL-72305 MDL-72305]
If users do not upload a profile picture the user initials are displayed on a rounded gray background as a placeholder picture in the top navbar or any other page using a placeholder image. This change will be available in both Boost and Classic.
===== Image editable component, single image formfield =====
[https://tracker.moodle.org/browse/MDL-69880 MDL-69880]
When uploading a user image or course image the user can now '''resize''' and '''crop''' the image. This feature can be reused for any component handling images using a new formfield:
$mform->addElement('singleimage').
This form-field will store a drawer file in the user context. On submitting the form the uploaded file needs to be stored in a more permanent location. The best way of achieving this is creating an image handler class to store / delete / handle form data. For example:
course/classes/imageeditable/handler.php
The image editable component can be used as a standalone feature too using
lib/classes/output/image_editable.php
When used as a standalone component it will allow users to change the profile picture from the user profile page, or update any other image used in a custom plugin or theme.
===== Removal of back to top link =====
[https://tracker.moodle.org/browse/MDL-72454 MDL-72454]
The back to top link will be removed for theme boost to make place for the page footer button.
===== Theme Boost styling changes =====
By default rounded edges will be used for UI components [https://tracker.moodle.org/browse/MDL-72455 MDL-72455], for the page header and main content area the borders will be removed [https://tracker.moodle.org/browse/MDL-72457 MDL-72457].
== Component library ==
== Component library ==
== Navigation ==
== Navigation ==
Line 74: Line 163:
* The new move section/activity modal
* The new move section/activity modal
* Native browser drag&drop implementation
* Native browser drag&drop implementation
The new course editor uses a component-based reactive pattern to keep track of the course changes. The pattern highlights are:
The new course editor uses a component-based reactive pattern to keep track of the course changes. The pattern highlights are:
* The main AMD module "core_crouseformat\courseeditor" maintains a data structure called state.
* The main AMD module "core_crouseformat\courseeditor" maintains a data structure called state.
* Each UI element is implemented as a Component that observes the course state data and reacts to any data change
* Each UI element is implemented as a Component that observes the course state data and reacts to any data change
Line 83: Line 170:


The reactive library documentation, as well as the format plugin migration guide, will be available soon.
The reactive library documentation, as well as the format plugin migration guide, will be available soon.
==== Other course related 4.0 changes ====
==== Other course related 4.0 changes ====
Two new web services have been added:
Two new web services have been added:
* core_courseformat_get_state: user by the new javascript course editor to get the current course state data (containing the list of sections, activities, and other course-related data)
* core_courseformat_get_state: user by the new javascript course editor to get the current course state data (containing the list of sections, activities, and other course-related data)
* core_courseformat_update_course: to alter the current course content. Each call returns the parts of the course state altered by the action
* core_courseformat_update_course: to alter the current course content. Each call returns the parts of the course state altered by the action
== API changes ==
== API changes ==
== Behat changes ==
== Behat changes ==

Revision as of 13:45, 7 September 2021

Moodle 4.0 This page will highlight the important changes that are coming in Moodle 4.0 for developers. Including how the UX improvements impact custom themes, relevant API changes, and what you can do as developer to prepare for the 4.0 release.

UX and theme changes

The 4.0 theme changes can be classified as changes to improve navigation, changes for the course creation project and general UI improvements for Moodle 4.0 and newer only.

Navigation project changes

A new layout has been added that pushes the blocks region offscreen called the drawers layout. This layout has a fixed width of 800px for the main content area and page buttons to open / close the drawers. Files:

/theme/boost/layouts/drawers.php
/theme/boost/templates/drawers.mustache

In case a page uses “fake blocks” the drawer region will be opened automatically on first visit.

Child themes implementing this layout should update the theme config.php and configure the ‘drawers’ layout from theme boost for pages like ‘course’ and ‘incourse’

Pages that should not use the drawers layout are the admin pages or other pages that require more horizontal space in the main content area.

Primary / secondary navigation

The top navbar now includes the new primary navigation, this navigation used to be in the page navdrawer region. If custommenu items are configured in the global theme settings they will be added to the primary navigation.

The main content area shows tabs for secondary navigation with a maximum of 5 items being rendered in this ‘more’ menu. A new UI component has been created to render menus like this. Files:

/lib/templates/moremenu.mustache
Navigation project Upcoming changes
Edit switch.

[https://tracker.moodle.org/browse/MDL-71610 MDL-71610]

On theme boost the “Turn editing on” and  “Customise this page” buttons have been replaced by an edit switch in the top navbar. Theme Classic will keep using the old buttons. Child themes can choose to use the edit switch if the theme config.php is using this variable

$THEME->haseditswitch = true;

Create a course project changes

The new course index feature can be themed using a set of scss variables. Use them to change the look and feel instead of adding custom css

/theme/boost/scss/moodle/courseindex.scss
Create a course project upcoming changes

[https://tracker.moodle.org/browse/MDL-71691 MDL-71691]

The activities in a course are rendered using a new activity UI component. The activities will use a new renderable and can be customised using a single mustache template

The icons used for activities have been redesigned and use a monochrome svg icon. If contrib plugins provide an icon-mono.svg in their pix folder this icon will be rendered. For example :

mod/quiz/pix/icon-mono.svg

The background colour for this icon can be styled using css in a plugin styles.css. Please use one of the theme variables for your icon background using:

.modtype_myplugin .inlineiconsvg {
    background-color: var(--activitytypea);
}

To customize all icon colours use this scss array and add it to the ‘Raw initial SCSS’ in the theme Boost advanced settings page

The complete array can be overridden using the ‘Raw initial SCSS’ in the theme settings page

$activity-icon-colors: (
    "typea": #5D63F6,
    "typeb": #11A676,
    "typec": #EB66A2,
    "typed": #F7634D,
    "typee": #399BE2,
    "typef": #A378FF
)

General UI improvements upcoming changes

Login page

[https://tracker.moodle.org/browse/MDL-69371 MDL-69371]

The login page has been redesigned and allows the admin to configure a background image for the login page only in the theme settings page. This change is available in both Boost and Classic. The login page still has all the features with an improved layout.

The page footer

[https://tracker.moodle.org/browse/MDL-71965 MDL-71965]

The page footer button is only visible when clicking a help button at the bottom right of the screen

User initials as profile picture placeholder

[https://tracker.moodle.org/browse/MDL-72305 MDL-72305]

If users do not upload a profile picture the user initials are displayed on a rounded gray background as a placeholder picture in the top navbar or any other page using a placeholder image. This change will be available in both Boost and Classic.

Image editable component, single image formfield

[https://tracker.moodle.org/browse/MDL-69880 MDL-69880]

When uploading a user image or course image the user can now resize and crop the image. This feature can be reused for any component handling images using a new formfield:

$mform->addElement('singleimage').

This form-field will store a drawer file in the user context. On submitting the form the uploaded file needs to be stored in a more permanent location. The best way of achieving this is creating an image handler class to store / delete / handle form data. For example:

course/classes/imageeditable/handler.php

The image editable component can be used as a standalone feature too using

lib/classes/output/image_editable.php

When used as a standalone component it will allow users to change the profile picture from the user profile page, or update any other image used in a custom plugin or theme.

Removal of back to top link

[https://tracker.moodle.org/browse/MDL-72454 MDL-72454]

The back to top link will be removed for theme boost to make place for the page footer button.

Theme Boost styling changes

By default rounded edges will be used for UI components [https://tracker.moodle.org/browse/MDL-72455 MDL-72455], for the page header and main content area the borders will be removed [https://tracker.moodle.org/browse/MDL-72457 MDL-72457].

Component library

Navigation

The core Navigation API has been left mostly untouched. The callbacks to all navigation callbacks remains unchanged and will be called as part of the regular 'navigation' and 'settingsnav' initialisation. Some new core classes have been created and exist within a new namespace 'core/navigation' and serves as conduit to rearrange, cherry-pick existing navigation nodes from the navigation/settingsnav trees and display within the respective navigation type. As such, it is highly recommended to provide unique keys for custom navigation nodes as this helps in the cherry-picking / rearranging process within the new classes.

Primary navigation / Primary Output

The primary navigation(the navbar) apart from the existing content will now display links to the Dashboard, My Courses, Site Admin and Course search, by default. You can still add items to the navbar via the 'custom menu' option. This will be displayed within the 'More' menu. We have transitioned the menus to be rendered via templates - refer user_menu.mustache. The lang menu has been moved to reside within the user menu.

New view

All settings for courses/modules will now be displayed as tabs within the module. A predefined set of tabs will be shown with any remaining / newly added ones residing within the 'Course Admin' page. The settings cog will not be shown anymore. It is recommended to review any settings as some might be displayed as tabs and possibly move them to the tertiary navigation as is done in the core activity modules1. At most 5 tabs will be displayed to a user with all the overflow nodes now residing within the 'More' menu. Some of the nodes can be hidden by using the new functions defined.

New API functions
Page API
  • Magic getters to fetch the primary and secondary navs and the primary output.
  • The secondarynav magic getter also checks whether a custom secondary class has been defined within the module's local\views directory. Use this if you want to deviate from the standard secondary nav structure/order.
  • set_secondary_nav - Force override the secondary navigation class
  • has_secondary_navigation_setter - Sets the ‘_hassecondarynavigation’ to indicate whether a page should render the secondary navigation
Navigationlib
  • set_show_in_secondary_navigation - whether or not a node should be displayed in the secondary nav. Accepts a single boolean argument
  • set_force_into_more_menu- whether or not to force a node into the 'More' menu. Accepts a single boolean argument
Changing order of tabs in secondary navigation nodes

Apart from the previously mentioned functions, you can also create a custom secondary class as mentioned earlier. This will automatically be picked by getter and used to render the secondary nav within the activity. E.g. mod_assign/local/views/secondary. Note: This is currently only possible on an activity and block level.

Upcoming changes:
  1. 1 - Complete tertiary nav overhaul for core’s modules - [https://tracker.moodle.org/browse/MDL-71912 MDL-71912]. [https://tracker.moodle.org/browse/MDL-71913 MDL-71913],[https://tracker.moodle.org/browse/MDL-71914 MDL-71914],[https://tracker.moodle.org/browse/MDL-71915 MDL-71915]
  2. Backwards compatibility for complex deep nested custom navigation. Any custom navigation added by 3rd party devs will now be displayed as flatter structure within a URL select - [https://tracker.moodle.org/browse/MDL-72352 MDL-72352]
  3. New module API to inject common content at the top of a module page. The common content would be the title, description and activity information. This solves 2 issues:
    1. A centralised location where we can handle #2 and inject it into the relevant page
    2. A centralised location where we can inject items particularly activity_information without the need to be replicated in each module.

The core_courseformat subsystem

Most of the logic for rendering and editing a course has been moved to a new subsystem called courseformat. The subsystem is located in "course/format" folder so it includes all the format plugins inside. The methods and modules which are distributed between the course and the course/format folders are now rearranged or refactored to be aligned with the current Moodle coding style.

Mandatory renderer in course formats

Now format plugins renderer is not optional anymore. Legacy formats without a renderer will get a deprecation message but it will continue working however, they should create a new renderer as soon as possible. The section-based format can do it by extending the provided core_courseformat\output\section_renderer class which includes all the necessary methods.

New format base class

The old base_format class (which all plugins extend) is now renamed as core_courseformat\base. The new class provides all the functionally of the previous base_format but it has been refactored to be used as a centralized source of truth for the course rendering. Legacy formats should extend the new class to avoid the deprecation message.

Now, the plugin format class provides information such as:

  • If the page is displaying a single or multiple section
  • Give access to other related format objects like the modinfo, the course record, maximum number of sections...
  • If the format is compatible with features like course index, reactive components, ajax...
  • Other format specifics like the page title, the default section name, default blocks...


The format instance is now the main object output components will use to render a course (see next section for more information).

New course output classes and mustache files

Traditionally, section-based course formats uses print_single_section_page and print_multiple_section_page to render the course content. In Moodle 4.0 most of the course rendering methods are migrated to output components and mustache templates. The old methods will get deprecation messages if they use the old renderer methods.

This is an example of a format rendering a course:

// Get the course format instance.
$format = course_get_format($course);

// Get the specific format renderer.
$renderer = $format->get_renderer($PAGE);

if (!empty($displaysection)) {
    // Setup the format instance to display a single section.
    $format->set_section_number($displaysection);
}

// Create the ouptut instance and render it.
$outputclass = $format->get_output_classname('content');
$widget = new $outputclass($format);

echo $renderer->render($widget);

Format plugins are free to use its own output classes to render a course, or they could override the existing output classes by providing their own implementation. For example, the default output for "content" (as in the previous example) is "core_courseformat\output\local\|content", however, if the plugin has a "format_XXX\output\courseformat\content" class, the $format->class the get_output_class will return the overridden one.

Another important update on course rendering is that now all course structure is rendered using mustache templates instead of the original html_writer methods. Now themes are able to override the course format by providing alternative versions of the mustache files. All core course templates are located in "course/format/templates".

All the new output classes and a guide on how to migrate the current third-party plugins will be available soon.

Course editor javascript modules and frontend components

The majority of the javascript logic related to the course editing is replaced by AMD modules. Because this is a major change in the way courses are edited and rendered, by default format plugins will continue using the previous YUI modules for now. However, formats can start using the new libraries overriding the "$format->supports_components()" method.

Some Moodle 4.0 new features are only available for courses using the new editor library:

  • Edit the course via the course index
  • Creating sections without reloading the course page
  • The new move section/activity modal
  • Native browser drag&drop implementation

The new course editor uses a component-based reactive pattern to keep track of the course changes. The pattern highlights are:

  • The main AMD module "core_crouseformat\courseeditor" maintains a data structure called state.
  • Each UI element is implemented as a Component that observes the course state data and reacts to any data change
  • When any reactive component needs to modify the course, it asks the course editor to execute a mutation. Mutations encapsulate all web services calls and alter the course state data.


The reactive library documentation, as well as the format plugin migration guide, will be available soon.

Other course related 4.0 changes

Two new web services have been added:

  • core_courseformat_get_state: user by the new javascript course editor to get the current course state data (containing the list of sections, activities, and other course-related data)
  • core_courseformat_update_course: to alter the current course content. Each call returns the parts of the course state altered by the action

API changes

Behat changes

To make behat tests more readable and easy to maintain, it is recommended to use the most direct steps to get what the test needs. So since MDL-66335 was integrated, and the step was improved in MDL-72179 is highly recommended to use

I am on the "Activity name" "[modname] activity" page 

or

I am on the "Activity name" "[modname] activity" page logged in as "user"

instead of navigating to the activity via

I am on "Course" course homepage
I follow "Activity name"

Now that Course index (MDL-71209) is integrated but the project is not stable, these behat steps

I am on "Course" course homepage
I follow "Activity name"

will fail using Boost theme.

The reason for it is that the drawer used in Boost is hiding the course index. So when the test is trying to follow an "Activity name" link, it finds two different links:

  • one in the course index
  • another one in the course main content.

But the first one, the one in the course index, is hidden by the drawer, and the test fails.

However the recommended behat steps

I am on the "Activity name" "[modname] activity" page 

or

I am on the "Activity name" "[modname] activity" page logged in as "user"

work fine.

Some of the failing behats are fixed in https://github.com/ferranrecio/moodle/commit/c79d58a50b48aa6891ff1d3ba92a7b0ab2393c88#diff-fdf8b0b1eade3b69eaad038de0ddd7c8dec2be7afa32dc693fb929739a49fa9dR32 - MDL-71209

For example:

And I am on the "Test assignment name" "assign activity" page logged in as teacher1

instead of:

When I log in as "teacher1"
And I am on "Course" course homepage
And I follow "Test assignment name"

Core plugins review

A few plugins from core Moodle LMS which are no longer or hardly used have been removed and, if appropriate, added to the Moodle plugins directory.

More information about this project, the list of plugins to be removed and the process to follow for keeping them before upgrading to 4.0 can be found in the Core plugins review page.