Cambiar el saludo de WordPress sin modificar la traducción

Personalizar WordPress es muy sencillo, mediante funciones, plugins y trucos puedes ofrecer una experiencia de WordPress para tus clientes, incluso para ti mismo, totalmente a tu gusto.

Con la traducción, además, puedes personalizar los mensajes de la administración, o del tema si está traducido.

Pero si solo quieres cambiar el mensaje de saludo de WordPress, el “Hola, Usuario” (el famoso “Howdy”), puedes hacerlo sin tener que modificar la traducción.

Solo tienes que añadir el siguiente código a tu plugin de funciones o al fichero functions.php de tu tema activo:

//Saludo personalizado en admin
function saludo_personal( $wp_admin_bar ) {
    $my_account=$wp_admin_bar->get_node('my-account');
    $newtitle = str_replace( 'Hola,', 'Que tengas buen día,', $my_account->title );
    $wp_admin_bar->add_node( array(
        'id' => 'my-account',
        'title' => $newtitle,
    ) );
}
add_filter( 'admin_bar_menu', 'saludo_personal',25 );

Nota: En este código sustituimos el mensaje de la traducción, si usas otra distinta a la oficial deberás cambiar el primer parámetro de str_replace de “Hola” al que veas en tu escritorio de WordPress. El segundo parámetro es tu mensaje personalizado.

Numeración autoincremental en los títulos de las entradas

Vale que este truco es muy especialito, quizás un poco exclusivo para usos igual muy concretos, pero seguro que se te ocurre en qué situaciones puede ser útil, a mi se me ocurren unas cuantas.

Por ejemplo, en publicaciones académicas donde cada entrada deba seguir una numeración para tener identificado el número de publicaciones, o en un blog de proyecto, y muchas cosas más.

El caso es que si quieres que en tus títulos aparezca un número, que se incremente solo en cada nuevo artículo puedes hacerlo, solo te llevará un par de pasos:

1. Crea la función

Lo primero es crear la función y guardarla en el archivo functions.php o tu plugin de funciones, que sería así:

//Numeración autoincremental en los títulos
function updateNumbers() {
    global $wpdb;
    $querystr = "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' ";
    $pageposts = $wpdb->get_results($querystr, OBJECT);
    $counts = 0 ;
    if ($pageposts):
    foreach ($pageposts as $post):
    setup_postdata($post);
    $counts++;
    add_post_meta($post->ID, 'incr_number', $counts, true);
    update_post_meta($post->ID, 'incr_number', $counts);
    endforeach;
    endif;
}

add_action ( 'publish_post', 'updateNumbers' );
add_action ( 'deleted_post', 'updateNumbers' );
add_action ( 'edit_post', 'updateNumbers' );

Guardas los cambios y vamos al segundo paso …

2. Modifica el loop

Ahora lo que toca es modificar el loop de tu index.php, single.php, archive.php y el resto donde haya loop en que aparezcan títulos (por ejemplo taxonomy.php u otros) para que, al recuperar el título de la entrada añada el número generado.

De este modo, donde encontremos este código … 

<?php the_title(); ?>

Lo sustituiremos por este otro:

<?php echo get_post_meta($post->ID,'incr_number',true); ?>

Guardas y ya está :)

Limitar búsquedas solo a los títulos

En ocasiones el buscador interno de WordPress se hace demasiado poco útil, y no es que lo haga mal, pero no es todo lo específico que podría ser, en según que momentos.

Una posible necesidad, si te ha surgido, sería que el buscador interno de WordPress solo realice búsquedas en los títulos, que es de lo que normalmente se acuerda el usuario tipo.

Si es tu caso puedes modificar el comportamiento por defecto del buscador interno de WordPress. Solo hay que añadir este código a tu plugin de funciones o al archivo functions.php de tu tema activo:

//Buscar solo en títulos
function __search_by_title_only( $search, &$wp_query )
  {
      if ( empty($search) )
      return $search; // deja de procesar si no hay término alguno en la query
      $q =& $wp_query->query_vars;

      // wp-includes/query.php line 2180 (en version 3.3)
      $n = !empty($q['exact']) ? '' : '%';
      $searchand = '';
      foreach( (array) $q['search_terms'] as $term ) {
      $term = esc_sql( like_escape( $term ) );
      $search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
      $searchand = ' AND ';
  }
  $term = esc_sql( like_escape( $q['s'] ) );
  if ( empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] )
  $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
  if ( !empty($search) ) {
      $search = " AND ({$search}) ";
      if ( !is_user_logged_in() )
          $search .= " AND ($wpdb->posts.post_password = '') ";
      }
      return $search;
  }
add_filter( 'posts_search', '__search_by_title_only', 10, 2 );

Guardas los cambios y ya lo tienes. Ahora solo hará las búsquedas en los títulos de tus entradas.

Preparar tema WordPress para traducción

Hoy en día no tiene sentido, con el grado de avance de WordPress, publicar un tema nuevo sin que venga preparado para traducciones, para que los usuarios puedan fácilmente añadir la localización para su idioma. Si queremos que nuestro tema sea popular, que llegue a todas partes y sea fácil de utilizar por usuarios de WordPress de cualquier país, no tienes excusa para facilitar su internacionalización.

Además, es muy sencillo preparar un tema WordPress para traducción, internacionalización, localización, como quieras llamarlo, así que vamos a verlo ya mismo …

Los 5 pasos para preparar un tema WordPress para traducción que vamos a seguir son los siguientes:

  1. Cargar un dominio de texto
  2. Procesar los mensajes de texto con funciones WordPress
  3. Extraer los mensajes con Poedit
  4. Ofrecer una traducción para cada mensaje y crear un archivo de idioma para una traducción concreta
  5. Decir a WordPress que active la localización y cargue el archivo de idioma

Vamos a ello …

1. Cargar un dominio de texto

Lo primero que hay que hacer es cargar un dominio de texto añadiendo la siguiente línea al archivo functions.php de tu tema:

load_theme_textdomain('mitema', get_template_directory() . '/languages');

El primer argumento debe ser un identificador único (una buena práctica es usar el nombre de tu tema); lo que define el dominio del tema, ya que el texto para la traducción no estará en los archivos de instalación de WordPress. El segundo argumento define la carpeta de los archivos de idioma. Para cargar estos archivos la función debe estar unida a la acción after_setup_theme action:

add_action('after_setup_theme', 'my_theme_setup');
function my_theme_setup(){
    load_theme_textdomain('mitema', get_template_directory() . '/languages');
}

2. Procesar los mensajes de texto con funciones WordPress

Después de editar el fichero functions.php, el siguiente paso es revisar el código de los archivos del tema, encontrar los mensajes que tienen que traducirse y procesarlos con la función WordPress adecuada. Los dos más importantes, y que se usan más a menudo, son _e($text_message) y __($text_message).

La primera función busca la traducción del $text_message y lo imprime. Si la traducción no existe entonces imprime $text_message. Esta función se usa para los mensajes de texto que no sean funciones PHP, ya que imprime el resultado. Por ejemplo, eliges la siguiente línea:

echo ‘Hello user’;

Y hay que transformarla a:

_e(‘Hello user’,’mitema’);

La segunda función busca la traducción del $text_message y lo devuelve. Si no existe traducción entonces devuelve el $text_message. Esto se usa para el texto que esté en funciones PHP. Por ejemplo:

the_content( ‘Read more’ );

Hay que transformar la llamada de la función a:

the_content( __(‘Read more’,’mitema’) );

A veces un mensaje de texto incluye datos dinámicos, como números de una variable PHP. En estos casos usaremos la función PHP printf para producir la cadena del mensaje final:

$results_found = 12;
$message = sprintf( __(‘%s results found’ , ‘mitema’) , $results_found );

Singular y plural

WordPress ofrece una función para la traducción singular y plural del mismo mensaje de texto:

_n( $single, $plural, $number, $domain )

El primer argumento es el texto que se usará para el singular, y el segundo es el texto que se usará para el plural. El tercer argumento es el número con el que comparar para decidir cual usar.

Aunque la función _n() está incluida en WordPress no se recomienda usarla ya que el software de traducción solo usa el primer parámetro de una función, así que no se procesarían estos dos mensajes de texto. En su lugar podemos usar la declaración PHP if:

if($results_found == 1)
$message = __(‘1 result found’ , ‘my-text-domain’);
else
$message = sprintf( __(‘%s results found’ , ‘my-text-domain’) , $results_found );

3. Extraer los mensajes con Poedit

Una vez hemos procesado cada mensaje de texto con las funciones antes mencionadas nuestro tema está listo para traducción. A estos efectos hay tres tipos de ficheros de idioma:

  1. El archivo .POT contiene una lista de todos los mensajes traducibles de tu tema
  2. El archivo .po se crea cuando traducimos un fichero POT a un idioma concreto
  3. El archivo .mo es un archivo binario que lo crea automáticamente Poedit. Este es el que WordPress lee para traducir temas y plugins

Creamos el POT
Lo primero es crear el fichero POT, que contiene todos los mensajes del código del tema y que será el archivo que el traductor use para traducir los mensajes de otro fichero de idioma. Aunque hay varias aplicaciones para editar y crear ficheros de idioma te recomiendo Poedit, que es multiplataforma y es el que yo uso.

  1. Abre Poedit y crea un nuevo catálogo
  2. Completa la información del catálogo en la pestaña “Información del proyecto”
  3. En la pestaña “Rutas” identifica la carpeta donde Poedit buscará los archivos con el código que contiene los mensajes de texto traducibles. Estas carpetas son relativas a la carpeta de nuestro archivo de idioma así que guardaremos el archivo en una carpeta de la carpeta de tu tema, por lo que añadiremos ..:
  4. En la pestaña “Palabras clave” definiremos las funciones WordPress utilizadas para traducir mensajes (recuerda que Poedit no es solo para WordPress). En nuestro tema las dos palabras clave utilizadas han sido __ y _e.
  5. Una vez que hagas clic en “Aceptar” Poedit busca en las carpetas que le hemos dicho en la pestaña “Rutas” y te listará los mensajes de texto encontrados en los archivos del tema.
  6. Guarda el archivo POT en una carpeta llamada languores dentro de la carpeta de tu tema.

Este archivo POT recién creado en realidad no lo necesita WordPress, es simplemente la plantilla que contiene las cadenas de mensajes traducibles, que puedes facilitar al traductor para que lo traduzca y te devuelva un fichero .po.

4. Ofrecer una traducción para cada mensaje y crear un archivo de idioma para una traducción concreta

Como ya tenemos el POT ahora solo hay que empezar a traducir cadenas de texto con Poedit, la aplicación, la primera vez que guardes cambios crea el solito los ficheros .po y .mo.

  1. Empieza a elegir cadenas de texto de la lista y traduce una a una en los campos inferiores
  2. Sigue traduciendo hasta que estén todas las cadenas de texto traducidas a tu idioma
  3. Guarda y verás los ficheros .po y .mo generados automáticamente en la carpeta languages

5. Decir a WordPress que active la localización y cargue el archivo de idioma

Una vez hayamos creado los ficheros .po y .mo ya podemos decir a WordPress que active la localización y cargue los archivos del idioma. Edita el archivo wp-config.php, que encontrarás en la carpeta raíz de la instalación de WordPress.

Lo que hay que hacer es modificar la variable WPLANG al idioma que queremos usar. Por ejemplo:

define('WPLANG', '');

Pasaría a quedar así si vamos a usar la localización (traducción) al español de España:

define('WPLANG', 'es_ES');

Si WordPress encuentra un archivo de traducción al “español de España” como hemos definido en la configuración del catálogo, en la carpeta que configuramos en el primer paso de este tutorial, entonces mostrará los mensajes traducidos a este idioma en el tema y los visitantes lo verán en español de España. Si no lo encontrara entonces mostraría los mensajes por defecto.

EXTRA: Preparar para traducción plugins

Aunque no iba de plugins esta guía no está de más explicar como se prepara para traducción un plugin, máxime cuando hay pasos que se repiten, así que vamos a ver lo que cambia a la hora de internacionalizar plugins.

Al igual que hacemos con el tema, lo primero es decirle a WordPress donde encontrará los archivos de idioma, añadiendo la siguiente función, en este caso en el archivo principal del plugin:

load_plugin_textdomain('miplugin', false, basename( dirname( __FILE__ ) ) . '/languages' );

El primer parámetro define el dominio del texto, a ser posible usando el nombre del plugin, ya que debe ser único. El segundo parámetro define la ruta de la carpeta donde estará el fichero .mo. Como corresponde a una función anticuada, que fue válida hasta WordPress 2.7, especificaremos como valor false. El tercer parámetro es la carpeta donde están los archivos de idioma, en este caso asumimos que hay una carpeta llamada language dentro de la carpeta del plugin.

También, para cargar los archivos de idioma tenemos que añadir un ‘hook‘ y enlazar esta función en la acción init de WordPress:

function traduccion_miplugin()
{
load_plugin_textdomain('miplugin', false, basename( dirname( __FILE__ ) ) . '/languages' );
}
add_action('init', 'traduccion_miplugin');

Para terminar tendremos que procesar los mensajes de texto igual que hemos hecho con el tema, siguiendo los pasos 2 al 5, usando las funciones que a estas alturas ya conoces: _e($text_message) y __($text_message). Una vez procesado todo y creados los ficheros de traducción nuestro plugin estará listo para traducción.

Más información:

Syntax mode de WordPress para Panic CODA

Si no conoces la aplicación Panic CODA seguramente te estás perdiendo la que quizás sea el mejor software que existe para un programador web.

De hecho, hay desarrolladores web que se han pasado a Mac “solamente” para usar CODA. Y no es una locura, en realidad hay muchas razones para pasarse a Mac pero usar CODA es una de ellas, y poderosa. Pero bueno, que no se trata de hacer proselitismo de Mac o CODA.

Lo que quiero compartir contigo hoy es un fichero de descarga que permite usar la sintaxis de WordPress en CODA, para que identifique los códigos de tus temas y plugins WordPress, sus funciones en concreto, y te permite cosas como el autocompletado de sintaxis y esas cosas maravillosas que hace CODA.

Para tener esta funcionalidad solo tienes que hacer esto:

  1. Descargar este archivo:
    zip Modo WordPress para Panic CODA v.1.0 (230.65 kB )
  2. Descomprimir el zip
  3. Copiar la carpeta descomprimida llamada PHP-HTML-WP.mode en la carpeta ~/Library/Application Support/Coda/Modes/
  4. Abre un archivo PHP o de WordPress y carga el modo de sintaxis en CODA desde el menú “Text -> Syntax Mode -> PHP-HTML-WP
  5. Opcional: Si quieres que este modo sea la sintaxis por defecto, en el panel del Editor, en la venta de preferencias, elige el modo “PHP-HTML-WP” como tipo de archivo por defecto

Ahora CODA ya identificará las funciones WordPress, facilitándote la vida como desarrollador de WordPress, como ya hacía con PHP, HTML o CSS, por ejemplo.

Encontrado en HitchHackers

Obtener y mostrar imágenes del contenido

Desde hace varias versiones que WordPress puede mostrar en tu tema imágenes destacadas pero ¿qué pasa si no usas ese sistema?, o si simplemente tu tema no soporta imágenes destacadas.

La solución sería un código que revise tu contenido y, si encuentra una imagen, la muestre en tu sitio.

Sería una cosa así:

// Empieza el Loop
<?php if (have_posts()) : ?><?php while (have_posts()) : the_post(); ?>
<?php
// Definimos el contenido de la entrada a una variable
$szPostContent = $post->post_content;
// Defininimos el patrón a buscar
$szSearchPattern = '~<img [^\>]*\ />~';
// Ejecutamos preg_match_all para obtener todas las imágenes y guardar los resultados en $aPics
preg_match_all( $szSearchPattern, $szPostContent, $aPics );
// Contamos los resultados
 $iNumberOfPics = count($aPics[0]);
// Comprobación de si hay al menos 1 imagen
if ( $iNumberOfPics > 0 )
{
     // Ahora hacemos lo que sea con las imágenes
     // En este ejemplo se muestran las imágenes
for ( $i=0; $i < $iNumberOfPics ; $i++ ) {
          echo $aPics[0][$i];
     };
};

endwhile;
endif;
?>
// ...termina el loop, etc

En el código anterior, una vez mostramos las imágenes es bastante probable que quieras también mostrar el contenido ¿no?. Vale, pues el problema es que si usamos la función the_content(); las imágenes se volverán a mostrar. Para resolver esta puñetita solo hay que hacer un rodeo para quitar las imágenes, y mostrar solo el resto del contenido:

// Esta vez remplazamos/quitamos las imágenes del contenido
$szDescription = preg_replace( $szSearchPattern, '' , $szPostContent);
// Aplicamos filtros para que se muestre bien el contenido
$szDescription = apply_filters('the_content', $szDescription);
// Mostramos el contenido
echo $szDescription;

¡Y ya está!

Esta virguería la creó Matt Varone.

URL de acceso sencilla en WordPress

Creo que sabes de sobra que para acceder al escritorio de cualquier WordPress basta con añadir a la URL del sitio /wp-admin/ o wp-login.php, pero si quieres personalizar un poco más la URL de acceso al login de WordPress puedes hacerlo, y bien fácil.

Además, como ya vimos como cambiar la URL de acceso con plugin ahora toca hacerlo con un sencillo código.

Lo único que tienes que hacer es añadir una simple redirección en el fichero .htaccess de tu sitio, de este modo:

RewriteRule ^acceso$ http://tusitio.es/wp-login.php [NC,L]

Solo tienes que cambiar un par de cosas, la cadena acceso por la que tu quieras, para que quede como http://tusitio.es/acceso, que es el caso del ejemplo, o a tu gusto; y la url de tu sitio, claro.

Luego, lo suyo es que ofrezcas una pantalla de acceso personalizada, para ofrecer una experiencia completa.

Migrar de Drupal 6 a WordPress 3

Muchos de nosotros empezamos en el mundo de los CMSs con Drupal y a lo largo del tiempo nos hemos ido dando cuenta que WordPress es una mucho mejor opción y nos planteamos el cambiarnos de bando, eso sí, sin perder todos los posts, comentarios, categorias, … que durante largo tiempo (dos años en mi caso) hemos ido añadiendo en Drupal.

Por suerte, la migración de los datos es posible, aunque no tan simple como desearíamos. Basados en algunos scripts que encontré en su momento (como ésteéste o éste) me decidí a crear una programa en Java que se encargara de hacer la migración de los datos básicos de forma automática y que funcionara para versiones más recientes de Drupal y WordPress.

Por datos básicos se entienden los posts, páginas, stories, categorias y comentarios. Para temas más avanzados (CCKs, foros, usuarios y roles, redirecciones de las URLs, internacionalización y un largo etc) podéis consultar los servicios de migración profesionales que se ofrecen en Go WordPress (más de medio millón de posts migrados ya de Drupal y otros CMSs a WordPress!).

Las operaciones de conversión que realiza el programa son las siguientes (el código fuente está disponible gratuitamente al final del post). Obviamente, el programa está configurado para funcionar con mis datos de conexión y para los casos concretos que comentaba anteriormente. Adaptadlo a vuestras necesidades y ¡utilizadlo a vuestra cuenta y riesgo!.

Pasos para la migración de Drupal 6 a WordPress 3:

  1. Instalar WordPress en la misma base de datos donde tenéis Drupal instalado (no obligatorio pero facilita la escritura de queries que accedan a los dos conjuntos de tablas al mismo tiempo)
  2. Eliminar los datos de las siguientes tablas de WordPress: comments, posts, postmetaterm_relationships, term_taxonomy, terms.
  3. Migración de las taxonomías de categorías en Drupal.  Cada fila en term_data se inserta en las tablas de WordPress terms term_hierarchy en term_taxonomy (si la categoría es hija de otra categoría)
  4. Migración de los posts/páginas. Esto implica recuperar los datos de las siguientes tablas de Drupal: node (información básica del post como el título, la fecha,…), node_revisions (el body y el teaser del post) y url_alias (la clean URL que se utiliza para acceder al post). Toda esta información se inserta en la tabla posts en wordpress. Drupal guarda como URL la URL completa del post mientras que en wordpress cada post sólo guarda la parte correspondiente al título del post con lo que hay que realizar la adaptación pertinente.
  5. Corregir los links internos a imágenes y archivos en el body de los posts. En WordPress normalmente las tendremos en la carpeta “uploads” mientras que en Drupal estaban probablemente en “sites/default/files”. Hay que reescribir todas las referencias a esta segunda para que los links apunten correctamente a la carpeta de wordpress. Esto lo hacemos con una instrucción como ésta :  body=body.replaceAll(“/sites/default/files/”, “/wp-content/uploads/”);
  6. Relacionar posts y categorias. En Drupal la relación se guarda en term_node y hay que moverla a la tabla term_relationships en wordpress.
  7. Una vez migrados los links hay que actualizar el attributo count de categoria para que muestre el número de posts asociados a esa categoria según la información en term_relationships que acabamos de generar
  8. Migración de los comentarios. Bastante directa, de la tabla comments de Drupal a la comments de wordpress.
  9. Igual que antes, hay que actualizar el atributo  comment_count de la tabla posts table para que refleje el valor correcto de comentarios asociados al post (sinó, los comentarios no se mostraran aunque se hayan insertado correctamente).

El código fuente Java que realiza estas operaciones se puede descargar aquí .

Forzar el cambio de contraseña cada 30 días

Si tienes una web en la que la seguridad sea importante, seguramente te gustaría aplicar el criterio de que los usuarios cambien de contraseña cada cierto tiempo, como es exigible en entornos corporativos, donde se fuerza el cambio de claves para evitar el uso de contraseñas fáciles de recordar o la desidia de los usuarios al respecto de la seguridad del sitio.

Si es tu caso te recomiendo utilizar Expire user password, que automatiza la obligación de cambiar la contraseña a los usuarios registrados cada 30 días.

No hay nada que configurar, lo activas y empieza la cuenta atrás, así de simple.

También funciona para instalaciones multisitio, lo que tiene todo el sentido.

Si quieres cambiar el tiempo de expiración de las contraseñas deberías entonces añadir al fichero wp-config.php una nueva variable ‘DEFINE’ llamada “TMG_AEP_EXPIRY” definiendo el número de segundos a partir de los cuales se pedirá de nuevo el cambio de contraseña.

Cambiar contraseña perdida de WordPress

Si has olvidado la contraseña y, por algún motivo que no alcanzo a comprender, no tienes acceso a tu email para recuperarla, ni puedes acceder a tu base de datos, hay una oportunidad más para poder cambiar la contraseña si te acuerdas del ID de tu usuario (que si es un usuario único y aún usas el primero que activaste en la instalación será el número 1).

Eso si, todo arreglo tiene su precio, y es que debes poder acceder por FTP a tu instalación de WordPress.

Si este es tu caso y no te vale la opción de cambio de contraseña mediante PHPmyAdmin o no te fías de scripts para recuperar contraseñas de WordPress, puedes cambiarla con una sencilla función.

Solo tienes que acceder por FTP y abrir el fichero functions.php de tu tema activo y añadir la siguiente función:

wp_set_password('NuevaClave',1);

Donde “NuevaClave” es la nueva contraseña que elijas y “1″ (ambos sin comillas) el ID de usuario. Guarda los cambios y ya podrás entrar en tu sitio con tu nombre de usuario y la “NuevaClave“.

A mandar ;)