Cómo añadir en tres pasos un metabox a un Custom Post Type de WordPress
Concha Alviz | 7 octubre, 2016 | 10:04 am
Dar de alta un Metabox en WordPress puede parecer algo complicado. Sin embargo, como veremos en este artículo, es posible desarrollar un Metabox en WordPress fácilmente y en tan solo 3 pasos. Pero vayamos por partes…
¿Qué es un Metabox?
Como más de uno sabréis, WordPress es un framework muy muy versátil. Aunque, a primera vista, pareciera que su uso solo estuviera concebido para desarrollar blogs, es un gestor de contenidos muy potente y flexible. Por defecto, soporta diferentes tipos de contenido (o post types):
- Artículos (o Posts)
- Páginas (o Pages)
- Adjuntos (o Attachments)
- Revisiones (o Revisions)
- Menú de navegación (o Navigation Menu)
Sin embargo, desde la versión 3.0, también permite la creación de nuestros propios contenidos (Custom Post Types) y nos permite utilizarlos y desarrollarlos de maneras casi infinitas.
Cada CPT, por lo tanto, es un mundo, y puede contener casi cualquier dato que necesitemos. Para introducir estos datos en la administración y, por tanto, para mostrarlos en nuestra plantilla, necesitaremos Metaboxes que, en la mayor parte de los casos, serán inputs para introducir y ordenar nuestro contenido.
Aunque WordPress ya incluye Metaboxes clásicos y por defecto, — como el Título, el Extracto, el Contenido o las Categorías por ejemplo —, que pueden dar mucho de sí, en la mayor parte de los proyectos es bastante probable que necesitemos nuevos y customizados Metaboxes que nos permitan introducir nuestro contenido específico y que se adapten a nuestras necesidades.
¿Cómo crear un Metabox fácilmente?
Imaginad que tenemos una empresa de desarrollo web y que en nuestro sitio corporativo queremos incluir los proyectos que llevamos a cabo, a modo de galería. Nos interesaría mostrar una captura de pantalla de cada una de las webs que hemos desarrollado y asociar a cada una de ellas una url al sitio web final. Para ello, registramos un Custom Post Type para albergar este tipo de contenidos:
add_action('init','myprojects'); function myprojects(){ register_post_type( 'projects', array( 'labels'=>array( 'name'=>'Proyectos', 'singular_name'=>'Proyecto', 'add_new'=>'Añadir nuevo', 'add_new_item'=>'Añadir nuevo proyecto', 'edit_item'=>'Editar proyecto', 'new_item'=>'Nueva proyecto', 'view_item'=>'Ver proyecto', 'search_items'=>'Buscar proyectos', 'not_found'=>'No se encontraron proyectos', 'not_found_in_trash'=>'No se encontraron proyectos en la papelera' ), 'public'=>true, 'has_archive'=>true, 'menu_position'=>20, 'menu_icon'=>plugins_url('/img/review.png',__FILE__), 'hierarchical'=>true, 'supports'=>array( 'title', 'thumbnail', ), 'taxonomies'=>array( 'category', 'post_tag', ), ) ); }
Según el CPT que hemos creado y los supports que hemos añadido, la ficha básica de cada uno de nuestros proyectos incluirá un título y una miniatura o thumbnail, por lo que el requisito de incluir una captura de pantalla de nuestros trabajos estaría cumplido. Solo tendríamos que asociar una imagen destacada a cada uno de los proyectos y mostrarla en plantilla de la manera que más nos convenga. Sin embargo, ¿qué ocurre con la url que queremos incluir en cada proyecto?
Podríamos ser un poco guarretes y añadir el support editor, que nos incluiría en la ficha de proyecto un área de contenido libre (lo que comúnmente llamamos con the_content()
), donde poder incluir la url. Sin embargo, para rizar un poco el rizo y para darle sentido a esta especie de tutorial, vamos a crear un Metabox muy sencillo.
Paso 1: Registrar el Metabox en nuestro CPT
Para ello, debemos incluir el siguiente código en nuestro CPT:
'register_meta_box_cb' => 'add_url_metaboxes',
Yo lo he llamado ‘add_url_metaboxes‘, pero vosotros podéis (y debéis) llamarlo como queráis. El CPT, por lo tanto, quedaría de esta manera:
add_action('init','myprojects'); function myprojects(){ register_post_type( 'projects', array( 'labels'=>array( 'name'=>'Proyectos', 'singular_name'=>'Proyecto', 'add_new'=>'Añadir nuevo', 'add_new_item'=>'Añadir nuevo proyecto', 'edit_item'=>'Editar proyecto', 'new_item'=>'Nueva proyecto', 'view_item'=>'Ver proyecto', 'search_items'=>'Buscar proyectos', 'not_found'=>'No se encontraron proyectos', 'not_found_in_trash'=>'No se encontraron proyectos en la papelera' ), 'public'=>true, 'has_archive'=>true, 'menu_position'=>20, 'menu_icon'=>plugins_url('/img/review.png',__FILE__), 'hierarchical'=>true, 'supports'=>array( 'title', 'thumbnail', ), 'taxonomies'=>array( 'category', 'post_tag', ), ) 'register_meta_box_cb' => 'add_url_metaboxes', //Registramos el Metabox ); }
Paso 2: Añadimos nuestro Metabox
Ya fuera de la función de nuestro CPT, añadimos nuestro Metabox mediante la función de WordPress add_meta_box()
. Genéricamente, esta función se desarrolla de esta manera:
add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args )
Donde:
$id
: la ID del Metabox.$title
: el título de nuestro Metabox. Será el título que aparezca en el módulo que se muestre en la administración.$callback
: Función que rellena el Metabox con el contenido deseado.$screen
(opcional): La pantalla o pantallas en las que mostrar el metabox (por ejemplo, en un CPT)$context
(opcional): El contexto en donde se situará nuestro módulo dentro de la administración. Normalmente, ‘normal, ‘side’ o ‘advanced’.$priority
(opcional): La prioridad o posición que tendrá el módulo dentro del contexto elegido. Es decir, alta o baja.$callback_args
(opcional): Otros datos que queramos incluir en nuestra función.
Todo esto, aplicado a nuestro ejemplo, nos dejaría:
function add_url_metaboxes() { add_meta_box('url_live_template', 'Url Live Template', 'url_live_template', 'projects', 'side', 'default'); }
Como veréis, lo hemos incluido todo en una función llamada add_url_metaboxes()
cuyo nombre coincide con el que usamos al registrar nuestro Metabox en el CPT del paso 1. Hemos escogido ‘url_live_template‘ como nombre para la $id
de nuestro metabox y para el $callback
, mientras que hemos optado por ‘Url Live Template‘ como $title
de nuestra caja en la administración. Además, hemos asociado nuestro metabox a el CPT ‘projects‘, por lo que solo aparecerá en los post de este tipo, y hemos considerado que aparezca en el ‘side‘ de la administración, con una prioridad ‘default‘. No hemos incluido $callback_args
.
Paso 3: Desarrollar nuestro Metabox
Para desarrollar nuestro Metabox, crearemos la función url_live_template()
, el mismo nombre que utilizamos como $callback
en la función anterior:
function url_live_template() { global $post; // Añadimos un 'noncename' que necesitaremos para verificar los datos y de dónde vienen. echo '<input type="hidden" name="urltemplate_noncename" id="urltemplate_noncename" value="' . wp_create_nonce( plugin_basename(__FILE__) ) . '" />'; // Recuperar los datos existentes, si es que hay datos existentes. $url_template = get_post_meta($post->ID, 'url_template', true); // El input que aparecerá en administración donde introducir/mostrar los datos echo '<input type="text" name="url_template" value="' . $url_template . '" />'; }
En este punto, hay que tener especial cuidado en la elección de name
, id
y value
que escogemos para cada uno de los inputs
. Los escogidos para el noncename los tendremos que utilizar, más adelante, cuando guardemos los datos. El value
y el name
del input
que aparecerá en la administración, también, y estos serán el meta_value
y el meta_key
, respectivamente, que se registrarán en base de datos. Para nuestro ejemplo, el input
que hemos escogido es uno de tipo texto, pero podéis escoger el que consideréis más apropiado.
Paso 3: Guardar los datos de nuestro metabox
Para ello, crearemos una nueva función llamada save_url_live_template()
. Vosotros podéis usar el nombre que os parezca más oportuno. Por lo general, y para tener un poco más ordenado, le suelo añadir el prefijo ‘save_‘ al nombre de la función que utilizo para generar el metabox (en el paso anterior)
function save_url_live_template($post_id, $post) { // Verificamos que los datos vienen del metabox donde se encuentra el noncename que hemos establecido anteriormente if ( !wp_verify_nonce( $_POST['urltemplate_noncename'], plugin_basename(__FILE__) )) { return $post->ID; } // Verificamos si el usuario tiene autorización para editar el post if ( !current_user_can( 'edit_post', $post->ID )) return $post->ID; // Incluimos los datos en un array para poder hacer el foreach de más abajo. $url_meta['url_template'] = $_POST['url_template']; foreach ($url_meta as $key => $value) { if( $post->post_type == 'revision' ) return; // Verificamos que no se trate de una revisión. if(get_post_meta($post->ID, $key, false)) { // Si ya tiene un valor, lo actualizamos. update_post_meta($post->ID, $key, $value); } else { // Si no tiene un valor, lo creamos. add_post_meta($post->ID, $key, $value); } if(!$value) delete_post_meta($post->ID, $key); // Si está en blanco, lo borramos. } } add_action('save_post', 'save_url_live_template', 1, 2); // Guardamos los datos
¡Y ya está! Nuestro metabox creado en tres simples pasos. ¿A que es fácil? A partir de ahora, crear un metabox siempre será algo muy fácil… y divertido.