Solución al problema con UTF-8 en WordPress 2.2

Autor: Armonth | El lunes 28 de mayo del 2007 @ 21:02.

Un conocido acaba de actualizar a WordPress 2.2 y me ha comentado que tiene problemas al mostrar la codificación UTF-8 y es algo ya comentado antes por los comentaristas de SigT.

WordPress usa UTF-8 por defecto para el contenido y mostrar las páginas, pero la codificación de la base de datos siguen estando en latin1. En el fichero wp-config.php hay dos entradas al respecto:

define('DB_CHARSET', 'utf8');   
define('DB_COLLATE', '');

En principio, si actualizáis desde una versión anterior, lo mejor sería quitar el utf8 de la primera quedando:

define('DB_CHARSET', '',);   
define('DB_COLLATE','');

Al menos a mí amigo le ha funcionado. Quizá en algunos casos haya que comentar la segunda línea, dejarlas las dos con el utf8, comentar las dos o directamente ninguna (si no os da ningún problema).

Pero esto (toca decirlo) es un apaño temporal y más tarde o más temprano tendremos que tener un WordPress 100% UTF-8 ya ahora tenemos ficheros y "contenido" de la base de datos pero falta la base de datos. Para ello podemos leer un borrador en el Codex WordPress llamado "Converting Database Character Sets" enfocado 100% a WordPress 2.2.

Voy a traducir/adaptar rápidamente las partes importantes del borrador. Como siempre: haced copia de seguridad antes de tocar nada.

Cómo convertir la codificación de la base de datos

Hasta WordPress 2.1.3 (incluida) las bases de datos de WordPress eran creadas con la codificación latin1 y de orden alfabético (N.dT: collation) latin1_swedish_ci.

Con la versión 2.2 WordPress permite definir ambas opciones (codificación y orden alfabético) de la base de datos en el fichero wp-config.php. Definir los valores DB_CHARSET y DB_COLLATE en el fichero wp-config.php provoca que WordPress cree la base de datos con los valores adecuados. Pero esto sólo puede hacerse para nuevas instalaciones y no para las viejas o actualizadas desde versiones anteriores. Para "reconvertir" la base de datos vamos a asumir que la base de datos está en latin1 y se necesita convertir a utf-8.

El problema

Cambiar la codificación requiere el uso del comando de MySQL ALTER TABLE. Cuando se cambia la codificación todos los campos TEXT y similares son convertidos a UTF-8. Sin embargo esta conversión rompe los TEXT existentes ya que presupone y espera que el contenido alojado en estos campos TEXT está en latin1, pero WordPress aloja caracteres unicode en la base de datos latin1 y, como resultado, los datos se llenan de basura después de la conversión.

La solución

La solución es ALTER_(AR)_ todos los campos TEXT y relacionados a campos BLOB, luego cambiar la codificación y devolver los campos BLOB a TEXT.

Pasos de ejemplo:

  1. Avisa con tiempo y pon el blog fuera de servicio.
  2. Haz una copia de seguridad.
  3. ALTER TABLE wp_users MODIFY display_name BLOB;
  4. Repetir paso 3 para el resto de tablas/columnas.
  5. ALTER DATABASE wordpress charset=utf8;
  6. ALTER TABLE wp_users charset=utf8;
  7. Repetir paso 6 para el resto de tablas.
  8. ALTER TABLE wp_users MODIFY display_name TEXT CHARACTER SET utf8;
  9. Repetir paso 8 para el resto de tablas/columnas.
  10. Añadir el DB_CHARSET y DB_COLLATE correspondientes al wp-config.php.
  11. Pon en marcha de nuevo el blog.

Así pues, en los pasos 3 y 4 hay que cambiar CHAR, VARCHAR, TEXT, ENUM y SET cambiándolos el campo a BLOG, en el paso 5 hay que cambiar la base de datos a UTF-8, en los pasos 6 y 7 cambiar todas las tablas a UTF-8 y, finalmente, en el paso 8 y 9 devolver los campos BLOB a su estado anterior (ya fuese CHAR, VARCHAR, TEXT, ENUM y SET) con el campo UTF-8 configurado.

La clave en la conversión es que los campos BLOB, a diferencia de CHAR, VARCHAR, TEXT, ENUM y SET, no son convertidos en basura cuando la base de datos y sus tablas son cambiadas a UTF-8.

Finalizando

Recomendación personal: si sabes lo que haces (y tienes tiempo), sigue los pasos del "borrador", si no haz el cambio que he dicho al principio y espera que una de las nuevas versiones actualice automáticamente la base de datos, salga un script que lo haga o similar.

Comentarios