Pulling a defined language out of multilang text

Pulling a defined language out of multilang text

by Martin Greenaway -
Number of replies: 6

Hi all,

In some code I have written, I have a form where I get a series of lists of values into various select boxes, where the select box text options need to be multilanguage-capable.  A simple example of the source would be something like this: 

<span class="multilang" lang="EN">Yes</span><span class="multilang" lang="FR">Oui</span>
<span class="multilang" lang="EN">No</span><span class="multilang" lang="FR">Non</span>
<span class="multilang" lang="EN">Prefer not to say</span><span class="multilang" lang="FR">Je préfère ne pas le dire</span>

However, the response value (which goes to an external web service) must only contain the English version.  I'd desperately like to avoid having to special case the creation of the arrays for each of these select boxes and hard code all the array keys. Obviously the following would work fine if the external web service accepted the foreign translations:

$rawoptions = explode(PHP_EOL, $sourcedata);
$optionsarray = array();
foreach($rawoptions as $value) {
  $optionsarray[format_string($value)] = format_string($value);
}

That would produce this sort of thing in French, for example:

Array
(
  [Oui] => Oui
  [Non] => Non
  [Je préfère ne pas le dire] => Je préfère ne pas le dire
)

However, I need an output that is something like this:

Array
(
  [Yes] => Oui
  [No] => Non
  [Prefer not to say] => Je préfère ne pas le dire
)

Am I right in thinking that there's no option I can pass to format_string() in order to get a specific language back?  I mean, format_string() just applies the filters, I'm assuming it can't manipulate how they are applied.

Does anyone have any suggestions on how to do this in a neat(ish) way, rather than hardcoding the options for every select box?

Average of ratings: -
In reply to Martin Greenaway

Re: Pulling a defined language out of multilang text

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

You can always change the current language to any language you want (as long as it's available in your Moodle site), and make get_string()/format_string() use it. E.g.:

$rawoptions = explode(PHP_EOL, $sourcedata);
$optionsarray = array();
$currlang = $CFG-&gt;lang;
foreach($rawoptions as $value) {
  $CFG-&gt;lang = 'en';
  $key = format_string($value);
  $CFG-&gt;lang = $currlang;
  $optionsarray[$key] = format_string($value);
}
$CFG-&gt;lang = $currlang;

Obviously, if you are doing this inside a function, don't forget to include $CFG in your globals list.

Saludos. Iñaki.

Average of ratings: Useful (1)
In reply to Iñaki Arenaza

Re: Pulling a defined language out of multilang text

by Martin Greenaway -

Ohhh, okay.  I thought it was defined by the something to do with the user's session settings, but if I can ("just") meddle with the $CFG->lang value, that would work fine. Certainly better than trying to reliably stripos and substring my way to the English value, which I've kind of got working but don't 100% trust. 


Thank you for this, I'll give it a try today.

In reply to Martin Greenaway

Re: Pulling a defined language out of multilang text

by Iñaki Arenaza -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

$CFG->lang is defined based on the user's session settings (see lib/setup.php, around line 877 in Moodle 3.3/3.4). But after digging through the code a bit more, the multilang filter ultimately calls current_language() to determine which language sub-string to pick.

And current_language() has an ordered list of criteria to define which the current language is, including things such as a session forced language, a course forced language, a session language (when the user selects a different language from the drop down menu), the user language and $CFG->lang (which by default is initialised as the user language).

So while playing with $CFG->lang produces the desired results most of the time (and that's why I've used it so far myself), I've discovered a nice little gem in lib/(moodlelib.php while spelunking current_language(). There is an official function to force a language for strings and dates localisation, which is called force_current_language(). In fact, this is how we set the "session forced language" that current_language() checks for.

So instead of playing with $CFG->lang, you should use force_current_language().

Saludos. Iñaki.

Average of ratings: Useful (2)
In reply to Iñaki Arenaza

Re: Pulling a defined language out of multilang text

by Martin Greenaway -

This is exactly what I needed - many thanks for your assistance on this!

In reply to Martin Greenaway

Re: Pulling a defined language out of multilang text

by Michael Milette -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers Picture of Translators

Hi Martin,

Since you are dealing with select boxes and need consistent language coming out of it, have you considered hard coding the value portion of the option element to the required language?

Example:

<select>
  <option value="yes">{mlang en}Yes{mlang}{mlang fr}Oui{mlang}</option>
  <option value="no">{mlang en}No{mlang}{mlang fr}Non{mlang}</option>
  <option value="secret">{mlang en}Prefer not to say{mlang}{mlang fr}Je préfère ne pas le dire{mlang}</option>
</select>

The result is that the information submitted will always be in the same language regardless of the user's preferred language.

The example above uses the the Multi-Language Content (v2) or Multi-lingual Content filters instead of the Moodle Multi-language Content. As you can see, it uses a much simpler plain text (no HTML) syntax that is easy for people to type in. Just in case this is still too complicated, there is also an Atto plugin called Multi-Language Content that lets course creators simply select text and specify it's language. Although it says that Multi-Language Content (v2) is required, it is compatible with Multi-lingual Content too since they use the same {mlang} tag syntax. Best of all, because you are not actually entering HTML into Moodle, you can use it in many more places in Moodle where HTML tags are not normally permitted. I have been using Multi-lingual Content since I first help conceive it years ago and both are compatible with Moodle up to and including Moodle 3.4.

Of course you could just use the regular HTML syntax from your example in the option elements and it would work too.

Hope you find this useful.

Best regards,

Michael Milette

In reply to Michael Milette

Re: Pulling a defined language out of multilang text

by Martin Greenaway -

Hi Michael,

Thanks for this. I was not aware of the mlang filters; I will certainly take a look at them, as they look much easier to create content with than the span tags.

However, the point behind the original question was that I'd really rather avoid hard-coding the keys, as if any of these options change in future, I will need to dive into the code then to change the keys accordingly.  At the moment these options are being pulled from a user profile dropdown field, which is simple enough to configure, and I don't want to introduce a dependency on code changes if I can help it.  Iñaki's response works very well for my needs here.

Regards,

Martin