Las metaboxes en wordpress son las cajas que aparecen en cualquier página o post debajo del editor de TinyMCE, son campos agregados para darle funcionalidad extra a nuestras entradas.
En este ejemplo vamos a ver cómo las podemos crear, mostrar y finalmente cómo guardar en base de datos. Crearemos un campo de tipo texto, uno de tipo checkbox y otro de tipo wysiwyg.
Los datos de las metabox por lo general son guardados en la tabla postmeta y tienen relación únicamente con el post a través del campo post_id.
Para este ejemplo crearemos un plugin y le daremos esta funcionalidad, aunque sin mayores problemas se podría añadir al archivo functions de nuestro tema y funcionaría perfectamente.
Si tienes dudas con la creación de plugins en wordpress te invito a que revises estas entradas.
Dicho todo lo anterior veamos una imagen de lo que vamos a conseguir.
Crea tu plugin, yo al mío lo he llamado udp_metaboxes y agrega el archivo .php dentro de la carpeta, una vez lo tengas activa el plugin y vamos añadiendo el código por partes.
Añadir la metabox a los posts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // /** * @description Hook que añade una metabox */ add_action("add_meta_boxes", "udp_metabox"); /** * @description Añade una caja a un post */ function udp_metabox() { add_meta_box( "udp_caja", //identificador "¿Cómo quieres que se vea el post en un widget?", //título de la caja "udp_caja_fn_print", //función que pinta el contenido "post", //donde queremos que sea visible, post, page o nombre del post type "advanced", //donde queremos que aparezca, advanced por defecto o side (en el sidebar) "high" //prioridad a la hora de mostrarse, high será la primera ); } |
Con la acción add_meta_boxes podemos añadir una metabox, le tenemos que decir que función será la encargada de crear la metaboxes.
Crear un array con los campos a crear
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //creamos un listado de los campos para proyectos $udp_meta = array( array( "lbl" => "Título a mostrar en el widget", "id" => "udp_title", "type" => "text" ), array( "lbl" => "¿Quieres mostrar el contenido html?", "id" => "udp_chk_html", "type" => "checkbox" ), array( "lbl" => "Contenido html a mostrar en el widget", "id" => "udp_multimedia", "type" => "wysiwyg" ) ); |
Esto no hace nada por sí sólo, pero lo podremos reutilizar a la hora de crear el formulario y a la hora de guardar los datos.
Crear el formulario de la metaboxes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /** * @description Pinta el html de la metabox */ function udp_caja_fn_print() { global $udp_meta, $post; //campo nonce (campo oculto) por seguridad, evitamos que el form sea procesado desde otro dominio wp_nonce_field("udp_metabox_nonce","udp_box_nonce"); foreach($udp_meta as $field) { //obtenemos el valor del campo guardado anteriormente $meta = get_post_meta($post->ID, $field["id"], true); //también podemos obtenerlo con get_post_custom pasando el $post->ID //$meta = get_post_custom($post->ID); //comprobamos el tipo de campo switch ($field["type"]) { case 'text': ?> <p> <label for="<?php echo $field['id'] ?>"><?php echo $field["lbl"] ?></label><br> <input value="<?php echo $meta ?>" type="text" id="<?php echo $field['id'] ?>" name="<?php echo $field['id'] ?>" class="widefat"> </p> <?php break; case 'checkbox': ?> <p> <input <?php echo $meta === "on" ? "checked" : "" ?> type="checkbox" id="<?php echo $field['id'] ?>" name="<?php echo $field['id'] ?>"> <?php echo $field["lbl"] ?> </p> <?php break; case 'wysiwyg': ?> <p> <label for="<?php echo $field['id'] ?>"><?php echo $field["lbl"] ?></label><br> <?php wp_editor( $meta, //valor de editor $field['id'] //id del campo ) ?> </p> <?php break; } } } |
Si ahora accedes a la edición / creación de cualquier post verás al final del mismo la metaboxes lista para añadir contenido, el problema es que todavía no funciona, para que guarde y actualice la información debes añadir el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /** * @description Salva el contenido de nuestra caja en el hook save_post */ add_action("save_post", "udp_save_metabox"); /** * @description Salva el contenido de la metabox * @param $post_id Id del post */ function udp_save_metabox($post_id) { //si no lleva la variable post meta_box_nonce o no concuerda con udp_metabox_nonce salimos if(!isset($_POST["udp_box_nonce"]) || !wp_verify_nonce($_POST["udp_box_nonce"], "udp_metabox_nonce")) { return; } //si es un autoguardado salimos if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE) { return; } //si el usuario no tiene privilegios salimos if(!current_user_can("edit_post")) { return; } //en otro caso podemos guardar la meta global $udp_meta; foreach($udp_meta as $field) { //obtenemos los nuevos datos $udpPostData = $_POST[$field["id"]]; //actualiza el valor de la tabla wp_postmeta update_post_meta( $post_id, //id del post $field["id"], //id del campo $field["type"] === "text" ? esc_attr($udpPostData) : $udpPostData //nuevo valor ); } } |
Si te das cuenta, tenemos que hacer unas cuantas comprobaciones antes de salvar los datos, todo el código lo he comentado en cada sección para que sea muy sencillo entender el porqué de cada línea.
Así de sencillo es crear metaboxes en wordpress, a continuación dejo el código completo de nuestro plugin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | <?php /* Plugin Name: udpadmin Description: Plugin para crear una metabox en los posts Plugin URI: https://www.uno-de-piera.com Author: Unodepiera Author URI: https://www.uno-de-piera.com Version: 1.0 License: GPL2 Text Domain: unodepiera Domain Path: /languages */ // /** * @description Hook que añade una metabox */ add_action("add_meta_boxes", "udp_metabox"); /** * @description Añade una caja a un post */ function udp_metabox() { add_meta_box( "udp_caja", //identificador "¿Cómo quieres que se vea el post en un widget?", //título de la caja "udp_caja_fn_print", //función que pinta el contenido "post", //donde queremos que sea visible, post, page o nombre del post type "advanced", //donde queremos que aparezca, advanced por defecto o side (en el sidebar) "high" //prioridad a la hora de mostrarse, high será la primera ); } //creamos un listado de los campos para proyectos $udp_meta = array( array( "lbl" => "Título a mostrar en el widget", "id" => "udp_title", "type" => "text" ), array( "lbl" => "¿Quieres mostrar el contenido html?", "id" => "udp_chk_html", "type" => "checkbox" ), array( "lbl" => "Contenido html a mostrar en el widget", "id" => "udp_multimedia", "type" => "wysiwyg" ) ); /** * @description Pinta el html de la metabox */ function udp_caja_fn_print() { global $udp_meta, $post; //campo nonce (campo oculto) por seguridad, evitamos que el form sea procesado desde otro dominio wp_nonce_field("udp_metabox_nonce","udp_box_nonce"); foreach($udp_meta as $field) { //obtenemos el valor del campo guardado anteriormente $meta = get_post_meta($post->ID, $field["id"], true); //también podemos obtenerlo con get_post_custom pasando el $post->ID //$meta = get_post_custom($post->ID); //comprobamos el tipo de campo switch ($field["type"]) { case 'text': ?> <p> <label for="<?php echo $field['id'] ?>"><?php echo $field["lbl"] ?></label><br> <input value="<?php echo $meta ?>" type="text" id="<?php echo $field['id'] ?>" name="<?php echo $field['id'] ?>" class="widefat"> </p> <?php break; case 'checkbox': ?> <p> <input <?php echo $meta === "on" ? "checked" : "" ?> type="checkbox" id="<?php echo $field['id'] ?>" name="<?php echo $field['id'] ?>"> <?php echo $field["lbl"] ?> </p> <?php break; case 'wysiwyg': ?> <p> <label for="<?php echo $field['id'] ?>"><?php echo $field["lbl"] ?></label><br> <?php wp_editor( $meta, //valor de editor $field['id'] //id del campo ) ?> </p> <?php break; } } } /** * @description Salva el contenido de nuestra caja en el hook save_post */ add_action("save_post", "udp_save_metabox"); /** * @description Salva el contenido de la metabox * @param $post_id Id del post */ function udp_save_metabox($post_id) { //si no lleva la variable post meta_box_nonce o no concuerda con udp_metabox_nonce salimos if(!isset($_POST["udp_box_nonce"]) || !wp_verify_nonce($_POST["udp_box_nonce"], "udp_metabox_nonce")) { return; } //si es un autoguardado salimos if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE) { return; } //si el usuario no tiene privilegios salimos if(!current_user_can("edit_post")) { return; } //en otro caso podemos guardar la meta global $udp_meta; foreach($udp_meta as $field) { //obtenemos los nuevos datos $udpPostData = $_POST[$field["id"]]; //actualiza el valor de la tabla wp_postmeta update_post_meta( $post_id, //id del post $field["id"], //id del campo $field["type"] === "text" ? esc_attr($udpPostData) : $udpPostData //nuevo valor ); } } |
En próximos tutoriales veremos cómo mostrar esos datos en forma de widget de forma realmente sencilla.