Automatizar tareas de traducción de WordPress con Grunt

Grunt es una de esas herramientas que al principio parece un poco intimidante, pero al empezar a utilizarla se hace cada vez más necesaria y adictiva.

Por si aún no lo conoces, Grunt es un programita hecho en javascript sobre node.js que permite automatizar una gran cantidad de tareas, y sirve especialmente para poner a punto la versión en producción de un sitio; por ejemplo: optimizar imágenes, compilar estilos desde LESS a CSS (o Coffeescript a javascript), ejecutar pruebas unitarias, minificar y concatenar estilos y scripts, etc.

Hace algunos posts escribí sobre algunas herramientas de localización para WordPress que ayudan a generar el catálogo de traducciones POT necesario para hacer un tema o plugin traducible a otros idiomas, y que es un excelente ejemplo de tareas en las que Grunt se luce.

Afortunadamente bradyvercher adaptó esas herramientas para trabajar como módulos de Grunt, por lo que podemos utilizar las mismas herramientas de localización “oficiales” de WordPress de forma automática con Grunt.

Definición del proyecto

El primer paso, si aun no tienes node.js es instalarlo en tu sistema — revisa las instrucciones para tu sistema operativo o pregúntale a tu buscador cómo hacerlo. Al instalar node, tendrás disponible en la línea de comandos el gestor de paquetes npm, que vas a necesitar para crear una definición de paquete de nuestro proyecto y así guardar la configuración de los módulos que vamos a usar con Grunt.

¿Todo instalado? ¿Listo? Ok, sigamos.

Lo siguiente es crear la definición de paquete, que podemos hacer de forma automatizada ejecutando npm init en la carpeta del proyecto. Se mostrarán varias preguntas y como resultado obtendrás un archivo package.json parecido a esto:

{
	"name": "tuproyecto.com",
	"version": "1.0.0",
	"description": "Sitio web del proyecto multilenguaje cachilupi",
	"main": "index.php",
	"repository": {
		"type": "git",
		"url": "https://github.com/felipelavinz/mi-repo.git"
	},
	"keywords": [
		"wordpress",
		"l10n"
	],
	"author": "Felipe Lavín Z. <felipe@yukei.net>",	
	"license": "propietary",
	"bugs": { "url": "https://github.com/felipelavinz/mi-repo/issues" },
	"homepage": "https://github.com/felipelavinz/mi-repo",	
	"devDependencies": {
		"grunt": "^0.4.5",
		"grunt-cli": "^0.1.13",
		"grunt-contrib-watch": "^0.6.1",
		"grunt-wp-i18n": "^0.4.5"	
	}
}

Instalar dependencias

Lo que hace este archivo es definir cuáles son los módulos y versiones de paquetes para node que tu proyecto va a utilizar, por ejemplo lo que puedes ver en la propiedad devDependencies, que si acabas de generar el archivo, probablemente no va a estar o bien está vacía.

Para definir los módulos que vamos a utilizar con npm, ejecuta el siguiente comando:

npm install --save-dev grunt grunt-cli grunt-contrib-watch grunt-wp-i18n

Este comando le indica al gestor de paquetes npm que instale los módulos señalados y que los guarde como dependencias del proyecto (la parte --save-dev). Los módulos que instalamos son:

  • grunt y grunt-cli, para ejecutar las tareas que vamos a automatizar con Grunt
  • grunt-wp-18n que es el plugin de Grunt que contiene las herramientas de traducción de WordPress. Ojo, que para utilizarlo vas a necesitar poder ejecutar scripts de php por línea de comandos (comprúebalo con php -a; si te aparece una consola interactiva estás ok).
  • grunt-contrib-watch que es un plugin para Grunt que permite vigilar cambios en archivos y carpetas. Es algo así como inotify que utilizaba para compilar archivos LESS automáticamente en Linux pero para Grunt

Obviamente, también podrías instalar otros plugins para realizar otras tareas.

Al instalar estos módulos y plugins con la opción --save-dev, el archivo package.json guardará la información de todo lo que le pedimos instalar a npm. El código de todo lo que instalamos quedará en la carpeta node_modules.

Si usas un sistema de control de versiones, es buena idea versionar package.json y excluir node_modules, ya que al clonar el repositorio puedes ejecutar npm install (sin más) y npm bajará e instalará todos los módulos que están indicados en package.json. Si no usas control de versiones… deberías.

Definición de la tarea de traducción

Finalmente, para poder utilizar Grunt necesitamos crear un archivo Gruntfile.js donde vamos a definir las tareas que se van a automatizar. En la documentación de Grunt hay información a fondo, pero puedes partir con lo siguiente (obviamente, ajustando la información de rutas donde corresponda):

module.exports = function(grunt){
	grunt.initConfig({
		makepot: {
			target: {
				options: {
					// la ruta al tema
					cwd: 'htdocs/wp-content/themes/mi-super-tema',
					// la carpeta dentro del tema donde se guarda el catálogo de traducciones
					domainPath: '/languages',
					exclude: [],
					mainFile: 'htdocs/wp-content/themes/mi-super-tema/style.css',
					// el tipo de proyecto; sería wp-plugin si es un plugin 
					type: 'wp-theme',
					// debe corresponder al dominio de traducción del tema
					potFilename: 'mi-super-tema.pot'
				}
			}
		},
		watch: {
			theme_translations: {
				// vigilar cambios en todos los archivos php del tema
				files: ['htdocs/wp-content/themes/mi-super-tema/**/*.php'],
				tasks: ['makepot'],
				options: {
					nospawn: true
				}
			}
		}
	});
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-wp-i18n');
	grunt.registerTask('default', ['watch']);
};

Con esto, vamos a tener disponibles las siguientes tareas:

  • grunt makepot que genera el catálogo de traducciones para el tema
  • grunt watch que va a vigilando cambios en los archivos PHP del tema y actualiza el catálogo de traducciones cada vez que guardas un cambio
  • Además, también puedes utilizar simplemente grunt para ejecutar la tarea anterior

Actualizar las traducciones

Con estas tareas de Grunt, el catálogo de traducciones (es decir, el archivo POT) siempre estará actualizado; para traducir los nuevos textos puedes utilizar poedit que es el cliente gráfico más popular para ello.

Para incorporar los nuevos textos, debes seguir los siguientes pasos:

  1. Abrir el archivo de traducciones, por ejemplo, htdocs/wp-content/themes/mi-super-tema/languages/en_US.po
  2. Importar los nuevos textos traducibles: ingreas al menú Catálogo y luego la opción Update from POT File (“actualizar desde archivo POT” o algo así).
  3. ¡Listo! Ahora sólo debes traducir los nuevos textos y guardar el archivo.