Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Internacionalización con CakePHP

Internacionalización con CakePHP

CakeFest Argentina 2009

Mariano Iglesias

December 09, 2009
Tweet

More Decks by Mariano Iglesias

Other Decks in Programming

Transcript

  1. ¿Es necesaria? Ampliar la audiencia CakePHP nos facilita las cosas

    Los traductores no tienen porqué conocer nuestra aplicación Sirve para los archivos “fijos“, y para la base de datos Pensar en el futuro, con poco esfuerzo
  2. Métodos para el suicidio Enamorado de los switch Enamorado de

    las tablas switch ($language) { case 'en': echo 'My message'; break; case 'es': echo 'Mi mensaje'; break; } $terms = $this->Term->find('all'); $terms = Set::combine($terms, '/Term/code', '/Term/text'); $this->set(compact('terms')); // ... echo $term['my_message'];
  3. La propuesta de CakePHP Métodos __() -> __('My message') __n()

    -> __n('Un elemento', 'Varios elementos', $count) Configure::write('Config.language', 'es') Translate behavior i18n extractor
  4. La propuesta de CakePHP Manipulación Multibyte 1 letra != 1

    byte 8 bits -> 256 wchar_t (L'w') mb_strlen(), mb_strpos(), mb_substr(), ... Multibyte::checkMultibyte() -> ord($char) > 128 Multibyte::utf8($string) -> array (valores mayores a 128 permitidos) Multibyte::ascii($array) -> string
  5. La propuesta de CakePHP <p><?php __('Welcome to my page'); ?></p>

    <?php echo $html->link(__('Home', true), '/'); ?> <p><?php echo sprintf(__('Your name is %s', true), $name); ?></p> $ cake i18n extract -output app/locale locale/ default.pot POEDIT locale/eng/LC_MESSAGES default.po default.mo
  6. Manos a la obra Veamos un ejemplo Modificamos una vista

    Corremos el extractor Verificamos el archivo template creado Corremos POEDIT Verificamos los archivos de traducción Algunos consejos para el uso de POEDIT
  7. Translate Behavior Ofrece internacionalización para nuestras tablas Centraliza traducciones en

    una misma tabla Se encarga de filtrar los datos traducidos según el idioma actual automaticamente
  8. Translate Behavior class Post extends AppModel { var $name =

    'Post'; var $actsAs = array('Translate' => array( 'title', 'body' )); var $belongsTo = array('User'); } CREATE TABLE `posts`( `id` INT NOT NULL AUTO_INCREMENT, `user_id` INT NOT NULL, `title` VARCHAR(255) NOT NULL, `body` TEXT, `created` DATETIME, `modified` DATETIME, PRIMARY KEY(`id`) ); CREATE TABLE `posts`( `id` INT NOT NULL AUTO_INCREMENT, `user_id` INT NOT NULL, `title` VARCHAR(255) NOT NULL, `body` TEXT, `created` DATETIME, `modified` DATETIME, PRIMARY KEY(`id`) );
  9. Translate Behavior mysql> desc i18n; +-------------+--------------+------+-----+---------+----------------+ | Field | Type

    | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(10) | NO | PRI | NULL | auto_increment | | locale | varchar(6) | NO | MUL | NULL | | | model | varchar(255) | NO | MUL | NULL | | | foreign_key | int(10) | NO | MUL | NULL | | | field | varchar(255) | NO | MUL | NULL | | | content | text | YES | | NULL | | +-------------+--------------+------+-----+---------+----------------+ mysql> select * from i18n; +----+--------+-------+-------------+-------+------------------------------------------+ | id | locale | model | foreign_key | field | content | +----+--------+-------+-------------+-------+------------------------------------------+ | 1 | eng | Post | 1 | title | Pre-registration opened | | 2 | spa | Post | 1 | title | Pre-inscripciones abiertas | | 3 | eng | Post | 1 | body | Body for Pre-registration opened | | 4 | spa | Post | 1 | body | Cuerpo para Pre-inscripciones abiertas | +----+--------+-------+-------------+-------+------------------------------------------+ 4 rows in set (0.00 sec)
  10. Translate Behavior $posts = $this->Post->find('all', array( 'recursive' => -1, 'fields'

    => array('title', 'body') )); $posts = Set::combine($posts, '/Post/title', '/Post/body'); SELECT `I18n__title`.`content`, `I18n__body`.`content` FROM `posts` AS `Post` LEFT JOIN `i18n` AS `I18n__title` ON (`Post`.`id` = `I18n__title`.`foreign_key` AND `I18n__title`.`model` = 'Post' AND `I18n__title`.`field` = 'title') LEFT JOIN `i18n` AS `I18n__body` ON (`Post`.`id` = `I18n__body`.`foreign_key` AND `I18n__body`.`model` = 'Post' AND `I18n__body`.`field` = 'body') WHERE `I18n__title`.`locale` = 'eng' AND `I18n__body`.`locale` = 'eng' array( [Pre-registration opened] => Body for Pre-registration opened [Site Updates] => Body for Site Updates )
  11. Translate Behavior $this->Post->create(); $this->Post->save(array('Post' => array( 'user_id' => 1, 'title'

    => array('eng' => 'ENG 1', 'spa' => 'spa1'), 'body' => array('eng' => 'Body for ENG 1', 'spa' => 'Cuerpo para spa1') ))); $this->Post->create(); $this->Post->save(array('Post' => array( 'user_id' => 1, 'title' => array('eng' => 'ENG 1'), 'body' => array('eng' => 'Body for ENG 1') ))); $this->Post->save(array('Post' => array( 'id' => $this->Post->id, 'title' => array('spa' => 'spa1'), 'body' => array('spa' => 'Cuerpo para spa1') )));
  12. Modificando el idioma class AppController extends Controller { var $components

    = array('Cookie'); function beforeFilter() { $lang = null; if (!empty($this->params['url']['lang'])) { $lang = $this->params['url']['lang']; $this->Cookie->write('CakeFestLanguage', $lang, false, '+365 days'); } else { $lang = $this->Cookie->read('CakeFestLanguage'); } if (empty($lang)) { $lang = Configure::read('CakeFest.defaultLanguage'); } Configure::write('Config.language', $lang); } function beforeRender() { $this->set('currentLanguage', Configure::read('Config.language')); } }
  13. Modificando el idioma class AppHelper extends Helper { function url($url

    = null, $full = false) { if (!empty($url) && !is_array($url) && $url[0] == '/') { $urlRoute = Router::parse($url); if (!empty($urlRoute['controller'])) { $url = array_merge(array_intersect_key($urlRoute, array_flip(array('admin', 'controller', 'action', 'plugin'))), $urlRoute['pass'], $urlRoute['named']); } } if (is_array($url)) { if (!isset($url['lang']) && Configure::read('Config.language') != Configure::read('CakeFest.defaultLanguage')) { $url['lang'] = Configure::read('Config.language'); } } return parent::url($url, $full); } }
  14. Cacheando elementos $this->element('news', array('cache' => array( 'time' => '+1 day',

    'key' => $currentLanguage ))); tmp/cache/views element_eng_news element_spa_news