Problem/Motivation
The registration field formatter label is not translatable.
User story:
As a visitor viewing a site in another language, I want to see the registration link text in my language, so that I know what to do to register.
Proposed resolution
Use the String translation module (i18n_strings
, part of the Internationalization project (i18n
)) to make the string translatable.
Do NOT use t()
to translate variables (e.g.: t($text)
), especially because $text
is code entered by a user. Otherwise, this opens your site up to cross-site scripting and other security problems.
Remaining tasks
Write a patch that doesn't use t().- Review patch and RTBC
- Commit patch.
User interface changes
No changes to the registration module user interface. The label entered by the user becomes available in the String Translation interface, if the appropriate modules are enabled.
API changes
No changes to the registration module API. A new i18n_string group becomes available. Two new, internal functions become available to facilitate translation. Translations of the user-entered label are stored separately by the i18n_string module.
Original report by @zterry95
While trying to translate the formatter label of the register link. we can't get it works.
I have take some time to study this problem and I think it's a bug.
Here is the patch to fix this. Tested my my local and it works; the register label can be translated now.
attachment is the patch.
Comment | File | Size | Author |
---|---|---|---|
#4 | registration-2234915-4-translate_link_text.patch | 5.66 KB | mparker17 |
Comments
Comment #1
zterry95 CreditAttribution: zterry95 commentedComment #2
mgiffordSimple enough patch. Applies nicely to git.
Comment #3
mparker17From the documentation for the
t()
function:So, I'm marking this patch as "Needs work".
However, I have to fix this for a client site right now, so I'm assigning it to myself.
Comment #4
mparker17Drupal 7 core itself doesn't provide a way to translate arbitrary strings; but the Internationalization module (
i18n
) has a sub-module called String translation (i18n_strings
) that makes it relatively simple to bolt arbitrary string translation on to an existing module without rewriting how the module works internally. It does this by providing a function calledi18n_string()
, which, depending on how it's called will either register the string or retrieve the translated version (it's important that the string be registered first, so it becomes available to translate).Note that I didn't want to add a hard dependency on the
i18n_string
module, so, as suggested in the documentation on using the i18n API from other modules I wrapped calls to it's eponymous function in afunction_exists()
call, which I further wrapped in a "private", namespaced function so the code is more readable and so it acts the way the module did before if thei18n_string
module isn't installed.***
To use the i18n_string functionality, it's recommended you create a "i18n_string group" (namespace) for strings from your module, which you do by implementing
hook_i18n_string_info()
.Secondly, you need a way to generate a "key" when both saving and loading the user-entered string. In this case, I generated a key in the namespace "registration" (i.e.: the machine name of this module) that consisted of the entity type (e.g.: "node"), the bundle name (i.e.: content type; e.g. "campaign"), the view mode (e.g.: "full" for the full content view), the field name, and the machine name of the setting(s) we wanted to translate ("label"). However, since the view mode is not available at formatter-view-time, I stored a chunk of the key as a formatter setting (which I called
i18n_string_key
).Finally, you need to register the new string when it's saved. In this case, it was rather difficult because
registration_field_formatter_settings_form()
only deals with a chunk of the Manage display form, and modifying the form is not allowed (because it's not passed-by-reference) so I couldn't add a submit handler. The solution was to add a '#process' to the form-chunk. However, it turns out that, when processing the form-chunk,$form_state['submitted']
acts exactly opposite to the way I expected (i.e.: it's equal to TRUE when loading the form-chunk and FALSE when saving the form-chunk). Checking that the form was being submitted before registering the string was necessary to avoid blowing away the string's translation when a user just wants to look at the string.Comment #5
mparker17Comment #6
mparker17Comment #7
mparker17Comment #8
csc4 CreditAttribution: csc4 commentedBit unclear what's happening with this - it's a big issue on multilingual sites. According to @mgifford at https://www.drupal.org/node/2234915#comment-8755545 patch does the job so is there any reason it's not committed? Should we use it?
Should it perhaps be using hook_variable_info? That would mean we could translate via the variables module - cf r4032login.variable.inc
Comment #9
mgifford@csc4 I just said it applied to Git.
@mparker17 has rolled up a new patch that is ready for review. It follows a better approach for string translation.
This just needs a review. Have you tested it out yet @csc4? Even on SimplyTest.me
Comment #10
csc4 CreditAttribution: csc4 commentedI've tested https://www.drupal.org/files/issues/registration-2234915-4-translate_lin... and it's working for the node, but not working in panels is that because it's not using hook_variable_info?
Comment #11
idebr CreditAttribution: idebr commentedWhile this solves the issue by the OP, its scope is limited to the registration link in the field configuration. How should this fit in an effort to make other parts of Registration translatable? For example, Profile2 has a submodule to implement i18n for its custom entities: http://cgit.drupalcode.org/profile2/tree/contrib/profile2_i18n.module
Comment #12
Jochen Wendebaum CreditAttribution: Jochen Wendebaum commentedIt would be nice to get a final solution for this issue. I will not apply the first patch to get my site up, knowing that further updates of the module will brake it again. *sigh*
Comment #13
caxy4 CreditAttribution: caxy4 commentedI understand the user story and don't disagree with the need for translation in some cases – unfortunately we don't want to make the registration module dependent on i18n as it is a minority use case and getting site translation working robustly usually means a developer is involved that would be capable of applying this patch to suite his/her needs.
Closing as "Won't fix"
Comment #14
mparker17This doesn't add a dependency on i18n: it uses a function from
i18n_string
if the module is enabled, but if the module is missing, it doesn't do anything. Please review the patch and Translating user-entered strings in D7 for more details.Comment #15
caxy4 CreditAttribution: caxy4 commentedThanks for the follow up @mparker17 – I've reviewed and incorporated the patch (9b3a21c).
Let me know if it meets your needs before I close the ticket.
Comment #17
mparker17Looks good to me, thanks!
Comment #18
caxy4 CreditAttribution: caxy4 commentedGood to hear!
Closing as fixed.