Internacionalización en Zend Framework 2

La internacionalización o traducción de sitios Web, es otra de las características importantes que nos facilita un Framework de desarrollo. Veamos como utilizar el componente de internacionalización en Zend Framework 2.

Utilizaremos las sesiones y la base de datos para simular el comportamiento que podría tener la internacionalización en una aplicación real.

En primer lugar, en nuestro module.config.php, tenemos que añadir los siguientes arreglos. En los que indicamos que el traductor esté activo en el modulo, que el idioma por defecto sea el castellano, y que la forma las traducciones las coger de un phparray (hay otras formas como gettext o ini, pero por sencillez prefiero esta).

    'service_manager' => array(
        'abstract_factories' => array(
            'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
            'Zend\Log\LoggerAbstractServiceFactory',
        ),
        'aliases' => array(
            'translator' => 'MvcTranslator',
        ),
    ),
    'translator' => array(
        'locale' => 'es_ES',
        'translation_file_patterns' => array(
            array(
                'type'     => 'phparray',
                'base_dir' => __DIR__ . '/../../../config/language',
                'pattern'  => '%s.php',
            ),
        ),
    ),

Después crearemos un directorio llamado language en el directorio config de la aplicación en general en el que irán los ficheros de traducción.

Dentro de el creamos un fichero php con el nombre es_ES y dentro de el irán traducciones como esta:

<?php
//Del idioma base al Español
return array(
    "Skeleton Application" => "Aplicación esqueleto",
    "Home"                 => "Inicio",
    "All rights reserved." => "Todos los derechos reservados",
    "Welcome to %sZend Framework 2%s"=>"Bienvenido al %sZend Framework 2%s",
    
    "Congratulations! You have successfully installed the %sZF2 Skeleton Application%s. You are currently running Zend Framework version %s. This skeleton can serve as a simple starting point for you to begin building your application on ZF2."
    =>
    "¡Felicitaciones! Haz instalado correctamente el %sla aplicación esqueleto del ZF2%s. Estás corriendo la versión %s del Zend Framework. Este esqueleto te servirá como un punto de inicio sencillo para empezar a construir tu aplicación con el ZF2."
    ,
    "Internationalization in Zend Framework 2"=>"Internacionalización en Zend Framework 2",
    "All rights reserved."=>"Todos los derechos reservados. Victor Robles"
);
?>

En la plantilla voy a crear un formulario para cambiar de idioma, esto debería ser dinámico imprimiendo solo los idiomas que estén disponibles en la base de datos.

<?php echo $this->doctype(); ?>
<html lang="en">
<head>
<!--contenido del head-->
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
	<div class="navbar-header">
		<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
		</button>
		<a class="navbar-brand" href="<?php echo $this->url('home') ?>"><img src="<?php echo $this->basePath('img/zf2-logo.png') ?>" alt="Zend Framework 2"/>&nbsp;<?php echo $this->translate('Skeleton Application') ?></a>
	</div>
	<div class="collapse navbar-collapse">
		<ul class="nav navbar-nav">								<!--En las vistas y plantillas utilizamos este método para traducir texto estatico-->				
			<li class="active"><a href="<?php echo $this->url('home') ?>"><?php echo $this->translate('Home') ?></a></li>
		</ul>
		<!--Creamos un select para cambiar de idioma-->
		<form action="<?php echo $this->basePath("modulo/cambiaridioma")?>" method="post" style="float:right;margin-top:10px;">
		 <select name="idioma" onchange="this.form.submit()">
			<option disabled selected>Idiomas</option>
			<option value="es_ES">Español</option>
			<option value="en_GB">Inglés</option>
			<option value="de_DE">Alemán</option>
		</select>
		</form>
	</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
	<?php echo $this->content; ?>
	<hr>
	<footer>
		<p>&copy; 2005 - <?php echo date('Y') ?> by Zend Technologies Ltd. <?php echo $this->translate('All rights reserved.') ?></p>
	</footer>
</div> <!-- /container -->
<?php echo $this->inlineScript() ?>
</body>
</html>

Para hacer el ejemplo utilizaremos esta base de datos(en un ejemplo real la base de datos se puede hacer mucho mejor, esto es solo un ejemplo rápido):

CREATE TABLE idiomas(
id_idioma int(255) auto_increment not null,
nombre	varchar(25) not null,
localizacion varchar(25) not null,
CONSTRAINT pk_id_idioma PRIMARY KEY(id_idioma)
)ENGINE=InnoDb;

INSERT INTO idiomas VALUES(NULL,"Español","es_ES");
INSERT INTO idiomas VALUES(NULL,"English","en_GB");
INSERT INTO idiomas VALUES(3,"Deutsch","de_DE");

CREATE TABLE articulos(
id_articulo int(255) auto_increment not null,
id_duplicado int(255) not null,
idioma      int(255),
titulo      varchar(100),
cuerpo      varchar(255),
CONSTRAINT pk_id_articulo PRIMARY KEY (id_articulo),
CONSTRAINT fk_idioma FOREIGN KEY (idioma) REFERENCES idiomas(id_idioma)
)ENGINE=InnoDb;

INSERT INTO articulos VALUES(NULL,1,1,"Esto es el titulo en Castellano","Esto es el cuerpo en Castellano");
INSERT INTO articulos VALUES(NULL,1,2,"This is the title in English","This is the body in English");
INSERT INTO articulos VALUES(NULL,3,1,"Contrata a Victor Robles","¡Es un crack!");
INSERT INTO articulos VALUES(NULL,3,2,"Employ Victor Robles","¡Is a crack!");
INSERT INTO articulos VALUES(NULL,5,3,"Esto estaría en alemán","¡Is a crack!");

El controlador

<?php
namespace Modulo\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Session\Container;
//Incluir modelos
use Modulo\Model\Entity\PruebasModel;

class PruebasController extends AbstractActionController{
    private $dbAdapter;
    private $id_idioma;
    private $localizacion;
    
    public function getIdioma(){
        $idioma=new Container("idioma");
        $this->id_idioma=$idioma->id;
        $this->localizacion=$idioma->lang;
        return $idioma;
    }
    
    public function getDbAdapter(){
        $this->dbAdapter=$this->getServiceLocator()->get('Zend\Db\Adapter');
        return $this->dbAdapter;
    }
    
    public function indexAction(){
        $modelo=new PruebasModel($this->getDbAdapter());
     
        if($this->getIdioma()->id!=null || $this->getIdioma()->id!=false){
            $articulos=$modelo->getArticulos($this->getIdioma()->id);
        }else{
            $articulos=$modelo->getArticulos();
        }

         return new ViewModel(
                array(
                    "title"=>"Internationalization in Zend Framework 2",
                    "articulos"=>$articulos
                    )
                );
    }
    
    public function cambiarIdiomaAction(){
	//Con el idioma que nos llega del formulario creamos una sesión
        $idioma_post=$this->params()->fromPost("idioma", "es_ES");
        $idioma=new Container('idioma');
        $idioma->lang=$idioma_post;
        
		//Conseguimos el id del idioma
        $modelo=new PruebasModel($this->getDbAdapter());
        $idioma->id=$modelo->getIdIdioma($idioma->lang);
        
        echo $idioma->lang;
        echo $idioma->id;
        
		//Establecemos el nuevo idioma
        $translator = $this->getServiceLocator()->get('translator');
        $translator->setLocale($idioma->lang)->setFallbackLocale($idioma->lang);
        
        $this->redirect()->toRoute("home");
    }
}
?>

El modelo:

<?php
namespace Modulo\Model\Entity;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
use Zend\Db\ResultSet\ResultSet;


class PruebasModel extends TableGateway{
    private $dbAdapter;
    
    public function __construct(Adapter $adapter = null, $databaseSchema = null, ResultSet $selectResultPrototype = null){
        $this->dbAdapter=$adapter;
        return parent::__construct('articulos', $this->dbAdapter, $databaseSchema,$selectResultPrototype);
    }
    
    public function getIdIdioma($localizacion){
        $select=$this->dbAdapter->query("SELECT id_idioma FROM idiomas WHERE localizacion='$localizacion'",  Adapter::QUERY_MODE_EXECUTE);
        $resultado=$select->toArray();

        return $resultado[0]["id_idioma"];
    }
    
    public function getArticulos($id_idioma=1){
        $select=$this->select(array("idioma"=>$id_idioma)); 
        return $select->toArray();
    }
    
}

?>

La vista:

<h1><?php echo $this->translate($this->title); ?></h1>
<?php
var_dump($this->articulos);
?>

La parte más importante para mantener el idioma en sesión, es la siguiente. Dentro del fichero Module.php

<?php
namespace Modulo;

use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Session\Container;

    class Module
    {
        public function getConfig()
        {
            return include __DIR__ . '/config/module.config.php';
        }
							//Se ejecuta al cargar el módulo
         public function onBootstrap(MvcEvent $e){
             
            $eventManager        = $e->getApplication()->getEventManager();
            $moduleRouteListener = new ModuleRouteListener();
            $moduleRouteListener->attach($eventManager);
	
			//Conseguimos el servicio traductor
            $translator = $e->getApplication()->getServiceManager()->get('translator');
			
			//Cargamos la sesión idioma
            $idioma=new Container('idioma');

			//Asignamos el idioma en sesión
			$translator->setLocale($idioma->lang)->setFallbackLocale($idioma->lang);
        }
        
        public function getAutoloaderConfig()
        {
            return array(
                'Zend\Loader\StandardAutoloader' => array(
                    'namespaces' => array(
                        __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                    ),
                ),
            );
        }

  
}

El resultado:
internacionalización en zend framework 2

Si cambiamos el idioma al inglés.
internacionalización en zend framework 2.2

Más información:
Zend i18n Translating Documentación oficial
Configuración de un sitio multilingüe en ZF2

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post