0

My application has Contact model in app/models/contact.php. I have used _construct to add some list in array which its values should be translated using _('some text',true) as follows:

class Contact extends AppModel{
   var $sex;
   function __construct($id = false, $table = null, $ds = null) {
      parent::__construct($id, $table, $ds);      
      $this->sex =array(
                 'U' => __('Choose Sex', true),
                 'M' => __('Male', true),
                 'F' => __('Female', true)    
                     );
   } 
}

The above mentioned $sex variable is used to populate HTML select as follows:

// From contacts controller index function

function index(){
   $this->set('sex', $this->Contact->sex);
.....
}

// From index view index.ctp
<?php echo $form->input('sex', array('type' => 'select', 'options' => $sex)); ?>

After running cake i18n, translating strings using Poedit version 1.5.5 and deleting files in app/tmp/cache, I have found that strings in the list still as it is without translation.

How could I solve this issue with translation strings in the model?

General Notes:

  • CakePHP version 1.2.10
  • XAMPP AMP package on Windows7 64 bit
thaJeztah
  • 27,738
  • 9
  • 73
  • 92
SaidbakR
  • 13,303
  • 20
  • 101
  • 195
  • For such enums I would recommend using class constants - and an approach like http://www.dereuromark.de/2010/06/24/static-enums-or-semihardcoded-attributes/ You can also bake your files with this enum like support then. But your code itself looks ok to me. if the object is constructed, it should translate those strings. PS: I recommend upgrading to 2.x by the way. – mark May 07 '13 at 14:21
  • @mark Unfortunately, the upgrade is not possible option at this time. – SaidbakR May 07 '13 at 15:58

1 Answers1

4

CakePHP 1.2 doesn't use 'lazy loading', the Model may therefore be loaded/constructed before you set the language/locale (for example, inside your AppController::beforeFilter()).

Things to consider

It may be worth considering;

  • If these strings should already be translated inside the constructor (you won't be using them all the time)
  • If these strings should be translated inside the model at all

Especially this last point; IMO translating strings is part of the 'presentation layer'; i.e. belongs inside a View (or a Helper).

Translate 'on demand'; at the last possible moment

This also allows you to switch the language, without the Model having already translated the strings;

In your model:

class Contact extends AppModel
{
    protected $_sexOptions = array(
        'U' => 'Choose Sex',
        'M' => 'Male',
        'F' => 'Female',
    );

    public function getSexOptions()
    {
        $out = array();
        foreach ($this->_sexOptions as $k => $v) {
            $out[$k] = __($v, true);
        }
        return $out;    
    }
}

Inside your controller;

$this->set('sex', $this->Contact->getSexOptions());

Translate inside the 'presentation' layer; i.e. your view:

Create a simple helper to make this re-usable;

app/views/helpers/options.php

class OptionsHelper extends AppHelper
{
    /**
     * translates options
     */
    public function translate($options)
    {
        $out = array();
        foreach (options as $k => $v) {
            $out[$k] = __($v, true);
        }
        return $out;
    }
}

Add this helper to your controller;

public $helpers = array(
    // ... other helpers
    'options',
);

Inside your view;

echo $this->Form->input('sex', array(
    'type'    => 'radio',
    'options' => $this->Options->translate($sex)
));
thaJeztah
  • 27,738
  • 9
  • 73
  • 92
  • Thank you very much, I used the solution that depends on model, and I canceled the work from constructor and the get methods work so fine. – SaidbakR May 07 '13 at 15:57