Translating database fields

View: New views
13 Messages — Rating Filter:   Alert me  

Translating database fields

by Jeremy Andrews-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

I'm looking for advice on the proper way to resolve this issue:
  http://drupal.org/node/571742

Summary:
The support module [1] defines four default states ("new", "active",
"pending", "closed") and four default priorities ("low", "normal",
"high", "critical").  These fields are defined in the database to allow
the easy creation of custom states and priorities.  Because of this, I'm
unsure on how to correctly make them translatable.

The t() api documentation page [2] explicitly states, "however tempting
it is, custom data from user input or other non-code sources should not
be passed through t()."  It goes on to explain that doing so can lead to
orphaned words, mistranslation of non-English words, etc.  My question
then is, what is the correct way to make these states and priorities
translatable?

Yes, they can simply be changed in the database if you'd like to change
them to another language, but some websites want the ability to
translate them into multiple languages.

If replying, please do so in the issue linked above.

Thanks,
 -Jeremy

[1] http://drupal.org/project/support 
[2] http://api.drupal.org/api/function/t/6 



Re: Translating database fields

by Michael Prasuhn :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm sure others have a better handle on this, than I, and I'm sure  
they will chime in here.

My understanding is that you could run the output through t() but you  
would have to make sure that the users know and the edit page explains  
that the strings must be entered in English, and then in turn  
translated for each language by hand, using Locale.

One important point to note though, is that you will want to make sure  
that the default strings are run through t() somewhere in your code so  
that the extractor picks them up, and they are included in packaged  
translations. Do not however use the output of t() to insert as  
defaults into the database, as the default strings in the database  
must remain in English.

I believe I've read somewhere that some modules accomplish this by  
including a module_name.locale.php file or some similar with something  
like:

<?php

$foo = t('A string my module stores in the database');
$foo = t('Another string my module stores in the database');

So that the extractor will find these strings and include them in  
translation templates.

-Mike
__________________
Michael Prasuhn
503.512.0822 office
503.539.3864 cell
503.661.7574 home
mike@...
http://mikeyp.net

On Sep 22, 2009, at 6:23 PM, Jeremy Andrews wrote:

> Hello,
>
> I'm looking for advice on the proper way to resolve this issue:
>  http://drupal.org/node/571742
>
> Summary:
> The support module [1] defines four default states ("new", "active",
> "pending", "closed") and four default priorities ("low", "normal",
> "high", "critical").  These fields are defined in the database to  
> allow
> the easy creation of custom states and priorities.  Because of this,  
> I'm
> unsure on how to correctly make them translatable.
>
> The t() api documentation page [2] explicitly states, "however  
> tempting
> it is, custom data from user input or other non-code sources should  
> not
> be passed through t()."  It goes on to explain that doing so can  
> lead to
> orphaned words, mistranslation of non-English words, etc.  My question
> then is, what is the correct way to make these states and priorities
> translatable?
>
> Yes, they can simply be changed in the database if you'd like to  
> change
> them to another language, but some websites want the ability to
> translate them into multiple languages.
>
> If replying, please do so in the issue linked above.
>
> Thanks,
> -Jeremy
>
> [1] http://drupal.org/project/support
> [2] http://api.drupal.org/api/function/t/6
>
>


Re: Translating database fields

by Gábor Hojtsy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 23, 2009 at 3:23 AM, Jeremy Andrews <lists@...> wrote:
> Hello,
>
> I'm looking for advice on the proper way to resolve this issue:
>  http://drupal.org/node/571742

http://drupal.org/node/571742#comment-2073144

Gábor

Re: Translating database fields

by Ken Winters :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hmm, tt() doesn't seem very developer friendly.

If you're developing a module that is translatable, you can't  
realistically require i18n, and checking for the module / function in  
100 places would be unpleasant (assuming that it is normally used the  
same way as t() in the code).

Other than making a wrapper function in the module that passes to tt()  
if it exists, do you have any suggestions to make this cleaner?

- Ken Winters

On Sep 23, 2009, at 4:00 AM, Gábor Hojtsy wrote:

> On Wed, Sep 23, 2009 at 3:23 AM, Jeremy Andrews  
> <lists@...> wrote:
>> Hello,
>>
>> I'm looking for advice on the proper way to resolve this issue:
>>  http://drupal.org/node/571742
>
> http://drupal.org/node/571742#comment-2073144
>
> Gábor


Re: Translating database fields

by Gábor Hojtsy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 23, 2009 at 3:10 PM, Ken Winters <kwinters@...> wrote:
> Hmm, tt() doesn't seem very developer friendly.
>
> If you're developing a module that is translatable, you can't realistically
> require i18n, and checking for the module / function in 100 places would be
> unpleasant (assuming that it is normally used the same way as t() in the
> code).
>
> Other than making a wrapper function in the module that passes to tt() if it
> exists, do you have any suggestions to make this cleaner?

You definitely should not require i18n if your module just provides
optional translation support. You'll need to define tt() yourself
conditionally I guess. There is no way in Drupal (I know of) to
invoke_if_exists_otherwise_return_the_args_to_me(), even
module_invoke() skips returning you stuff if the hook was not defined.

Gábor

Re: Translating database fields

by Jeremy Andrews-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 2009-09-23 at 15:17 +0200, Gábor Hojtsy wrote:

> On Wed, Sep 23, 2009 at 3:10 PM, Ken Winters <kwinters@...> wrote:
> > Hmm, tt() doesn't seem very developer friendly.
> >
> > If you're developing a module that is translatable, you can't realistically
> > require i18n, and checking for the module / function in 100 places would be
> > unpleasant (assuming that it is normally used the same way as t() in the
> > code).
> >
> > Other than making a wrapper function in the module that passes to tt() if it
> > exists, do you have any suggestions to make this cleaner?
>
> You definitely should not require i18n if your module just provides
> optional translation support. You'll need to define tt() yourself
> conditionally I guess. There is no way in Drupal (I know of) to
> invoke_if_exists_otherwise_return_the_args_to_me(), even
> module_invoke() skips returning you stuff if the hook was not defined.

So you're suggesting that currently the "correct" way to make text
stored in the database translatable is to use tt()?  Why is tt() more
correct than t()?  Isn't tt() going to end up orphaning the translations
if the database text gets changed, the same as t()?  Doesn't tt() still
have the same problem when the database text gets changes to non-english
language?  Is what this is really solving is avoiding a misnomer,
avoiding putting "database defined text" into the "code defined text"
locale group?

What about Mike's suggestion to create a support.locale.php file whose
sole purpose is to expose default database strings?  Is that practice
frowned upon?  At this time it seems like the simplest solution, though
if someone decides to add their own custom states and/or priorities they
won't be translatable without also hacking the support.locale.php file.
How is this solved?  What is the proper way to be sure that any text
stored in the database is exposed to the translation system, even text
that may be added later by the user?

Sorry, it seems I'm still confused as to the proper solution.

Thanks,
 -Jeremy


Re: Translating database fields

by Gábor Hojtsy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Didn't you ask to follow up on the issue? :D

On Wed, Sep 23, 2009 at 3:48 PM, Jeremy Andrews <lists@...> wrote:
> So you're suggesting that currently the "correct" way to make text
> stored in the database translatable is to use tt()?

I don't know of a better way. We tried to get people to review
approaches for this in core for Drupal 6, but nobody showed up at that
time, so no such solution got into Drupal 6 consequently. Given lack
of interest it did not get into Drupal 7 either as it seems.

> Why is tt() more
> correct than t()?  Isn't tt() going to end up orphaning the translations
> if the database text gets changed, the same as t()?

I did not look into the current implementation (tt() is using some
abstractions :), but the idea is that unlike t(), you provide tt()
with more detailed meta information on the "location" of the string,
so you tell it that "this is status label number 3 from mymodule", so
when the status label 3 is updated, the string to translate can be
updated without leaving orphan strings behind. With t() you lack this
metainformation on the string (even in Drupal 7, unless you abuse the
context system to hell which is however not supposed to used in this
granularity given that it makes translation sharing impossible).

> Doesn't tt() still
> have the same problem when the database text gets changes to non-english
> language?

It segments this problem to at least the non-default textgroup. There
is obviously no way we can tell whether a string is English or not and
it is pointless to keep trying to get users to enter English text at
all times on a localized site. That would be crazy.

> Is what this is really solving is avoiding a misnomer,
> avoiding putting "database defined text" into the "code defined text"
> locale group?

The Drupal 6 textgroup system lets you segment strings and as
implemented with tt(), it also lets you use the location information
to update and look up strings based on the objects they relate to.
These are all unavailable if you use t(). Also, t() has some other
niceties, like caching short strings for easy lookup. Now if we'd tell
people to translate things like taxonomy with t() itself, then you can
easily end up with a huge cache of short strings (including all your
taxonomy terms) loaded up on every page. Pretty useless and resource
consuming.

We could say you might still somewhat safely use t() in some user
input cases, but it would still go with the leftover stale strings,
mixing up the English and non-English text in the database and on the
translation UI, etc. Textgroups and tt() exploiting them with the
location information attempts to solve these problems as well as not
letting user input go to the t() cache loaded on every page. which is
designed with the UI text mass in mind.

> What about Mike's suggestion to create a support.locale.php file whose
> sole purpose is to expose default database strings?  Is that practice
> frowned upon?  At this time it seems like the simplest solution, though
> if someone decides to add their own custom states and/or priorities they
> won't be translatable without also hacking the support.locale.php file.
> How is this solved?  What is the proper way to be sure that any text
> stored in the database is exposed to the translation system, even text
> that may be added later by the user?

As said, while technically t() might look like it solves your
problems, I'd advise against it. See above.

Gábor

Re: Translating database fields

by Jennifer Hodgdon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There's a whole section in the Handbook on how to do this:
    http://drupal.org/node/303984

    --Jennifer

Jeremy Andrews wrote:

> Hello,
>
> I'm looking for advice on the proper way to resolve this issue:
>   http://drupal.org/node/571742
>
> Summary:
> The support module [1] defines four default states ("new", "active",
> "pending", "closed") and four default priorities ("low", "normal",
> "high", "critical").  These fields are defined in the database to allow
> the easy creation of custom states and priorities.  Because of this, I'm
> unsure on how to correctly make them translatable.



--
Jennifer Hodgdon * Poplar ProductivityWare
www.poplarware.com
Drupal, WordPress, and custom Web programming


Re: Translating database fields

by mark burdett-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 23, 2009 at 7:42 AM, Jennifer Hodgdon <yahgrp@...> wrote:
> There's a whole section in the Handbook on how to do this:
>   http://drupal.org/node/303984

This is the specific page I used recently,
http://drupal.org/node/304002 "Making your custom data translatable"

Littering your module with if (module_exists('i18nstrings')) isn't so
nice, so I'm hoping that a future version of core will provide a real
API for string translation.. (where's the issue for this? :)

--mark

Parent Message unknown Re: Translating database fields

by Peter Droogmans :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

You can do the opposite, define a tt function if the module doesn't exist, it keeps your code cleaner


Met vriendelijke groeten,
Peter Droogmans
Attiks
Ketsstraat 94
2140 Borgerhout
peter@...
03-288 61 17
0497-44 44 77

-----Original Message-----
From: mark burdett <mfburdett@...>
Sent: woensdag 23 september 2009 18:40
To: development@... <development@...>
Cc: jeremy@... <jeremy@...>
Subject: Re: [development] Translating database fields


On Wed, Sep 23, 2009 at 7:42 AM, Jennifer Hodgdon <yahgrp@...> wrote:
> There's a whole section in the Handbook on how to do this:
>   http://drupal.org/node/303984

This is the specific page I used recently,
http://drupal.org/node/304002 "Making your custom data translatable"

Littering your module with if (module_exists('i18nstrings')) isn't so
nice, so I'm hoping that a future version of core will provide a real
API for string translation.. (where's the issue for this? :)

--mark


Re: Translating database fields

by Earl Miles :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Peter Droogmans wrote:
> You can do the opposite, define a tt function if the module doesn't exist, it keeps your code cleaner

You need to do it this way:

if (!module_exists('i18nstrings') && !function_exists('tt')) {
   function tt($string) {
     return $string;
   }
}

That way 2 modules trying to define tt() won't run over each other.

Re: Translating database fields

by Gábor Hojtsy-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 23, 2009 at 6:36 PM, mark burdett <mfburdett@...> wrote:

> On Wed, Sep 23, 2009 at 7:42 AM, Jennifer Hodgdon <yahgrp@...> wrote:
>> There's a whole section in the Handbook on how to do this:
>>   http://drupal.org/node/303984
>
> This is the specific page I used recently,
> http://drupal.org/node/304002 "Making your custom data translatable"
>
> Littering your module with if (module_exists('i18nstrings')) isn't so
> nice, so I'm hoping that a future version of core will provide a real
> API for string translation.. (where's the issue for this? :)

Mark, http://groups.drupal.org/node/18735 has links to issues with
different options.

Gábor

Re: Translating database fields

by Nedjo Rogers-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

mark burdett wrote:
> Littering your module with if (module_exists('i18nstrings')) isn't so
> nice, so I'm hoping that a future version of core will provide a real
> API for string translation.. (where's the issue for this? :)
>
> --mark

The most advanced patch is http://drupal.org/node/361597, but lamentably
we didn't get it complete for D7.