En alguna ocasión podemos estar interesados en mostrar un metabox con campos personalizados o custom fields para una plantilla determinada o concreta, y no mostrarlos en el resto para tener el back-end limpio y ordenado, y no mostrar más datos de los necesarios.
Pongamos como ejemplo que tenemos una plantilla de página page-proveedor.php, donde tenemos unos campos personalizados de contacto: e-mail y teléfono. Cómo estos campos sólo los mostraremos en el front-end en las páginas que tengan esta plantilla, ¿por qué no hacer lo mismo en el back-end?
Vamos a ver cómo mostrarlos sólo en el caso que estemos editando una página y tengamos seleccionada la plantilla page-proveedor.php. Lo primero es agregar en nuestro functions.php un meta_box con la función add_meta_box, y después las funciones para crear los campos adicionales y guardar los datos al actualizar el post.
<?php
function my_custom_fields_metabox() {
add_meta_box( 'provider-metabox', 'Información relacionada Proveedores', 'my_custom_fields', 'page', 'normal', 'high' );
}
add_action( 'add_meta_boxes', 'my_custom_fields_metabox' );
function my_custom_fields($post) {
//si existen se recuperan los valores de los metadatos
$provider_email = get_post_meta( $post->ID, 'provider_email', true );
$provider_phone = get_post_meta( $post->ID, 'provider_phone', true );
// Se añade un campo nonce para probarlo más adelante cuando validemos
wp_nonce_field( 'provider_metabox', 'provider_metabox_nonce' );?>
<table width="100%" cellpadding="1" cellspacing="1" border="0">
<tr>
<td width="20%"><strong>E-mail</strong></td>
<td width="80%"><input type="email" name="provider_email" value="<?php echo sanitize_email($provider_email);?>" class="large-text" placeholder="E-mail" /></td>
</tr>
<tr>
<td><strong>Teléfono</strong></td>
<td><input type="text" name="provider_phone" value="<?php echo sanitize_text_field($provider_phone);?>" class="large-text" placeholder="Teléfono" /></td>
</tr>
</table>
<?php }
function my_custom_fields_save_data($post_id) {
// Comprobamos si se ha definido el nonce.
if ( ! isset( $_POST['provider_metabox_nonce'] ) ) {
return $post_id;
}
$nonce = $_POST['provider_metabox_nonce'];
// Verificamos que el nonce es válido.
if ( !wp_verify_nonce( $nonce, 'provider_metabox' ) ) {
return $post_id;
}
// Si es un autoguardado nuestro formulario no se enviará, ya que aún no queremos hacer nada.
if ( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
return $post_id;
}
// Comprobamos los permisos de usuario.
if ( $_POST['post_type'] == 'page' ) {
if ( !current_user_can( 'edit_page', $post_id ) )
return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ) )
return $post_id;
}
// Vale, ya es seguro que guardemos los datos.
// Si existen entradas antiguas las recuperamos
$old_provider_email = get_post_meta( $post_id, 'provider_email', true );
$old_provider_phone = get_post_meta( $post_id, 'provider_phone', true );
// Saneamos lo introducido por el usuario.
$provider_email = sanitize_text_field( $_POST['provider_email'] );
$provider_phone = sanitize_text_field( $_POST['provider_phone'] );
// Actualizamos el campo meta en la base de datos.
update_post_meta( $post_id, 'provider_email', $provider_email, $old_provider_email );
update_post_meta( $post_id, 'provider_phone', $provider_phone, $old_provider_phone );
}
add_action( 'save_post', 'my_custom_fields_save_data' );
También en el functions.php agregaremos un archivo custom-fields.js en el action admin_print_scripts:
<?php
function my_admin_scripts(){
//Agregamos nuestro JS
wp_enqueue_script( 'my_custom_fields_js', get_template_directory_uri() . '/js/custom-fields.js', array('jquery'), '1.0' );
}
add_action('admin_print_scripts', 'my_admin_scripts');
Por último, en este archivo custom-fields.js agregaremos estas líneas:
jQuery(document).ready(function ($) {
$('#page_template').change(function() {
$('#provider-metabox').toggle($(this).val() == 'page-proveedor.php');
}).change();
});
Como vemos, simplemente en el evento change del selector de plantilla de página (que tiene el ID #page_template), hacemos un toggle de nuestro ID del meta_box. El evento Toggle lo que hace es mostrar u ocultar el elemento seleccionado. En este caso le pasamos como parámetro la comprobación de si el valor del selector de plantilla es igual a page-proveedor.php. En caso de que sea true, se mostrará el meta_box, y se ocultará en caso contrario.
Por último lanzamos el evento .change() para que se ejecute en la carga de la página y muestre u oculte el meta_box según nuestras necesidades desde el inicio.