How to translate Form labels?
Permalink
Hi! I'm building a multilingual site in German and English in 5-7.5.13. The Multilingual feature works as expected and is pretty intuitive to use - good job! However, I'm struggling to get a custom view for the Form block translated.
For the form title it works as expected. I wrap it in the tc() function and when I Reload Strings in 'Translate Site Interface', it is picked up and I can translate it.
However, with the form labels inside the foreach loop, only one of the strings is picked up.
In the form I have field named 'Phone'. Only this string is picked up when I reload the strings.
I suspect it is only picked up and translated because this string also appears in other places around the site. See below entry in my de_CH.po file.
The other strings in the form labels such as "First Name", "Adults" and "Children" are not picked up when I reload the strings. I think I might have to add these to the file manually, because the t() function does not work in a loop...
Any pointers?
For the form title it works as expected. I wrap it in the tc() function and when I Reload Strings in 'Translate Site Interface', it is picked up and I can translate it.
<h2><?php echo tc('Form', 'Room Inquiry');?></h2>
However, with the form labels inside the foreach loop, only one of the strings is picked up.
<?php foreach ($questions as $question): <div class="form-group field field-<?php echo $question['type']; ?> <?php echo isset($errorDetails[$question['msqID']]) ? 'has-error' : ''?>"> <label <?php echo $question['labelFor']; ?>> <?php echo t($question['question']);?> <?php if ($question['required']):?><span class="text-muted small" style="font-weight: normal"><?php echo "*"?></span> <?php endif; ?></label> <?php echo $question['input']; ?> </div> </div> <?php endforeach; ?>
In the form I have field named 'Phone'. Only this string is picked up when I reload the strings.
<?php echo t($question['question']);?>
I suspect it is only picked up and translated because this string also appears in other places around the site. See below entry in my de_CH.po file.
#: application/blocks/msv_location_map/templates/msv_location_map/view.php:108 #: application/single_pages/dashboard/map_locations/locations/view.php:170 #: packages/views/blocks/msv_location_map/view.php:106 #: packages/views/single_pages/dashboard/map_locations/locations/view.php:170 msgid "Phone" msgstr "Telefon"
The other strings in the form labels such as "First Name", "Adults" and "Children" are not picked up when I reload the strings. I think I might have to add these to the file manually, because the t() function does not work in a loop...
Any pointers?
I don't know what I'm talking about.
But I'm wondering whether t() expects a literal. Could you refactor things such that t() is used when you add each of the literal values to $question[]?
But I'm wondering whether t() expects a literal. Could you refactor things such that t() is used when you add each of the literal values to $question[]?
Putting a variable inside t($variable) works technically, but is discouraged from use as far as practical because translation string extractors won't find the original strings. So anyone translating would need to dig through the code to find the origin of a variable rather than simply have the string presented to them by the t-string extractor.
Based on
https://documentation.concrete5.org/developers/concepts/localization...
t() wants a constant, although you can use t('%s', <const expression>). I can't see how that would help you within a loop, though. I'd still try wrapping the individual strings in t() when you initialise $questions. That way, each string gets a t() and you don't have to worry about t() in your loop.
https://documentation.concrete5.org/developers/concepts/localization...
t() wants a constant, although you can use t('%s', <const expression>). I can't see how that would help you within a loop, though. I'd still try wrapping the individual strings in t() when you initialise $questions. That way, each string gets a t() and you don't have to worry about t() in your loop.
The string that will be extracted by the translation system is the first argument of the t() function.
So, when using
the translation system will allow you to translate %s.
What's the translation of %s? It will always be %s... So this approach doesn't make sense.
The first argument of the t() function must me the literal string to be translated.
Since in this case we don't know the literal strings to be translated a priori, we have the following solutions:
1. we write a PHP file that won't be executed, but that contains the literal strings to be translated. This has been done for instance in the core in this file:
https://github.com/concrete5/concrete5/blob/develop/concrete/src/Sup...
2. since concrete5 8.1, if we are developing a package, we can add a getTranslatableStrings method that accepts a \Gettext\Translations instance: in this method you can add the strings to be translated (you'll be able to translate these strings in the /dashboard/system/multilingual/translate_interface dashboard page).
In this case, this getTranslatableStrings method should read the question texts, and add them to the \Gettext\Translations instance.
So, when using
t('%s', $something);
the translation system will allow you to translate %s.
What's the translation of %s? It will always be %s... So this approach doesn't make sense.
The first argument of the t() function must me the literal string to be translated.
Since in this case we don't know the literal strings to be translated a priori, we have the following solutions:
1. we write a PHP file that won't be executed, but that contains the literal strings to be translated. This has been done for instance in the core in this file:
https://github.com/concrete5/concrete5/blob/develop/concrete/src/Sup...
2. since concrete5 8.1, if we are developing a package, we can add a getTranslatableStrings method that accepts a \Gettext\Translations instance: in this method you can add the strings to be translated (you'll be able to translate these strings in the /dashboard/system/multilingual/translate_interface dashboard page).
In this case, this getTranslatableStrings method should read the question texts, and add them to the \Gettext\Translations instance.
@mlocati: are you sure that
won't work?
The documentation at
https://documentation.concrete5.org/developers/concepts/localization...
recommends something like
I just simplified it further to suit the context of this thread. If this is wrong, then we need to get the documentation changed.
t('%s', $something)
The documentation at
https://documentation.concrete5.org/developers/concepts/localization...
recommends something like
t('Edit %s', $blockTypeName)
Absolutely sure (I wrote that doc).
Translating "Edit %s" is meaningful (for instance, I'd translate it into Italian as "Modifica %s").
I would translate "%s" as "%s"...
Again, please remark that the translation system can only work on literal strings used as the first parameter of t().
Translating "Edit %s" is meaningful (for instance, I'd translate it into Italian as "Modifica %s").
I would translate "%s" as "%s"...
Again, please remark that the translation system can only work on literal strings used as the first parameter of t().
@mlocati: thanks. I understand now.
Grazie, I think I will use that approach to solve my problem!
You can do this compilation using msgfmt on the command line. msgfmt is part of the gettext package.