Wordpress

Agregar campos personalizados a la administración de WordPress

Muchas veces tener simplemente “título”, “entrada” y “extracto” en WordPress como campos de texto al administrar una noticia no es suficiente para un sitio y necesitamos algún campo extra como “subtítulo”, “volanta”, “fuente”, o cualquier otro tipo de campo propio. Normalmente esto se puede gestionar usando los custom fields, pero la administración de estos campos no es tan simple o intuitiva para usuarios no avanzados y no está disponible para todos los niveles de usuario.

Para uno de los proyectos de Nicestream, en el que trabajan varios editores, necesitábamos agregar un par de campos personalizados a la administración de noticias que fuesen claros al agregar y editar. Mi idea era hacerlo sin tener que modificar el código de WordPress, para evitar bugs, tener todos estos cambios en un solo lugar y no preocuparnos al tener que actualizar el backend (en este caso la versión MU).

Hay actions y filters que permiten agregar y modificar con funciones simples distintas áreas del blog, así que la mejor solución era crear un plugin especial para mostrar los nuevos campos en la edición de posts aprovechando eso. Pero no fue tan fácil encontrar documentación y ejemplos al respecto, y tuve que revisar varias fuentes diferentes y pensar algunas cosas con Javi (estas cosas se piensan más rápido con una mente de programador) para sacarlo.

Como creo que puede ser interesante y necesario para otros, se me ocurrió compartir el código para que puedan aprovecharlo y usarlo como base si necesitan algo similar. Eso sí, el código funciona a partir de la versión 2.5 de WordPress.

1: Definir los campos a agregar

Voy a usar de ejemplo un campo para agregar un subtítulo. Primero definimos en una función un espacio en el que va a aparecer nuestro campo cuando escribamos o editemos un post:

add_action('admin_menu', 'agregar_campos');
function agregar_campos() {
	add_meta_box('subtitulo', 'Subtítulo', 'fn_subtitulo', 'post', 'normal', 'high');
}

La acción “admin_menu” sirve para que se incluya nuestra función en la administración (puede ir en otra parte del código sin problemas).

La función “add_meta_box” nos permite agregar secciones a la administración de páginas, posts y links. Los parámetros que acepta son los siguientes: ('id', 'titulo', 'funcion', 'pagina', 'contexto', 'prioridad') (pueden ver más detalles sobre esta función en el Codex de WordPress).

Entonces, agregamos una sección con el id “subtitulo”, el título de la caja será “Subtítulo”, la función que se ejecutará en esa caja será “fn_subtitulo”, la página en la que aparece será la de administrar posts, el contexto será la parte de edición básica y la prioridad es “alta”, para que aparezca arriba de los otros campos (aunque el título y el texto de la entrada siempre aparecerán primero).

Nosotros estamos usando por ahora 2 campos separados, así que simplemente agregamos otra área usando “add_meta_box” de nuevo dentro de la misma función.

2: Crear las funciones de los campos

En segundo lugar, creamos las funciones que se van a usar en los campos que agregamos:

function fn_subtitulo() {
	global $wpdb, $post;
	$value  = (get_post_meta($post->ID, subtitulo, true));
	echo '<label class="hidden" for="subtitulo">Subtítulo</label>
	<input type="text" name="subtitulo" id="subtitulo" value="'.htmlspecialchars($value).'" style="width: 600px;" />';
}

Primero invocamos las variables globales de la base de datos y de los posts. En segundo lugar definimos la variable $value y usamos “get_post_meta” para obtener el contenido de ese campo si ya existe (lo necesitamos si estamos editando un post en el que ya completamos este campo). Finalmente, incluimos un <input> en el que se puede editar ese campo (si el $value no existe todavía, obviamente lo veremos vacío). El HTML del <input> está copiado del formato usado por otros campos del formulario, pero podemos hacerlo como más nos guste (mientras valide), e incluir algún texto más si hace falta, o usar un <textarea> o lo que necesitemos en este caso. Agregué la función htmlspecialchars al contenido del campo para evitar problemas al guardar y editar textos con caracteres especiales (sobre todo con las comillas).

Si usamos más de un campo, tenemos que crear otra función similar a esta para cada uno de ellos por separado y referenciarla al agregar la “meta_box” correspondiente.

3: Funciones para agregar los campos a la base de datos

Lo siguiente sería crear una función que guarde nuestro campo personalizado en la base de datos:

add_action('save_post', 'guardar_campos');
add_action('publish_post', 'guardar_campos');
function guardar_campos() {
   global $wpdb, $post;
	if (!$post_id) $post_id = $_POST['post_ID'];
	if (!$post_id) return $post;
	$subtitulo= $_POST['subtitulo'];
	update_post_meta($post_id, 'subtitulo', $subtitulo);
}

Primero añadimos dos acciones para que esta función se ejecute tanto al publicar un post como al guardarlo si lo editamos. El resto simplemente controla el contenido enviado por el formulario con el id “subtitulo” y usa la función update_post_meta de WordPress para actualizar el campo personalizado con ese nombre referenciando al post que estamos editando.

Y ya que estamos, agregamos una función similar para eliminar de la base de datos este campo personalizado en el caso de que se borre el post al que pertenece:

add_action('delete_post', 'borrar_campos');
function borrar_campos() {
   global $wpdb, $post;
	if (!$post_id) $post_id = $_POST['post_ID'];
	if (!$post_id) return $post;
	delete_post_meta($post_id, 'subtitulo');
}

Básicamente hace lo mismo que la función anterior, pero se ejecuta sólo al borrar un post, y usa la función delete_post_meta para eliminar el campo personalizado que indiquemos.

Y, de nuevo, si tuviésemos más de un campo, simplemente habría que comprobar el $_POST correspondiente y utilizar “update_post_meta” o “delete_post_meta” de nuevo para cada campo dentro de las mismas funciones.

Recapitulando…

Si organizamos todo esto en un archivo PHP, le agregamos la cabecera que usa WordPress para sus plugins, lo subimos a la carpeta /wp-content/plugins/, y lo activamos desde la administración, estamos hechos.

El código final de este ejemplo quedaría así:

<?php
/*
Plugin Name: Campos personalizados
Version: 1.0
Author URI: http://ldablog.com.ar/
Plugin URI: http://ldablog.com.ar/2008/09/agregar-campos-personalizados-a-la-administracion-de-wordpress/
Description: Plugin para agregar campos personalizados a la administración de posts de WordPress.
Author: Leo
*/

add_action('admin_menu', 'agregar_campos');
function agregar_campos() {
	add_meta_box('subtitulo','Subtítulo','fn_subtitulo','post','normal','high');
}

function fn_subtitulo() {
	global $wpdb, $post;
	$value  = (get_post_meta($post->ID, subtitulo, true));
	echo '<label class="hidden" for="subtitulo">Subtítulo</label>
	<input type="text" name="subtitulo" id="subtitulo" value="'.htmlspecialchars($value).'" style="width: 600px;" />';
}

add_action('save_post', 'guardar_campos');
add_action('publish_post', 'guardar_campos');
function guardar_campos() {
   global $wpdb, $post;
	if (!$post_id) $post_id = $_POST['post_ID'];
	if (!$post_id) return $post;
	$subtitulo= $_POST['subtitulo'];
	update_post_meta($post_id, 'subtitulo', $subtitulo);
}

add_action('delete_post', 'borrar_campos');
function borrar_campos() {
   global $wpdb, $post;
	if (!$post_id) $post_id = $_POST['post_ID'];
	if (!$post_id) return $post;
	delete_post_meta($post_id, 'subtitulo');
}

?>

Pueden copiarlo en un archivo .php con el nombre que les parezca, subirlo a la carpeta de plugins y probarlo.

Y, por último, algo fundamental: Para mostrar este campo en la parte que queramos de nuestro theme, podemos usar la función “get_post_meta” como se ve más arriba u obtenerlo en un array usando “get_post_custom” o “get_post_custom_values“.

41 comentarios

  1. No útil. Utilísimo. Lo voy a probar en algo que estoy armando.
    ¿Se viene una serie de tutoriales para WordPress? :P

    Responder
  2. Me alegro de que sirva!

    No estaba pensando en hacer una serie, pero si en intentar compartir más esas pequeñas cosas que voy haciendo y que no están tan a mano… siempre lo dejo pasar porque me parecen muy boludas y tampoco es que yo sea un muy buen programador, pero no todo es tan fácil de encontrar y seguro que al menos sirven como base para alguien.

    Qué estás armando? Tu blog? :P

    Responder
  3. Simplemente genial! Ni te imaginas lo que me has ayudado :)

    Estaba creando un plugin parecido en el que se puedan elegir varios tipos de contenidos y dos de tus líneas me han sacado de un apuro de 5 horitas :P

    Gracias!

    Responder
  4. @ERiDeM: De nada, esa era la idea! Saludos!

    Responder
  5. Muchísimas gracias! Estoy montando una especie de «revista electrónica» que (ab)usa (de) campos personalizados y es un apuro tener que explicar su uso a los usuarios poco especializados. Con tu maravillosa ayuda voy a poder integrarles loscampos que necesito en una caja en la edición de las entradas, y eso es la leche!!

    Un abrazo, y feliz año!

    Responder
  6. ES LO QUE PRECISO pero no me fuciona, copie el texto, lo grave como .php, lo subi a plu ing pero NO ME LO DETECTA, no lo puedo activar

    Que debo hacer? no soy programador

    Saludos

    Responder
  7. Perdon, ya esta activo, ahora veo como funciona

    Responder
  8. Una cosa…
    como se llama el campo personalizado para llamar desde el theme con
    get_post_meta($post->ID, “?????????”, $single = true);

    No lo se ver…
    una ayuda!

    Responder
  9. ID, ‘subtitulo’, $single = true); ?>

    ya esta solucionado ! era un problema de mi theme !!

    Responder
  10. Excelente tutorial! he hecho todas mis funciones para el plugin que tengo pensado hacer y lo único que me faltaba era crear el formulario de los campos personalizados y no encontraba por ningun lugar algo que me explique como hacerlo! Encerio ha sido realmente útil! Gracias

    Responder
  11. Larga vida para ti hermano!! eres un genio!!!!
    necesitaba dormir…

    Responder
  12. me funciono pero como le hago para añadir mas 2 campos y ademas que funcione para subir una imagen junto con un combobox.

    gracias.

    Responder
    • Se pueden duplicar las funciones para agregar todos los campos que hagan falta, pero lo del combobox ya es un poco más complicado. Quizás te facilite la vida un plugin como Flutter.

  13. Muy bien, yo estuve testeando duplicando las funciones pero me dejaba de funcionar la administracion de WP, entonces que tanta posibilidad tengo que me pueda ayudar que es lo que debe de llevar ese archivo.

    se lo agradeceria mucho.

    saludos.

    Responder
    • Leo, alguna idea para crear lo que te comento?

      saludos.

    • Mmmm… Si no se te da fácil lo del PHP probablemente te resulte mejor bajar el plugin More Fields, que tiene una interfaz para agregar campos personalizados fijos.

  14. Muchas gracias leo, tu siempre atento a tus usuarios a sus solicitudes.

    Ya me estuve checando este plugin esta muy interesante y contiene todo lo que necesito, sabras de algun manual en español sobre este plugin.

    Gracias por adelantado.

    Saludos.

    Responder
    • La verdad no conozco manuales en español, pero es bastante sencillo de usar, no creo que tengas problemas!

  15. Vaya, era lo que andaba buscando!!!
    muy buen aporte…:))

    Responder
  16. Impresionante. Muchas gracias. Estaba buscando JUSTO esto. Me gusta mucho mucho vuestro blog. Enhorabuena.

    Responder
  17. Hernan Marenco

    Excelente, tanto la solución como la explicación. Muchas gracias por tan útil herramienta.

    Responder
  18. Jorge Codina

    Increible este artículo, es lo que estaba buscando, eres un genio…eso si tengo una duda….luego de tener los campos que quiero agregados a mi panel de edición tal como lo explicas aquí….como lo hago para mostrarlos en el sitio?? intente resolverlo viendo los links al codex de wordpress que dejas al final del artículo pero no me resulta con ninguno…

    Responder
    • Jorge, lo expliqué más o menos en este otro post. ¡Espero que te ayude!

    • Jorge Codina

      Muchas gracias..me ha funcionado de maravillas..enserio me has salvado jajaja…una consulta mas…no tienes por ahi algún tutorial que explique como agregar campos de la misma manera…pero esta vez, que permita mostrar una imagen como metadato??

      te lo agradecería mucho…o si tienes alguna pistade donde poder sacara algunaidea también..

      saludos

    • Jorge, si lo que buscás es algo que te permita subir una imagen, investigaría las funciones nativas de WordPress o buscaría un plugin que permita sumar imágenes extra a un post, no creo que haya una forma simple y prolija de hacerlo a mano usando los custom fields…

  19. Jorge Codina

    Hola de nuevo, he estado probando estas funciones, y me han andado bastante bien, asi que te agradezco nuevamente…sin embargo, tengo algunos problemas mientras voy aumentando la cantidad de opciones que agrego al editor según tu muestras…resulta que he declarado 7 campos, el último, al ingresar texto en este, y luego publicar o actualizar el artículo, el texto no se guarda y el campo aparece en blanco….

    sigo las mismas instrucciones que con los demas campos, que sí me funcionan, pero no se que puede estar fallando, ¿será que la cantidad de campos que se pueden declarar está limitado? o debo ingresar algún código extra para esto? podrías ayudarme con esta duda? la verdad que he tratado de buscar una respuesta estos últimos días y nada…y ya es un poco frustrante…
    te lo agradecería mucho

    Saludos

    Responder
    • No creo que haya ningún límite. Revisa el código a ver si hay algo mal escrito, un paréntesis mal cerrado o algún detalle así en la parte que guarda ese campo!

  20. Excelente aporte, se me hizo claro y bien explicado.
    No soy un letrado en esta área, sin embargo me atreví a probar, solo el que tu tienes hecho y sin modificar y no se si funciona en wordpress 3.2.1 porque no he visto cambios, activé el plugin y busqué donde podría verse reflejado.
    Como puedo saber que funciona si no veo un menú con el nombre que le puse al plugin???

    De antemano, muchas gracias, como dicen ustedes eres Grosso!

    Responder
    • Si el plugin está en la lista y está activado… la forma de verlo funcionando es ir a agregar un post y que aparezca el nuevo campo.

      ¿No está?

    • Cuando agrego el nuevo post aparece el campo ya creado, pero al momento de seleccionarlo y agregar el campo con info marca un error, así como al crear uno nuevo:

      Warning: Cannot modify header information – headers already sent by (output started at /home7/radiomat/public_html/elberrinchecom/wp-content/plugins/customfields.php:1) in /home7/radiomat/public_html/elberrinchecom/wp-includes/class-wp-ajax-response.php on line 129

      El nombre del archivo cambia segun haga modificaciones en el mismo sistema.
      customfields.php es el nombre que le di al archivo que he creado con el código.
      Gracias!

    • Que raro… No dejaste ningún espacio al principio del archivo antes de abrir PHP?

      Realmente a simple vista no me doy cuenta de que puede ser :S

  21. Solo quiero felicitaros por el blog. Impresionante la forma de explicar.
    Me está sirviendo de mucha ayuda.
    Pronto espero compartir con vosotros el proyecto que estoy realizando en parte con vuestra ayuda.
    Gracias

    Responder
  22. Hola lo guarde tal cual en un PHP dentro de plugins y cuando lo activo me sale este mensaje

    ———————————————————————-
    El plugin ha generado 4 caracteres de salida inesperada durante la activación. Si te sale el mensaje de advertencia “headers already sent” (cabeceras ya enviadas), problemas con las feeds u otros problemas, prueba a desactivar o eliminar este plugin.
    ———————————————————————

    y todas las “ñ” del dashboard se convirtieron en caracteres no legibles, al igual que los acentos, que podrá ser?

    Responder
  23. Muchas gracias por el blog! Os felicito.

    Tengo una duda, y si solo quiero los campos personalizados para una determinada categoría? como se podría realizar?
    Gracias

    Responder
  24. Jorge Codina

    Hola de nuevo!!! te cuento que he estado utilizando esta forma de agregar capos personalizados por bastante tiempo, y me han dado excelentes resultados, insisto con darte las gracias respecto a eso. Sin embargo, hace poco he notado una cierta falla, me explico:

    al crear un nuevo post, ingresar los datos al nuevo campo personalizado que he creado según explicas y finalmente publicar el contenido, estos se aprecian bastante bien según donde yo lo haya aplicado dentro del single.php o donde sea, sin embargo si entro a este post por el administrador de wordpress, ya sea para modifcarlo o lo que sea, y tan solo con dejar abierta esa pagina, los datos de los campos personalizados se borran automáticamente, desaparecen sin previo aviso.

    Esto sucede solo cuando no le doi click al botón “actualizar” en ese caso anda todo bien, pero en el caso de que ingrese a ese post, sin guardar o actualizar cambios los datos de los campos personalizados se borran.

    Tendrás alguna solucion para este problemilla?? creo que es un punto importante ya que un cliente normal pasa largo tiempo editando un post antes de guardarlo o actualizarlo.

    gracias!!

    Responder
  25. Jorge Codina

    Yo creo que debe ser por eso, pero no puedo asegurar nada, sigo las instrucciones tal cual, y me pasa l oque explicaba arriba

    Responder
    • No se me ocurre que puede ser y no tuve mucho tiempo para probarlo en una versión nueva de WordPress. De todas formas, para algo un poco más complejo quizás te convenga usar un plugin como More Fields y ya…

  26. Aprovecho para agradecerte este post, me sacó del paso un par de veces.
    En WordPress 3.3 paar lo que dice Jorge Codina, es decir, luego de guardar el post se queda la pantalla en blanco. La información se guarda correctamente, pero queda ahi.
    Pudieron solucionarlo? o hay que buscar otra alternativa? saludos!

    Responder
  27. Mi theme no trae campos personalizados y quiero usar uno para el thumbnail.

    Cómo lo hago???

    Responder

Comentar este post