• Resolved amplifiction

    (@amplifiction)


    I have been handed an existing WP plugin for translation. I am using the WP __() function, which works fine in all cases, except for the following. (This is the relevant part of the code, of course, not all of it.)

    class Co_product_configurator_Public {
    
        private $ins_banister_right;
        private $ins_banister_left;
        private $ins_none;
    
        public function __construct( $plugin_name, $version ) {
    
            $this->ins_banister_right = __( "Rampe d'escalier à droite", 'co_product_configurator');
            $this->ins_banister_left =  __( "Rampe d'escalier à gauche", 'co_product_configurator');
            $this->ins_none = __( 'Aucun', 'co_product_configurator');
        }
    
        public function copc_get_banister_product_by_height( $height = ''){
    
            $select_html .= '<div class="copc_banister_field"><label>'. $this->ins_banister_left .'</label><select name="copc_banister_left">';
            $select_html .= '<option value="">'. $this->ins_none .'</option>';
    
            $select_html .= '<div class="copc_banister_field"><label>'. $this->ins_banister_right .'</label><select name="copc_banister_right">';
            $select_html .= '<option value="">'. $this->ins_none .'</option>';
        }
    
    
    }
    

    My .po file contains: (line numbers are accurate)

    #: public/class-co_product_configurator-public.php:64
    msgid "Rampe d'escalier à droite"
    msgstr "Trapleuning rechts"
    
    #: public/class-co_product_configurator-public.php:65
    msgid "Rampe d'escalier à gauche"
    msgstr "Trapleuning links"
    
    #: public/class-co_product_configurator-public.php:66
    msgid "Aucun"
    msgstr "Geen"

    Problem is, the original French strings are showing up, (msgid) not the translated variants (msgstr).

    My .po file is functioning, as strings anywhere else in the plugin are correctly translated.

    Any help would be appreciated!

Viewing 5 replies - 1 through 5 (of 5 total)
  • I suspect the special characters are the problem. The original texts for translations should be in English, the translation then in French (and any other language you need). English does not have such special characters, which is probably why the problem occurs.

    Thread Starter amplifiction

    (@amplifiction)

    @threadi Thanks for the suggestion, but even without special characters, the strings don’t get translated. $ins_none is an example of that.

    Furthermore, replacing the variables with their content results in correct translations:

    // WORKS:
    
            $select_html .= '<div class="copc_banister_field"><label>'. __( "Rampe d'escalier à gauche", 'co_product_configurator') .'</label><select name="copc_banister_left">'; // $this->ins_banister_left
            $select_html .= '<option value="">'. __( 'Aucun', 'co_product_configurator') .'</option>'; // $this->ins_none
    
    // DOESN'T WORK:
    
            $select_html .= '<div class="copc_banister_field"><label>'. $this->ins_banister_left .'</label><select name="copc_banister_left">';
            $select_html .= '<option value="">'. $this->ins_none .'</option>';
    

    So there must be something wrong with the variables: with their declaration, initialization and/or usage. To reiterate:

    class Co_product_configurator_Public {
    
        private $ins_banister_right;
        private $ins_banister_left;
        private $ins_none;
    
        public function __construct( $plugin_name, $version ) {
    
            $this->ins_banister_right = __( "Rampe d'escalier à droite", 'co_product_configurator');
            $this->ins_banister_left =  __( "Rampe d'escalier à gauche", 'co_product_configurator');
            $this->ins_none = __( 'Aucun', 'co_product_configurator');
        }

    I would prefer to use variables because the strings they contain appear several times in the code, and I require a translation to multiple languages.

    Elsewhere in the plugin, I use variables in (almost) the same way, with the key difference that it’s outside of a class. These variables get translated succesfully.

    $msg_choose_height = __( 'Saisissez une hauteur comprise entre 700 mm et 4300 mm', 'co_product_configurator' );
    $msg_choose_step = __( 'Choisir un type de démarche', 'co_product_configurator');
    $msg_choose_width = __( 'Choisissez la largeur des marches pour continuer.', 'co_product_configurator');
    $msg_choose_banister = __( "Veuillez sélectionner une rampe d'escalier", 'co_product_configurator');
    
    // Example of using these variables:
    
                else if(jQuery(this).parent().hasClass('copc_step_4') && jQuery('select[name="copc_select_sizes"]').val() == ''){
                    var msg__ = '';
                    if(jQuery('input[name="copc_max_height"]').val() == ''){
                        msg__ = '<?php echo $msg_choose_height; ?>';
                    }
                    else if(jQuery('input[name="copc_select_type"]:checked').length == 0){
                        msg__ = '<?php echo $msg_choose_step; ?>';
                    }
                    else{
                        msg__ = '<?php echo $msg_choose_width; ?>';
                    }
                    alert(msg__); return;
                }
    

    So there seems to be something tricky about the use of variables in a class.

    Since you load the texts in the Constructor, it could be that the class is initiated far too early – even before the translation methods of WordPress. I generally try to avoid this kind of thing. For example (as you have probably already noticed), you cannot use the __() class directly when initializing private variables.

    At the moment I see 3 possibilities for you:
    a) You build one function per text and always call this function to load the text. Example:

    public function get_text_droite(): string {
     return __( "Rampe d'escalier à droite", 'co_product_configurator'); 
    }

    b) You write the text several times in the file. WordPress has no problem with this, and it doesn’t matter in terms of performance. It can only be annoying for text management if the texts change.

    c) You find out why the class in question is loaded so early.

    Thread Starter amplifiction

    (@amplifiction)

    @threadi Indeed, option B is doable but not ideal. The use of functions is a good idea, though. I went with that:

        function ins_banister_right(): string {
            return __( "Rampe d'escalier à droite", 'co_product_configurator');
        }
        function ins_banister_left(): string {
            return __( "Rampe d'escalier à gauche", 'co_product_configurator');
        }
        function ins_none(): string {
            return __( "Aucun", 'co_product_configurator');
        }
    
            $select_html .= '<div class="copc_banister_field"><label>'. $this->ins_banister_left() .'</label><select name="copc_banister_left">';
            $select_html .= '<option value="">'. $this->ins_none() .'</option>';
    

    (Side question: why do many developers include “public” in the definition of their functions? Isn’t that default?)

    As to why the class loads (too) early: I had previously fiddled with the order in which the relevant parts of the code load, but to no avail. This is what I settled on. (This is in co_product_configurator.php, which is the “main” .php file.)

    add_action('plugins_loaded', 'wan_load_textdomain');
    function wan_load_textdomain() {
    	load_plugin_textdomain( 'co_product_configurator', false, dirname( plugin_basename(__FILE__) ) . '/lang/' );
    }
    
    function run_co_product_configurator() {
    	$plugin = new Co_product_configurator();
    	$plugin->run();
    }
    run_co_product_configurator();

    As you may have guessed, I am a beginner and don’t know where to look beyond that. What counts is that the translation is working, so I am satisfied. Thank you for your help, @threadi !

    The visibility public for functions in a class is essential and should now always be used. See: https://www.php.net/manual/language.oop5.visibility.php

    I would recommend loading load_plugin_textdomain() via the init hook first, not before.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Strings in class not being translated. (All other strings are.)’ is closed to new replies.