Skip to content

Commit

Permalink
MDL-68227 core_h5p: localize H5P editor strings
Browse files Browse the repository at this point in the history
H5P editor has a folder with all supported languages in JS files.
A mechanish has been added to let users to translate them using AMOS.
That's how the translations are managed (the order how they are processed):

- If there a JS file for a language, it's loaded.
- If a string has been translated in Moodle (they are placed in
h5plib_vXXX), it will override strings loaded from the JS file.
  • Loading branch information
sarjona committed May 12, 2020
1 parent 206e179 commit a42a9ad
Show file tree
Hide file tree
Showing 8 changed files with 401 additions and 18 deletions.
52 changes: 44 additions & 8 deletions h5p/classes/editor.php
Expand Up @@ -378,15 +378,10 @@ private function add_assets_to_page(): void {
$PAGE->requires->js(autoloader::get_h5p_editor_library_url('scripts/h5peditor-editor.js' . $cachebuster), true);
$PAGE->requires->js(autoloader::get_h5p_editor_library_url('scripts/h5peditor-init.js' . $cachebuster), true);

// Add translations.
// Load editor translations.
$language = framework::get_language();
$languagescript = "language/{$language}.js";

if (!file_exists("{$CFG->dirroot}" . autoloader::get_h5p_editor_library_base($languagescript))) {
$languagescript = 'language/en.js';
}
$PAGE->requires->js(autoloader::get_h5p_editor_library_url($languagescript . $cachebuster),
true);
$editorstrings = $this->get_editor_translations($language);
$PAGE->requires->data_for_js('H5PEditor.language.core', $editorstrings, false);

// Add JavaScript settings.
$root = $CFG->wwwroot;
Expand Down Expand Up @@ -423,6 +418,47 @@ private function add_assets_to_page(): void {
$PAGE->requires->data_for_js('H5PIntegration', $settings, true);
}

/**
* Get editor translations for the defined language.
* Check if the editor strings have been translated in Moodle.
* If the strings exist, they will override the existing ones in the JS file.
*
* @param string $language The language for the translations to be returned.
* @return array The editor string translations.
*/
private function get_editor_translations(string $language): array {
global $CFG;

// Add translations.
$languagescript = "language/{$language}.js";

if (!file_exists("{$CFG->dirroot}" . autoloader::get_h5p_editor_library_base($languagescript))) {
$languagescript = 'language/en.js';
}

// Check if the editor strings have been translated in Moodle.
// If the strings exist, they will override the existing ones in the JS file.

// Get existing strings from current JS language file.
$langcontent = file_get_contents("{$CFG->dirroot}" . autoloader::get_h5p_editor_library_base($languagescript));

// Get only the content between { } (for instance, ; at the end of the file has to be removed).
$langcontent = substr($langcontent, 0, strpos($langcontent, '}', -0) + 1);
$langcontent = substr($langcontent, strpos($langcontent, '{'));

// Parse the JS language content and get a PHP array.
$editorstrings = helper::parse_js_array($langcontent);
foreach ($editorstrings as $key => $value) {
$stringkey = 'editor:'.strtolower(trim($key));
$value = autoloader::get_h5p_string($stringkey, $language);
if (!empty($value)) {
$editorstrings[$key] = $value;
}
}

return $editorstrings;
}

/**
* Preprocess the data sent through the form to the H5P JS Editor Library.
*
Expand Down
21 changes: 20 additions & 1 deletion h5p/classes/helper.php
Expand Up @@ -82,7 +82,6 @@ public static function save_h5p(factory $factory, \stored_file $file, \stdClass
return false;
}


/**
* Get the error messages stored in our H5P framework.
*
Expand Down Expand Up @@ -410,4 +409,24 @@ public static function get_cache_librarykey(string $library): string {
// Remove whitespaces and replace '.' to '_'.
return str_replace('.', '_', str_replace(' ', '', $library));
}

/**
* Parse a JS array to a PHP array.
*
* @param string $jscontent The JS array to parse to PHP array.
* @return array The JS array converted to PHP array.
*/
public static function parse_js_array(string $jscontent): array {
$jsarray = preg_split('/,\n\s+/', substr($jscontent, 0, -1));
$jsarray = preg_replace('~{?\\n~', '', $jsarray);

$strings = [];
foreach ($jsarray as $key => $value) {
$splitted = explode(":", $value, 2);
$value = preg_replace("/^['|\"](.*)['|\"]$/", "$1", trim($splitted[1], ' ,'));
$strings[ trim($splitted[0]) ] = str_replace("\'", "'", $value);
}

return $strings;
}
}
11 changes: 11 additions & 0 deletions h5p/classes/local/library/autoloader.php
Expand Up @@ -149,6 +149,17 @@ public static function get_h5p_editor_library_base(?string $filepath = null): st
return component_class_callback(self::get_handler_classname(), 'get_h5p_editor_library_base', [$filepath]);
}

/**
* Returns a localized string, if it exists in the h5plib plugin and the value it's different from the English version.
*
* @param string $identifier The key identifier for the localized string
* @param string $language Language to get the localized string.
* @return string|null The localized string or null if it doesn't exist in this H5P library plugin.
*/
public static function get_h5p_string(string $identifier, string $language): ?string {
return component_class_callback(self::get_handler_classname(), 'get_h5p_string', [$identifier, $language]);
}

/**
* Register the H5P autoloader.
*/
Expand Down
25 changes: 25 additions & 0 deletions h5p/classes/local/library/handler.php
Expand Up @@ -123,6 +123,31 @@ public static function get_h5p_editor_library_url(?string $filepath = null, ?arr
return new \moodle_url(static::get_h5p_editor_library_base($filepath), $params);
}

/**
* Returns a localized string, if it exists in the h5plib plugin and the value it's different from the English version.
*
* @param string $identifier The key identifier for the localized string
* @param string $language Language to get the localized string.
* @return string|null The localized string or null if it doesn't exist in this H5P library plugin.
*/
public static function get_h5p_string(string $identifier, string $language): ?string {
$value = null;
$h5pversion = static::get_h5p_version();
$component = 'h5plib_v' . $h5pversion;
if (get_string_manager()->string_exists($identifier, $component)) {
$defaultmoodlelang = 'en';
// In Moodle, all the English strings always will exist because they have to be declared in order to let users
// to translate them. That's why, this method will only replace existing key if the value is different from
// the English version and the current language is not English.
$string = new \lang_string($identifier, $component);
if ($language === $defaultmoodlelang || $string->out($language) !== $string->out($defaultmoodlelang)) {
$value = $string->out($language);
}
}

return $value;
}

/**
* Return the list of classes with their location within the joubel directory.
*
Expand Down
7 changes: 7 additions & 0 deletions h5p/h5plib/v124/joubel/editor/readme_moodle.txt
Expand Up @@ -8,6 +8,13 @@ Import procedure:
- Copy all the files from the folder repository in this directory.
- In the method ns.LibrarySelector.prototype.appendTo (scripts/h5peditor-library-selector.js),
comment the line "this.$selector.appendTo($element);" to avoid the display of the Hub Selector.
- Review strings in joubel/editor/language/en.js and compare them with
existing ones in lang/en/h5plib_vXXX.php: add the new ones and remove the
unexisting ones. Remember to use the AMOS script commands, such CPY, to copy
all the existing strings from the previous version. As you'll see, all the
strings in en.js have been converted following these rules:
* Prefix "editor:" has been added.
* Keys have been lowercased.

Removed:
* composer.json
Expand Down

0 comments on commit a42a9ad

Please sign in to comment.