Añadir metadatos en WordPress a un contenido

Seguimos con esta serie de artículos sobre como crear un plugin para WordPress. En el primero vimos como crear un contenido específico (Custom Post Type). Ahora vamos a ver como añadirle metadatos.

En la entrada anterior desarrollamos un plugin para poder crear un portfolio con nuestros trabajos. Ahora vamos a ver como añadir más información a los mismos. En concreto, vamos a ver como incluir una año de inicio y un año de finalización, para poder mostrar cuanto tiempo dedicamos a cada proyecto.

¿Quieres saber como se añaden metadatos en WordPress? Ahora te lo cuento.

Añadiendo metadatos

Nuestro objetivo será añadir una caja extra a la pantalla de edición de nuestro contenido para poder añadir la información que necesitamos. Esto se hace usando la función de WordPress add_meta_box. Tiene varios parámetros, usaremos los cuatro primeros:

  • id: Indica el id html que tendrá la caja. En principio, aquí podemos poner cualquier cosa, no es algo que vayamos a usar después (salvo que queramos modificar el estilo visual de nuestra caja usando CSS o algo similar)
  • title: El título de la caja. En nuestro caso pondremos “Fecha de inicio y final”
  • callback: La función a la que llamaremos para “pintar” el contenido de la caja
  • screen: Aquí hay que indicar en que página aparecerá esta caja. Esto puede resultar algo confuso, creo que queda más claro si digo que hay que indicar el tipo de contenido para el que queremos que aparezca la caja
add_action( 'add_meta_boxes', function() {
	add_meta_box( 
		'work_portfolio_custom_fields', 
		'Fecha inicio y final', 
		'work_portfolio_custom_fields_render' , 
		'work-portfolio' );
});


function work_portfolio_custom_fields_render($post){

}

Con esto se crear una caja vacía, sin contenido. Ahora añadiremos el contenido usando la función work_portfolio_custom_fields_render

Mostrando el formulario para los metadatos

Ahora vamos a necesitar tres cosas:

  • Recuperar el valor previo del metadato, en caso de que ya existiera
  • Crear un “nonce”. Esto es un sistema de seguridad que usa WordPress para verificar que los datos que enviamos se están enviando de forma correcta y así controlar que algún atacante no intente modificar nuestros datos mediantes llamadas http. Puedes leer más en el Codex de WordPress: Nonces
  • Crear el HTML con los inputs necesarios

Todo esto iría en la función work_porfolio_custom_fields_render que habíamos dejado en blanco y que ahora quedaría de la siguiente forma:

function work_portfolio_custom_fields_render($post){
	
	//Recuperamos el valor del metadato
	$work_start_year = get_post_meta( $post->ID, 'work_start_year', true );
	$work_end_year = get_post_meta( $post->ID, 'work_end_year', true );

	//Generamos el nonce por seguridad
	wp_nonce_field( 'work_portfolio_save', 'work_portfolio_nonce' );	
	
	//Creamos los inputs
	echo '<p><label for="work_start_year" style="width: 150px;display: inline-block;">Año de inicio</label>';
	echo '<input type="number" name="work_start_year" id="work_start_year" value="'. $work_start_year .'" /></p>';
	
	echo '<p><label for="work_end_year" style="width: 150px;display: inline-block;">Año de finalización</label>'; 
	echo '<input type="number" name="work_end_year" id="work_end_year" value="'. $work_end_year .'" /></p>';
}

Vayamos por parte. Al inicio usamos la función get_post_meta para recuperar los metadatos. A esta función le pasamos tres parámetros:

  • post_id: El id del contenido cuyo metadatos queremos recuperar
  • key: El metadato que queremos recuperar. Si obviamos este parámetro la función devolverá todos los metadatos asociados al contenido. En el caso de que el contenido no tenga definido un valor para el dato que hemos solicitado devolverá una cadena vacía
  • single: Indicamos si queremos que la función devuelva un valor único. Por defecto nos devolverá un array, lo cual es más cómodo cuando queremos recibir todos los metadatos, pero en este caso resulta un código más limpio si le decimos que solo queremos un dato único.

Después generamos el nonce, esto se explica en más detalle en la página que enlacé después. Para nuestro ejemplo solo tenemos que tener que tenemos que indicar dos parámetros, action y name. Ya veremos después que haremos con ellos.

Y para acabar añadimos el html para crear los inputs necesarios. Fijaos que estos inputs tienen como name el nombre del metadato. Esto no es necesario de forma estricta, pero así nos resultará un códgio más claro. Como valor tomamos el valor previo del metadato.

Haciendo todo esto, veremos lo siguiente:

Ejemplo de metadatos en WordPress

¿El siguiente paso? Grabar los datos

Grabando metadatos en WordPress

Con esto ya estamos mostrando el formulario con los metadatos. Pero si le damos a grabar veremos que no se hace nada. Tenemos que crear otra función asociada al hook save_post para grabar el contenido.

Esta función es la siguiente, que ahora explicaré línea por línea.

add_action( 'save_post', function($post_id) {

	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;

	if ( !isset( $_POST['work_portfolio_nonce'] ) || !wp_verify_nonce( $_POST['work_portfolio_nonce'], 'work_portfolio_save' ) ) return;
	
	if ( !current_user_can('edit_post') ) return;

	if ( isset($_POST['work_start_year']) )
		update_post_meta( $post_id, 'work_start_year', $_POST['work_start_year'] );
		
	if ( isset($_POST['work_end_year']) )
		update_post_meta( $post_id, 'work_end_year', $_POST['work_end_year'] );

});

Como vemos, la función va asociada al hook save_post y recibe como parámetro el ID del post.

En la primera línea comprobamos que no se está haciendo una grabación automática. Es decir, solo guardaremos los metadatos si el usuario le da al botón de grabar de forma explícita.

En la segunda comprobamos el “nonce”. Para ello usamos la función wp_verify_nonce, a la que le pasamos el nonce generado anteriormente (que vendrá por POST con el name indicado en la llamada a wp_nonce_field) y el nombre de la acción.

Esto de los nonce es un poco confuso pero nos asegura evitar problemas con llamadas no autenticadas a nuestra web. Si vuestro código no parece hacer nada a veces es por estos “nonces”, revisad que los action y el name están donde deben.

Después añadimos otra verificación de seguirad extra. En este caso comprobar que el usuario actual tiene permisos para editar entradas. Si no, no le dejamos continuar.

NOTA: Hay que tener en cuenta que el código funcionará sin estas dos comprobaciones de seguridad. Pero claro, será menos inseguro y nos arriesgamos a que alguien nos modifique los datos “desde fuera”

Y ya para acabar usamos la función update_post_meta, con la que guardamos los datos. Esta función tiene tres parámetros a considerar:

  • post_id: El ID de la entrada a la que le asociaremos el metadato
  • key: El metadato que guardaremos
  • value: El valor del metadato
  • (prev_value): El valor previo del metadato. Este parámetro se puede utilizar para evitar posibles errores, si el valor indicado no coincide con el valor previo no se grabará el dato. En nuestro caso, lo obviamos.

Con esto ya veremos como se graba el metadato. Pero aún queda un paso más. Mostrarlo

Como visualizar los metadatos

Ahora toca visualizar esta información. Para ello añadiremos los datos introducidos al final del contenido. Por lo que usaremos el hook the_content. Recuperaremos la información usando la función get_post_meta, que ya vimos anteriomente.

add_filter( 'the_content', function( $content ) {
		
		global $post;
		
		if ( is_single() && $post->post_type == 'work-portfolio' ) {
			
			$work_start_year = get_post_meta( $post->ID, 'work_start_year', true );
			$work_end_year = get_post_meta( $post->ID, 'work_end_year', true );
			
			$content = $content . '<div class="meta_years"><strong>Fecha:</strong> '.$work_start_year.' - '.$work_end_year.'</div>';
		}
		
		return $content;
	});

Esta función recibe el contenido que se va a visualizar a través de la variable content. ¿Y qué hacemos? Pues añadir los metadatos detrás del contenido. Y una vez hecho, devolvemos dicha variable.

Además, añadimos un par de comprobaciones previas. La primera, usamos la función is_single para que esta función solo añada contenido a las páginas individuales de cada trabajo y no a la página de archivo. Y además comprobamos el tipo de contenido (post_type) para no añadir esta contenido extra al resto de contenidos de la página.

Conclusiones

Espero que este artículo te haya sido de utilidad y hayas aprendido a añadir metadatos a contenidos en WordPress. En este caso no le estamos dando mucha utilidad, lo único que hacemos es añadir una fecha detrás del contenido. Que podrías pensar, bueno, para eso lo añadimos directamente al contenido.

Cierto, pero hay que tener en cuenta que la utilidad de estos metadatos es que después lo podremos usar para muchas cosas más. La más obvia, para filtrar o buscar contenidos en base a esta información. Pero esto ya lo veremos más adelante.