If I understand you correctly, Moodle can do most of the work for you without requiring any custom coding at all. Most of what you want to do is build in.
Configure the Moodle Language Menu
The first part here describes the process for enabling your Moodle site for multi-language support.
- As a Moodle Administrator, install the desired language packs that you want your Moodle site to support. You can do this by going to Site Administration > Language > Language Packs and installing the desired
languages. Take note of the ISO codes for each language. You will need this in step 6.
- Go to Site Administration > Language > Language settings.
- Enable Language Autodetect. That way, if the user is using one of your supported languages, it will default to that language.
- Set the Default Language. This is the language that will be used is if the user's browser is in an unsupported language.
- Enable Display Language Menu. This will make the language menu appear in Boost.
- Set Languages on language menu to "en,es,fr,it". If you have a dialect, such as fr_ca for French Canadian, include that one instead of "fr", even though the French language pack is installed. e.g. "en,es,fr_ca,it"
- Save your changes.
That's all there is to it. Your language menu should now appear and work correctly.
IMPORTANT: There is no such thing "No language" or "Nothing" in Moodle. Moodle must have a language and it can only be one of the languages installed. So doing a xx = "Nothing" as you indicated will never work. However, switching to a
language that does not exist in your Moodle site will cause Moodle to switch to the default language. You can try this from your dashboard by adding ?lang=xx to the URL.
In your message, I also noticed that all of your language names are in English.
This is not a good idea. If the person only speaks Spanish and not English, they will not be able to understand your language menu in order to make the desired selection. If you really want to change the names of the languages, you can do this by going
to
Site Administration >
Language >
Language Customization. For more information on how to customize language strings in Moodle, see
https://docs.moodle.org/en/Language_customisation
In my case, I have English and French Canadian installed so Moodle/Boost renders the language selection menu as:
Customizing the Language Selection Menu
Now, let's say that you don't particularly like the way Moodle is displaying the languages, e.g. English (en). This is the only time you will need to change some PHP in order to customize the Language selection menu.
The following describes how you can customize the names of the languages and remove the ISO language code.
A word of caution: It is never a good idea to customize the Boost theme. Why? Because the next time you update Moodle, any customizations you made to core Moodle code, including the Boost theme, will be overwritten and lost. I highly recommend that you clone the Boost theme first and then make your changes to that theme - if you have not already done so of course.
As you already figured out, the file to customize is indeed the classes/output/core_renderer.php. In this file, near the top, you will find a line that says use moodle_url; . Insert the following line right below it:
use custom_menu;
Next, right below the class core_renderer extends \core_renderer { line, add the following code:
/* Language menu customization by Michael Milette - May 3, 2020
* Trim unwanted parts of the language name.
*/
private function formatlangname($langname) {
// Remove the ISO language code between parentheses. e.g. English (en).
if (strpos($langname, '(')) {
$langname = substr($langname, 0, strpos($langname, '(') - 4);
}
// Remove the dialect part of the language (e.g. Français - Canada (fr_ca)).
if (strpos($langname, ' - ')) {
$langname = substr($langname, 0, strpos($langname, ' - '));
}
return trim($langname);
}
/**
* We want to show the custom menus as a list of links in the footer on small screens.
* Just return the menu object exported so we can render it differently.
*/
public function custom_menu_flat() {
global $CFG;
$custommenuitems = '';
if (empty($custommenuitems) && !empty($CFG->custommenuitems)) {
$custommenuitems = $CFG->custommenuitems;
}
$custommenu = new custom_menu($custommenuitems, current_language());
$langs = get_string_manager()->get_list_of_translations();
$haslangmenu = $this->lang_menu() != '';
if ($haslangmenu) {
$strlang = get_string('language');
$currentlang = current_language();
if (isset($langs[$currentlang])) {
$currentlang = $langs[$currentlang];
} else {
$currentlang = $strlang;
}
$currentlang = $this->formatlangname($currentlang);
$this->language = $custommenu->add($currentlang, new moodle_url('#'), $strlang, 10000);
foreach ($langs as $langtype => $langname) {
$langname = $this->formatlangname($langname);
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
}
}
return $custommenu->export_for_template($this);
}
/**
* Renders a custom menu object (located in outputcomponents.php)
*
* The custom menu this method produces makes use of the YUI3 menunav widget
* and requires very specific html elements and classes.
*
* @staticvar int $menucount
* @param custom_menu $menu
* @return string
*/
protected function render_custom_menu(custom_menu $menu) {
global $CFG;
$langs = get_string_manager()->get_list_of_translations();
$haslangmenu = $this->lang_menu() != '';
if (!$menu->has_children() && !$haslangmenu) {
return '';
}
if ($haslangmenu) {
$strlang = get_string('language');
$currentlang = current_language();
if (isset($langs[$currentlang])) {
$currentlang = $langs[$currentlang];
} else {
$currentlang = $strlang;
}
$currentlang = $this->formatlangname($currentlang);
$this->language = $menu->add($currentlang, new moodle_url('#'), $strlang, 10000);
foreach ($langs as $langtype => $langname) {
$langname = $this->formatlangname($langname);
$this->language->add($langname, new moodle_url($this->page->url, array('lang' => $langtype)), $langname);
}
}
$content = '';
foreach ($menu->get_children() as $item) {
$context = $item->export_for_template($this);
$content .= $this->render_from_template('core/custom_menu_item', $context);
}
return $content;
}
Explanation of related functions;
- lang_menu() function - Is currently only be used to detect whether a language menu exists. It is possible that some themes may use what comes out of it but, from what I could see, Moodle core uses this as if it was a function called
"haslangmenu". This is why it is not customized here.
- custom_menu_flat() function - This is the function that generates the language menu on narrow screens when the custom menu ends up being in the footer of the page.
- render_custom_menu() function - This is the function that generates the language menu at the end of the custom menu when viewed on a wider desktop screen.
If you are going to customize the language menu, be sure to apply any changes to both custom_menu_flat and render_custom_menu.
The above code is almost identical to the code found in the /lib/outputrenderer.php with the following modifications:
- Added the formatlangname function. As coded above, this function makes some formatting changes to the names of the languages which will be displayed.
- Added the 4 lines containing the word formatlangname.
The result? A beautiful, clean dropdown language menu like the ones you would see on other websites.
Of course, once you have it working, you can always customize the formatlangname function to apply any custom formatting that you might like. For example, some people like to include images of a country flags along with or instead of the language names while others might prefer to simply have a menu made up of 2 character language codes. My recommendation would be to keep accessibility in mind when doing such changes.
Other options
There is an other simple option: Place a list of languages within the General section of your courses and only including the available languages for that course? Example:
English | Français | ...
Best part: No programming involved. These can just be links but, add some Bootstrap classes to the links, and you can easily turn the links into a list of buttons. I would omit the current language from the list. This can easily be accomplished using the Multi-Language Content (v2) {mlang} tags.
This is probably better than trying to customize the language selection menu for every course.
Default Language
I don't know if you have ever tried switching language to one that does not exist in Moodle. It is safe and will simply switch you to the default language. By the way, there is no way in Moodle to
Course Custom Profile Fields\
With regards to accessing the course custom fields, as an example, take a look at the source code in FilterCodes' filter.php, specifically at the tag that retrieves custom course fields.
Hope you find this useful. I hope to see you at MoodleMoot Global 2020 Online next month!
Best regards,
Michael Milette