Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] I18n with keys/identifiers and strings to be translated #567

Open
enov opened this issue Nov 13, 2014 · 6 comments
Open

[Proposal] I18n with keys/identifiers and strings to be translated #567

enov opened this issue Nov 13, 2014 · 6 comments
Labels
Milestone

Comments

@enov
Copy link
Contributor

enov commented Nov 13, 2014

Hello all!

This is a proposal to enhance the Kohana I18n system to allow look up with keys while at the same time keeping the strings that needs to be translated in full and in its default language within the views.

There has been numerous discussions regarding whether to store the identifiers or the whole strings within the i18n dictionary folder. Both approaches have their advantages and disadvantages. This is to propose declaring both (identifier/key and whole string) in the View, like so:

__(['welcome_text' => 'Welcome to my site, this is a very long welcome message that you might not want to use it as key in your dictionary files']);

Then in the dictionary file you set:

return array (
    'welcome_text' => 'Բարեւ, բարեւ բարեւ ․․․',
);

I have a tentative code that makes this work, it just changes I18n::get and it is fully compatible with string only version we have already. This works whether you use identifiers, whole strings or an array of both, as described in this proposal.

    public static function get($string, $lang = NULL)
    {
        if (!$lang)
        {
            // Use the global target language
            $lang = I18n::$lang;
        }

        // Load the translation table for this language
        $table = I18n::load($lang);

        // Return the translated string if it exists
        if (is_string($string))
        {
            return isset($table[$string]) ? $table[$string] : $string;
        }
        else if (is_array($string))
        {
            // get the first key value pair from the array
            $val = reset($string);
            $key = key($string);

            // return translation based on the key
            if (isset($table[$key]))
            {
                return $table[$key];
            }
            // return translation based on value
            else if (isset($table[$val]))
            {
                return $table[$val];
            }
            // translation not found, return value
            else
            {
                return $val;
            }
        }
    }

References:
http://blog.mixu.net/2010/11/11/kohana-3-i18n-tutorial/
http://forum.kohanaframework.org/discussion/comment/24814/
http://forum.kohanaframework.org/discussion/comment/41757/

@enov enov added the Idea label Nov 13, 2014
@enov enov added this to the 3.4.0 milestone Nov 13, 2014
@ursoforte
Copy link

I think with "Storing identifiers" be better to translate phrases and big paragraphs.
__('welcome.back');

"Storing the translated string" does not seem to be suitable for large paragraphs.
__('Welcome Back');

@enov
Copy link
Contributor Author

enov commented Nov 15, 2014

@sudeste, exactly. The proposal is to store both, identifier and full string, in a single array element, in order:

  • To have shorter keys in the dictionary files (an advantage of storing identifiers)
  • To have the default language text available, when the translation is not (advantage of storing full string)
  • No need to change the keys in the dictionaries when changing the default translation text (an advantage of storing identifiers)

@acoulton
Copy link
Member

@enov I like this, although it does feel like keeping it backward compatible makes the method API a bit uncomfortable - since otherwise you would presumably just do get($key, $default, $default_lang); But there's already quite a bit of API change in 3.4 so maybe we need to stick with it.

Either that, or add a new method with a clean signature for this and deprecate the old one which would make it easier to find old-style usage.

Is there potential confusion between this and the kohana messages - which are also using key lookups but in totally separate tables?

@enov
Copy link
Contributor Author

enov commented Nov 19, 2014

keeping it backward compatible makes the method API a bit uncomfortable

Yeah, it does make the API a bit uncomfortable.

add a new method with a clean signature for this and deprecate the old one which would make it easier to find old-style usage.

Note that the __ function defined in bootstrap wraps I18n::translate.
Maybe we should add a new method I18n::ktranslate with additional $key argument and have ___ (tripple underscore) function in bootstrap? I am not 100% sure if this is good, though.

@acoulton
Copy link
Member

@enov Definitely a new method in I18n makes sense - though I'd go for clarity over conciseness, I18n::translate_key or I18n::lookup or something rather than ktranslate which would easily be misread and isn't really clear about what it is.

Similarly having __ and ___ is very poor for comprehension and typo-safety I think. TBH I've never really understood why or how the whole underscore thing became a convention. Partly I think it was just to avoid collisions with other global functions but there are much better ways to do that now.

Why not just translate or message or lang or something? It could be namespaced and explicitly imported if conflicts are an issue. If the PHP code block is going to fit in the key and the default message and the language it's in, then saving a couple of characters on the function name seems pretty pointless.

I do still think there's also an issue that we have I18n lookups and Kohana::message which would now do similar things (neither directly supporting parameters) and then also code dotted around other places eg in Validation that does strtr stuff on the results.

If I was going to design from scratch, I'd possibly consider making each distinct message a data class of some kind that could hold both the key and any expected params, and then a service class that can look up the appropriate translation and deal with replacements - and use that to replace both Kohana::message and I18n::translate.

So the view would look something like:

<p><?=message(new \Application\Message\WelcomeTextMessage($username));?></p>

Or you'd potentially handle that in a view model and just pass the resultant string to the template.

Maybe that's overkill for simple strings though, I dunno, and it would certainly not be BC.

@ursoforte
Copy link

Sorry revive it post.

I rethought this case a few days.
For more complete texts is better to use Gettext (has good modules easy to Kohana as Zend-i18n). The current form of Kohana is simple is functional for small texts.

I used "Zend-i18n / Gettext" and works perfectly for full texts

@neo22s neo22s modified the milestones: 5.0.0, 3.4.0 Mar 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants