CakePHP JavaScript文件的国际化

I'm wrapping up a project using Cakes internationalization features to allow our application to be translated into different languages. That's worked great.

A problem I've noticed though is there are a few places where text is added via JavaScript and this text does not currently come from the server at all. It's for things like dialogue boxes and a few pieces of text that change based on a users selection.

How have you handled this in your own applications? How would you handle this? Is there a library or component that handles this. What about any jQuery libraries?

CakePHP does not have a built-in / standard way of localizing JavaScript. It does offer various ways to localize strings 'in general'. See Internationalization & Localization

To localize strings that are output by JavaScript, consider;

  1. For 'static' strings (i.e. strings that are not depending on the content of your website), create localization files for your scripts. Many plugins use this approach For example, see this page on localizing the JQuery-UI date picker UI/Datepicker/Localization

  2. If you're already localizing strings in your website via .po files, and want to use the same translations in your JavaScript, you may consider to dynamically create the translation-files as mentioned in 1.), for example;

In your app/Config/routes.php, enable parsextensions, see File Extensions

Router::parseExtensions('json');

Create a controller that will output strings localized as JavaScript/JSON

http://example.com/localized/strings/eng.json

class LocalizedController extends AppController {

    public function strings($lang)
    {
        if('json' !== $this->request->ext) {
            throw new NotFoundException();
        }

        // Switch to the requested language
        Configure::write('Config.language', $lang);

        $strings = array(
            'hello',
            'world',
        );

        //translated the strings
        $translations = array();
        foreach ($strings as $string) {
             $translations[$string] = __($string);
        }

        // build and send a JSON response
        $this->autoRender = false;
        $this->response->type('json');
        $this->response->body(json_encode($translations));
        return $this->response;
    }

}

This json file should now be accessible via http://example.com/localized/strings/eng.json and can be loaded from within your javascripts at runtime

note

Just to clarify; the example is untested and just to illustrate the idea of dynamically creating JSON (or JavaScript) files containing localized strings. The code is far from efficient and (at least part of) the code should not be inside the controller, but (for example) inside a model.

You can also do it using JavaScript translation files with this format:

lang = {
    no: "No",
    yes: "Ja",
    agreed: "Akkoord"
}

One file per language, for example: lang.nl.js, lang.es.js, lang.en.js...

Then, you can check the current language and, depending on it, load one or another file:

if($this->Session->read('Config.language') == 'es'){
    $this->Html->script('lang.es', array('inline' => false));
}else{ 
    $this->Html->script('lang.en', array('inline' => false));
}

And inside your javascripts, instead of using something like this:

alert("Yes");

You should use this:

alert(lang.yes);

And that's it :)

For translating JavaScript inside my CakePHP applications, I use this library : https://github.com/wikimedia/jquery.i18n , it's the one used in Wikipedia.

You have all the necessary files inside the src folder. It's quite easy to set up and use. Of course it works with any kind of application, not only CakePHP !

I had the same problem like you and i found this link very helpful: http://jamnite.blogspot.de/2009/05/cakephp-form-validation-with-ajax-using.html

It's not up to date, but the main principle should be clear.

Checkout this CakePHP plugin: https://github.com/wvdongen/CakePHP-I18nJs

It uses the functionality of Drupal 8 JavaScript translations. It has CakePHP console functions to generate .po file(s) (exactly as you're used with Cake), and to generate your translated .po files to JavaScript.

Here's a solution i'm using for cakePHP 3 :

in your layout file ( mine is default.ctp ) :

if( isset( $translated_js ) && !empty( $translated_js ) ){
    $this->Html->scriptStart($block_render);
    echo "var translated_js = " . json_encode( $translated_js ) . ";";
    $this->Html->scriptEnd();
}

Now in any controller add a beforeRender method :

public function beforeRender(Event  $event){
    parent::beforeRender( $event );     

    $translated_js = [
        'reinit_map' => __('Reinit map to default'),            
    ];

    $this->set( 'translated_js' , $translated_js );
}

This way you can use the gettext instructions.

In your JS files you can now use the translated eelements this way :

translated_js.reinit_map

Hope it helps someone searching a way to translate texts and pass to JS

I use a more straightforward method. ( I do not know if it is the best, but it works ).

Inside the template file I define a series of hidden fields with the messages that js might need.

echo( $this->Form->hidden( 'msg-select-promotion-items', [ 'value' => __( 'Select promotion items' ) ] ) );

Here we take advantage of cake's own localization system.

And then in the js file :

alert( $('input[name=msg-select-promotion-items]').val() );

Hope this helps. Regards. Facundo.

I took the easier path:

alert( "<?php echo __('This is my translated string'); ?>" )

This way you can keep all translations in a single place: the .po file