Wordpress (Continuación)

Cuando usamos “iframe” para inserta un vídeo, centrarlo no es complicado porque basta con utilizar la sintaxis que usamos con cualquier párrafo, es decir

<p style="text-align: center;"><iframe...></iframe</p>

El problema es cuando usamos el reproductor de medios propio de WordPress. No podemos centrarlo ni tampoco alinearlo a la derecha o la izquierda porque su aspecto está definido en una hoja de estilos propia del sistema. En concreto, wp-mediaelement.css (dentro de wp-includes/js/mediaelement/). No obstante hay una solución:
1.- Editamos la hoja de estilos de nuestra tema (normalmente style.css).
2.- Añadimos las siguientes líneas:

NOTA: para el caso de vídeos subidos a nuestro servidor la regla válida es “.videocentrado .wp-video“, Para vídeos fuera de nuestro servidor (Yotube, vimeo, etc), es de aplicación “.videocentrado .embed-wrap“.

.videocentrado .wp-video, .videocentrado .embed-wrap {
margin-left:auto;
margin-right:auto;
margin-bottom:20px;
margin-top:20px;
}

3.- Ahora, cuando editemos una entrada e incrustemos un vídeo, debemos hacerlo de la siguiente forma:

<div class="videocentrado">Código del vídeo</div>

La “div” la pondremos manualmente en la pestaña “Texto” del editor de texto.
4.- Para alinear a la izquierda o a la derecha:

.videoizquierda .wp-video, .videoizquierda .embed-wrap {
	margin-bottom:20px;
	margin-top:20px;
	margin-right:20px;
	float:left;
}
.videoderecha .wp-video, .videoderecha .embed-wrap {
	margin-bottom:20px;
	margin-top:20px;
	margin-left:20px;
	float:right;
}

En los dos últimos casos, si insertamos texto dentro de la “div”, éste quedará “flotando” a la derecha o izquierda respectivamente.

NOTA: para el caso de vídeos subidos a nuestro servidor la regfuera de nuestro servidor (Yotube, vimeo, etc), debemos usar “embed-wrap” en lugar de “wp-video”.

Mismo sidebar, distinto contenidoHoy vamos a ver cómo se puede variar el contenido de un mismo sidebar según una página u otra. Como veremos, cabe añadir tanto texto como imágenes.

El caso más frecuente es si utilizamos wordpress no como blog sino como CMS para crear un sitio. En este caso, lo normal es usar “páginas” y no entradas, y también es conveniente, en caso de usar imágenes, poder incluir éstas en el sidebar. Pongamos un ejemplo para entendernos:

En el capítulo VI de “Liberalismo y romanticismo en tiempos de Isabel II” observamos que en el sidebar hay unas cuantas imágenes que incluso pueden ampliarse. Si nos vamos al capítulo VIII, nos encontramos con el mismo sidebar pero distintas imágenes. Observemos también que la página está dividida en tres partes (mediante <!–nextpage–>) y que se muestran distintas imágenes en cada una de éstas.

Veamos como hacerlo: Seguir leyendo …

Al módulo “Compartir” de Jetpack le falta bastante para convertirse en una herramienta completa pero, todo sea dicho, tras probar varios plugins me quedo con él. No obstante, es conveniente mejorar alguno de sus aspectos:

Colocación manual de los botones.

En primer lugar en “Ajustes > Compartir > Mostrar botones” marcaremos las opciones que nos interesen. Las explicaciones que doy son para el caso de haber seleccionado solo “Entradas” pero pueden aplicarse a todas ellas.

En segundo lugar, buscaremos en los archivos de nuestro tema la función “the content” o “the excerpt” (normalmente en “single.php”) y justo ANTES añadiremos una de las siguientes líneas: Seguir leyendo …

La última actualización de seguridad de WordPress resuelve varios problemas pero añade uno, a saber, la inserción de “Campos personalizados” (Custom Fields) en las entradas. El caso es que no se pueden añadir dichos campos salvo que, una vez insertado su valor, se guarde el borrador de la entrada.

A la espera de una nueva actualización, tenemos una solución bastante sencilla: descargar el archivo fix-custom-fields-in-wp342.zip, descomprimir, subir el archivo php a la carpeta de plugins de vuestro WP y activar desde le panel de control. El código lo podéis ver aquí.

También está disponible un plugin en el directorio oficial de WP: Hotfix.

De las dos soluciones, he probado solo la primera y funciona perfectamente.

Imaginemos un blog de música en el que se pasa revista a las últimas novedades. Aparte de la crítica, deberá ofrecer información básica como el nombre del autor o grupo, estilo musical, etc. La forma más sencilla de ofrecer estos datos no es otra que las taxonomías. Por lo tanto, lo primero será ponerlas en marcha: Taxonomías avanzadas en WordPress 3.1.

El segundo paso sería añadir una nueva página donde se mostrara un listado de todos los autores o grupos musicales, otra con los estilos musicales, etc. Para ello usaríamos la función get_terms. Así lo hacemos y vamos escribiendo entradas hasta que nos encontramos con que, por ejemplo, el número de los primeros supera los mil. Por tanto, decidimos dividir el listado en varias páginas.

¡Ojo! NO estamos hablando del campo “author” que identifica a quien publica una entrada sino de los autores que han compuesto la música.

El tercer paso es preparar una plantilla (podemos usar como base el archivo page.php). En nuestro caso podemos eliminar todo excepto las divisiones principales (dependerá de cada tema) y las llamadas al header, sidebar y footer. El archivo resultante, en lugar de page_personalizada.php, lo llamaremos listado-autores.php y en el encabezamiento pondremos:

<?php
/*
Template Name: Listado autores
*/
?>

Todo el código que se muestra a continuación debe insertarse en el archivo listado-autores.php.

Cuarto paso: construir el array y lo necesario para paginar:

<?php
$page = ( get_query_var('paged') ) ? get_query_var( 'paged' ) : 1;
$per_page = 300;
$offset = ( $page-1 ) * $per_page;
$args = array(
'orderby' => 'slug',
'number' => $per_page,
'offset' => $offset,
'paged' => $paged
);
?>

La variable $per_page determina el número de autores a mostrar en cada página y $orderby el orden en el que se mostrarán. Recomiendo usar slug para evitar errores con ciertos caracteres. El resto de las líneas no deben modificarse.

Quinta parte: llamar a la función get_terms  y ejecutar un bucle. Nota: Para no alargar el comentario en demasía, omito la parte que permite mostrar el listado en tres columnas e indico solo la forma para una lista sin ordenar. Si alguien está interesado en el código completo, que me lo pida.

Nota: autor es el nombre de la taxonomía. Debéis cambiarlo por el que corresponda.

<?php
    $terms = get_terms("autor", $args);
    echo '<ul>';
    foreach ($terms as $term) {
        echo '<li><a href="'. get_term_link($term->slug, 'autor') . '" title="' . $term->count . ' artículos">'. $term->name.'</a></li>' . "\n";
    }
    echo '</ul>';
?>

Sexta parte: el código necesario para mostrar las páginas.

<?php
$total_terms = wp_count_terms('autor');
$pages = ceil($total_terms/$per_page);
if( $pages > 0 ):
	echo '<div class="paginterna">';
    for ($pagecount=1; $pagecount <= $pages; $pagecount++):
		if ($paged == $pagecount) :
			$ruta = '<span class="maspaginas">Pág.' . $pagecount . '</span>';
			else:
			if ($pagecount == 1 and $paged <=1):
				$ruta = '<span class="maspaginas">Pág.' . $pagecount . '</span>';
				else:
				$ruta = '<span class="maspaginas"><a href="'.get_permalink().'page/'.$pagecount.'/">Pág. '.$pagecount.'</a></span>';
			endif;
		endif;
		echo $ruta;
	endfor;
	echo '</div>';
endif;
?>

Como podéis comprobar, hemos usado dos estilos: paginterna y maspaginas. Lo mismo de antes; si alguien está interesado que me lo diga.

Finalmente creamos una nueva página y en el apartado “Plantilla” (sección “Atributos de página”) seleccionamos “Listado autores” (ver el tercer paso).

Y el resultado lo podéis ver el la Revista de Prensa: Archivo por autores.

Si alguna vez ha querido mostrar el valor de una variable en el “footer” y que previamente había calculado en el loop, es muy posible que no se muestre. Para asegurarnos de que el código funciona debemos declararla de un forma concreta.

1.- Obtenemos el valor de la variable:

<?php $GLOBALS['$nombre-variable'] = 'valor-variable'; ?>

2.- Mostramos la variable en el “footer”:

<?php echo $GLOBALS['$nombre-variable']; ?>

Un ejemplo práctico. En la sección Arte e Historia, formada solo con páginas, quería mostrar en el “footer” el enlace a la página y el relativo al trackback. Pues bien, aquí podéis verlo en acción. El código utilizado ha sido el siguiente:

1.- Archivo page.php:

<?php
$GLOBALS['$infopie'] = '<p><strong>Información:</strong> Usted puede <a href="' . get_permalink() . '" rel="bookmark" title="Enlace permanente a ' . the_title_attribute( array('echo' => 0)) . '">enlazar esta entrada</a> o hacer <a href="' . get_trackback_url() . '" rel="trackback">trackback</a> desde su propio blog.</p>';
?>

2.- Archivo footer.php

<?php echo $GLOBALS[ '$infopie' ]; ?>

Las fechas siempre resultan problemáticas a la hora de compararlas porque la mayoría de las funciones de WordPress devuelven una cadena de texto. Cuando se trata de comprobar si son iguales o diferentes es sencillo, pero si queremos sumar o restar días a una fecha determinada o comprobar si una es posterior a otra el planteamiento cambia. Veamos dos ejemplos:

1) Vamos a añadir una nota que informa a los visitantes de cuando se actualizó por última vez la entrada. Basta con formatear ambas fechas de forma idéntica e incluir el código en el loop del archivo single.php:

<?php
$actualizado = get_the_modified_date('l, j \d\e F \d\e Y');
$publicado = get_the_date('l, j \d\e F \d\e Y');
if ($actualizado !== $publicado) :
	echo '<p>Última actualización: '. $actualizado . '</p>';
endif
?>

El resultado sería, por ejemplo, el siguiente:  “Última actualización: Domingo, 4 de marzo de 2012”.

2) Imaginemos ahora que ejecutamos una consulta y necesitamos mostrar las entradas que se hayan actualizado en el último mes:

<?php
$mes_anterior = mktime(0, 0, 0, date("m")-1, date("d"), date("Y"));
$modificado = get_the_modified_date('d/m/Y');
list($dia,$mes,$ano) = explode('/',$modificado);
$fecha_modificado = mktime(0,0,0,$mes,$dia,$ano);
if ($fecha_modificado > $mesanterior) :
	echo 'Esta entrada se actualizó hace menos de un mes';
endif
?>

Expliquemos con algo más de detalle:

  • Línea 2: calculamos la marca de tiempo Unix para hace 1 mes.
  • Líneas 3 al 5: calculamos la fecha en la que fue modificada la entrada por última vez y la convertimos a marca de tiempo Unix.
  • Línea 6: efectuamos la comparación gracias a que ambas variables son números enteros.

Documentación: date, mktime, get the modified date y get the date.

Estos últimos meses he dedicado buena parte del tiempo a profundizar en WordPress (y PHP) con el fin de personalizar la plantilla e incorporar nuevas funcionalidades. Intentaré a partir de ahora ofrecer los lunes trucos sencillos. Aquí tienen el primero de ellos:

En el editor de texto de WordPress aparece la opción “Insertar etiqueta More” que nos permite “cortar” la entrada en el punto que deseamos. De esta forma, aún cuando usemos “the_content” no se mostrará la entrada completa sino solo la parte definida por la mencionada etiqueta.

Existe, no obstante, una forma para hacerlo de forma automática en función del número de palabras que contenga la entrada:

<?php
global $post;
$numcontent = str_word_count($post->post_content);
if ($numcontent > 200) {
echo the_excerpt();
} else {
echo the_content();
}
?>

Si la entrada tiene más de 200 palabras, se muestra un resumen. En caso contrario, todo el texto. El código debe añadirse en The Loop, y lo normal sería incluirlo en “index.php” y “archive.php”.

Ahora bien, la función “the_excerpt” presenta un problema, a saber, devuelve texto plano. Esto significa que negritas, cursivas, enlaces o cualquier otra etiqueta HTML desaparece. Para solucionarlo es aconsejable usar el plugin Advanced Excerpt. Su configuración es muy sencilla y permite seleccionar las etiquetas HTML que aparecerán en el resumen.

Actualización Mayo 2017

La opción para eliminar los shortcodes (y la leyenda de las imágenes) del mencionado plugin no funciona. En esta otra entrada explico como solucionarlo.

Desde el principio, uno de mayores problemas ha sido encontrar un plugin que permitiera buscar en el blog de forma rápida y eficiente. Después de mucho tiempo usando Search Unleashed no ha quedado más remedio que buscar otra alternativa ya que no funciona con la versión 3.x de WordPress. El elegido para suplirlo ha sido Relevanssi. No es tan tan potente como el anterior u otros buscadores compatibles, pero lo he probado esta misma tarde y parece que su funcionamiento es más que correcto. Devuelve los resultados con velocidad y permite la búsqueda de frases exactas (usando comillas). Veremos lo que ocurre en la Revista de Prensa pues allí tenemos más de 30.000 entradas.

Hace unos días me ofrecí a compartir el código del archivo por meses con la comunidad de la excelente bitácora Ayuda WordPress en Español, y de ahí este comentario.

Por defecto, los meses se muestran uno debajo de otro pero cuando llevas un tiempo en la Red la lista se hace interminable. De ahí que buscara y aplicará un sistema que permitiera incluir los meses de cada año en una sola línea. Por desgracia, no recuerdo de dónde lo obtuve y pido por ello disculpas a su autor pues no puedo citarlo.

El código se inserta en archives.php del tema y aquí lo tenéis en formato txt.

<?php
global $month, $year; // scope WP global variables for later use
/* $arc_years => archive years query */
$arc_years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_status = 'publish' ORDER BY post_date DESC");
foreach($arc_years as $arc_year) : // foreach loop for archive years
?>
<ul>
<li><p>Archivo año <a href="<?php echo get_year_link($arc_year); ?> "><?php echo $arc_year; ?></a>:</p>
<?php
/* $arc_months => archive months query for archive year */
$arc_months = $wpdb->get_col("SELECT DISTINCT MONTH(post_date) FROM $wpdb->posts WHERE YEAR(post_date) = '$arc_year' AND post_status = 'publish' ORDER BY post_date");
foreach($arc_months as $arc_month): // foreach loop for archive months of archive year
?>

:: <a href="<?php echo get_month_link($arc_year, $arc_month); ?> "><?php echo $month[zeroise($arc_month, 2)]; ?></a>

<?php endforeach; // end foreach loop for archive months ?>
 ::</li></ul>
<?php endforeach; // end foreach loop for archive years ?>