Themes & Frontend

Interview Questions: Mustache, Renderers, and AMD

Q1: How do you override a core template in a theme?

Copy the original mustache file from the component (e.g., mod/forum/templates/discussion.mustache) to your theme's template directory (e.g., theme/mytheme/templates/mod_forum/discussion.mustache).

Moodle will automatically prioritize the theme's version.

Q2: What are AMD modules in Moodle?

Asynchronous Module Definition (AMD) is used for JavaScript modularity (RequireJS). It allows you to define dependencies and load scripts only when needed.

define(['jquery', 'core/modal'], function($, Modal) {
    return {
        init: function() {
            // Your code here
        }
    };
});

Q3: Explain the role of `config.php` in a Moodle theme.

The `config.php` file is the heart of a Moodle theme. It defines:

  • $THEME->name: The internal name of the theme.
  • $THEME->parents: Which themes this theme inherits from (e.g., `['boost']`).
  • $THEME->sheets: List of CSS/SCSS files to include.
  • $THEME->layouts: Defines different page layouts (e.g., frontpage, course, admin) and maps them to layout files.
  • $THEME->rendererfactory: Controls how renderers are overridden.

Q4: How does Moodle handle SCSS compilation?

Moodle uses a PHP-based SCSS compiler. In a theme based on Boost, you typically define a `scss` function in `lib.php` or configure `$THEME->scss` in `config.php`.

Moodle compiles the SCSS (including Bootstrap variables and Moodle core styles) into a single cached CSS file. When "Theme Designer Mode" is enabled, this compilation happens on every request; otherwise, it is cached.

Q5: What is a Renderer in Moodle and why would you override it?

A Renderer (Output Class) is a PHP class responsible for generating HTML. Core components use renderers to output their interface.

You override a renderer in a theme to change the HTML structure of a component without modifying core code. This is done by creating a class in your theme that extends the core renderer and defining it in `$THEME->rendererfactory` or following the naming convention `theme_mytheme_renderer_componentname`.

Q6: How do you pass data from PHP to a Mustache template?

Data is passed as a context array or object (stdClass) to the `render_from_template` method of the output manager.

$data = [
    'title' => 'Hello World',
    'items' => ['A', 'B', 'C']
];
echo $OUTPUT->render_from_template('local_myplugin/mytemplate', $data);

Q7: What are "Template Helpers" in Moodle Mustache?

Moodle provides specific helpers to perform logic or fetch core data within templates:

  • {{#str}}key, component, a{{/str}}: Fetches a language string.
  • {{#pix}}icon, component, alt{{/pix}}: Renders an icon.
  • {{#quote}}content{{/quote}}: Escapes JSON content.
  • {{#shortentext}}text, length{{/shortentext}}: Truncates text.
  • {{#userdate}}timestamp, format{{/userdate}}: Formats a timestamp.

Q8: How do you include a JavaScript module in a Mustache template?

You use the `{{#js}}` helper at the end of the template. This ensures the JS runs after the DOM elements are rendered.

{{#js}}
require(['local_myplugin/myscript'], function(MyScript) {
    MyScript.init();
});
{{/js}}

Q9: What is the difference between `Boost` and `Classic` themes?

Boost is based on Bootstrap 4 (and moving to 5). It uses a flat navigation drawer (or top nav in newer versions) and is the modern standard for Moodle themes.

Classic is a legacy-style theme that retains the "block" regions on both left and right sides and uses a more traditional navigation bar. It is also based on Bootstrap but mimics older Moodle layouts.

Q10: How do you add a new region (block area) to a theme layout?

1. Edit the layout file (e.g., `layout/columns2.php`).

2. Use `$OUTPUT->blocks('region-name')` to render the region in the HTML.

3. Register the region in `config.php` under `$THEME->layouts` for the specific page types where it should appear.

4. Define the region name in the language file so it appears nicely in the UI.

Q11: What is "Theme Designer Mode"?

It is a setting in Site administration > Appearance > Themes > Theme settings.

When enabled, Moodle does not cache CSS or JavaScript. This is essential for development so you can see changes immediately, but it significantly degrades performance and should never be used in production.

Q12: How do you use FontAwesome icons in Moodle?

Moodle core includes FontAwesome. You can use them in HTML via standard classes (e.g., ``).

In Mustache templates, it is better to use the `{{#pix}}` helper if mapping to Moodle core icons, or direct HTML if specific FA icons are needed that aren't mapped.

Q13: What is the purpose of `lib.php` in a theme folder?

It contains theme-specific PHP functions. Common uses include:

  • theme_mytheme_get_main_scss_content(): To inject dynamic SCSS variables.
  • theme_mytheme_pluginfile(): To serve files (like logos) uploaded to theme settings.
  • theme_mytheme_page_init(): To run code before the page is fully set up.

Q14: How do you create a settings page for your theme?

Create a `settings.php` file in your theme root. Use the global `$ADMIN` object to add a `admin_settingpage`.

You can add settings like text boxes, file uploads (for logos), color pickers, and checkboxes. These values are then accessible via `get_config('theme_mytheme', 'settingname')`.

Q15: Explain the "Cascade" in Moodle Themes.

Moodle themes can inherit from parent themes. If a file (template, layout, CSS) is not found in the current theme, Moodle looks in the parent theme, and finally in the core.

For example, if `theme_child` inherits from `theme_boost`, and you request a forum template, Moodle checks `theme_child`, then `theme_boost`, then `mod_forum`.

Q16: How do you debug JavaScript in Moodle?

1. Enable "Debug messages" to DEVELOPER.

2. Disable "Cache all javascript" in Theme Settings.

3. Use `console.log()` in your AMD modules.

4. Use the browser's Developer Tools (Sources tab) to set breakpoints. Note that with RequireJS, files are loaded asynchronously.

Q17: What is Grunt and why is it used in Moodle themes?

Grunt is a JavaScript task runner. In Moodle, it is used to:

  • Compile AMD modules (transpile ES6 to ES5, minify).
  • Compile SCSS to CSS (optional, usually done by PHP in dev).
  • Lint CSS (Stylelint) and JS (ESLint).

You run `grunt` or `grunt watch` in the Moodle root directory.

Q18: How do you handle internationalization (i18n) in JavaScript?

You cannot use `get_string()` directly in JS. Instead, you must pre-load strings.

Method 1 (AMD): Use the `core/str` module.

require(['core/str'], function(str) {
    str.get_string('submit', 'core').then(function(s) {
        console.log(s);
    });
});

Method 2 (Mustache): Use `{{#str}}` helper, which renders the string server-side.

Q19: What are "Fragments" in Moodle?

Fragments allow you to load a piece of Moodle content (usually a Mustache template + data) via AJAX.

They are useful for dynamic interfaces where you need to render a part of a page (like a modal content or a form) without reloading the whole page. You use `core/fragment` in JS to fetch them.

Q20: How do you override a core CSS class without using `!important`?

Increase the specificity of your CSS selector. Since your theme's CSS is loaded after core CSS, using the same specificity usually works, but nesting it inside the `body` or a specific region ID is safer.

Example: Instead of `.btn-primary { ... }`, use `body#page-mod-forum-view .btn-primary { ... }`.

Q21: What is the `outputcomponents` folder in a theme?

It is a deprecated location for renderers in older themes. Modern themes should place renderer overrides in `classes/output/` or simply `classes/` following the autoloading standard.

Q22: How do you customize the login page?

The login page uses a specific layout. You can:

1. Customize the `login` layout file in your theme.

2. Override the `core/login` mustache template.

3. Use CSS to style the existing login form.

4. Add instructions via Site administration > Plugins > Authentication > Manage authentication.

Q23: What is the difference between `require` and `define` in AMD?

define: Used to define a module that can be reused. It returns an object or function.

require: Used to load dependencies and execute code immediately, usually as the entry point of a script.

Q24: How do you use ES6 syntax in Moodle JavaScript?

You can write ES6 code in your `.js` files (e.g., `amd/src/myscript.js`).

You must run `grunt` (specifically the `amd` task) to transpile this code into ES5 compatible code in `amd/build/myscript.min.js`. Moodle serves the files from `amd/build/`.

Q25: How do you add a custom font to Moodle?

1. Place font files in `theme/mytheme/fonts/`.

2. In your SCSS file, use `@font-face` to load them.

3. Ensure you use the correct relative path or the `[[font:theme|filename]]` placeholder if processing via Moodle's CSS compiler.

Q26: What is the `user_preference` in the context of UI?

It allows you to store small UI states for a user, like "sidebar collapsed" or "preferred view mode".

You can set it via the `core_user/repository` module in JS or `set_user_preference()` in PHP. This ensures the UI state persists across sessions.

Q27: How do you ensure your theme is accessible (WCAG)?

1. Use semantic HTML (headings, lists, landmarks).

2. Ensure sufficient color contrast.

3. Support keyboard navigation (focus states).

4. Use ARIA attributes where necessary (e.g., for dynamic content).

5. Use the "Accessibility toolkit" plugin or browser tools like Lighthouse to audit.

Q28: What is the `pix` folder in a theme?

It stores images and icons. If you place an icon with the same name as a core icon (e.g., `pix/t/locked.png`) in your theme, Moodle will use your version instead of the core version throughout the site.

Q29: How do you create a "Child Theme"?

1. Create a new folder `theme/childname`.

2. Create `config.php` and set `$THEME->parents = ['parenttheme'];`.

3. Create `version.php`.

4. You only need to include the files you want to override (CSS, templates, renderers). Everything else falls back to the parent.

Q30: What is the `core/modal` module?

It is the standard way to create pop-up modals in Moodle.

There are subtypes like `core/modal_save_cancel`. You use the `ModalFactory` to create one and `ModalEvents` to listen for actions (like closing or saving).