Wordpress es una maravilla de software. Nacido en 2003, actualmente es el gestor de contenidos más usado (53.9% de cuota de mercado). La clave de su éxito, en mi opinión, radica en su sencillez de uso, en su versatilidad, en ser un proyecto libre, y sobre todo en su comunidad de usuarios, que crean plugins para casi cualquier cosa que podamos imaginar.

¿Pero sabías que se pueden crear tipos de posts personalizados en los que alojar cualquier tipo de dato que se te ocurra?

Me explico: Por defecto WordPress trae cuatro tipos de posts distintos:

  1. Entradas – Es el tipo predeterminado, para alojar nuevas entradas tipo blog.
  2. Páginas – Las páginas permanentes, fuera de la estructura cronológica de los posts.
  3. Adjuntos- Corresponde a la página que hay disponible para cada fichero adjunto.
  4. Revisiones – Una revisión es una versión antigua de otro documento, o un borrador.
  5. Menús – Son los menús de navegación creados desde el panel de control de WordPress. Sí, también es un tipo de post. ¿Sorprendido? :)

Todos ellos los crea WordPress automáticamente. Pero además de esos, nos permite crear otros nuevos que se adapten mejor a nuestras necesidades. La magia la lleva a cabo la función register_post_type().

Vamos a realizar un ejemplo en el que crearemos un catálogo de discos duros. Cada disco duro tendrá una serie de campos:

  • Nombre
  • Descripción
  • Fabricante
  • Precio
  • Capacidad
  • Velocidad de rotación
  • Imagen

Paso 1 – Dar de alta el nuevo tipo de post

Lo primero será crear el nuevo tipo de post. Podremos hacerlo de dos formas: o bien mediante código PHP, o bien desde el panel de control de WordPress.

Método 1 – Con código

Añadimos este código al fichero functions.php de nuestra plantilla:

    // Registramos un nuevo tipo de post discos duros
    add_action('init', 'register_dd', 1);
    function register_dd() {
        $labels = array(
            'name' => _x('Discos duros', 'post type general name'),
            'singular_name' => _x('Disco duro', 'post type singular name'),
            'add_new' => _x('Añadir nuevo', 'Disco duro'),
            'add_new_item' => __('Añadir nuevo disco duro'),
            'edit_item' => __('Editar disco duro'),
            'new_item' => __('Nuevo disco duro'),
            'view_item' => __('Ver disco duro'),
            'search_items' => __('Buscar discos duros'),
            'not_found' =>  __('No se ha encontrado nada'),
            'not_found_in_trash' => __('No se ha encontrado nada en la papelera'),
        );
        $args = array(
            'labels' => $labels,
            'public' => true,
            'hierarchical' => false,
            'menu_position' => 5,
            'has_archive' => true,
            'query_var' => true
            'supports' => array('title','editor','thumbnail'),
            'rewrite' => array('slug' => 'disco-duro'),
        );

        register_post_type( 'disco-duro', $args );
    }

Paso a paso, esto es lo que hacemos:

  1. Enganchamos la función “register_dd()” al evento “init”, dándole alta prioridad (cuanto más bajo, más prioritario).
  2. Definimos la función register_dd():
    1. Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de post.
    2. Creamos otro array con todas las opciones:
      1. labels – Por un lado, asignamos las etiquetas.
      2. public – Le damos visibilidad pública.
      3. hierarchical – No es un tipo de post jerárquico, donde pueda tener un post padre.
      4. menu_position – Introduciendo 5 hacemos que se muestre bajo el menú de entradas.
      5. has_archive – Permitimos acceder al archivo (listado) de discos duros.
      6. query_var – Indicamos que se podrán hacer consultas atacando a este tipo de post.
      7. supports – Lista de las funcionalidades que hemos decidido que tenga soporte este tipo de post. En concreto, permitos que tenga un título, una descripción con su editor WYSIWYG, y una imagen de miniatura.
      8. rewrite – Indicamos el nombre base que tendrán las URLs amigables.
    3. Finalmente, damos de alta el tipo de post, al que llamamos ‘discoduro’.

Si ahora accedemos al panel de control, esto es lo que veremos:

¡Ya tenemos nuestro tipo de post creado! Ha sido fácil, ¿verdad? :D

Método 2 – Sin código

¿Dije que la comunidad de desarrolladores de WordPress es genial? Existe un plugin que permite hacer todo eso, pero a golpe de ratón. Os presento a More Types. Mediante formularios web podremos crear y ajustar tanto como queramos nuestros tipos de posts personalizados. Instálatelo y ve a Ajustes > More Types:

Como ves, aparecen tanto los tipos por defecto, como los definidos por el usuario. Vamos a crear un nuevo tipo definido por el usuario pulsando sobre “Add new Post Type”. Completamos los siguientes campos:

  • Post type name singular: Disco duro.
  • Post type name plural: Discos duros.
  • Features: Marcamos ‘Título’, ‘Editor’ y ‘Miniatura’.
Desplegamos ‘Advanced Settings’:
  • Has archive: Yes.
  • Menu position: 5.
  • Menu name: Discos duros.
  • ‘Add new’ text: Añadir nuevo.
  • ‘Add new item’ text: Añadir nuevo disco duro.
  • ‘Edit item’ text: Editar disco duro.
  • ‘New item’ text: Nuevo disco duro.
  • ‘View item’ text: Ver disco duro.
  • ‘Search item’ text: Buscar disco duro.
  • ‘Not found’ text: No se ha encontrado nada.
  • ‘Not found in Trash’ text: No se ha encontrado nada en la papelera.

Pulsamos sobre ‘Save’ y ya lo tenemos. El resultado es el mismo que en el método 1:

Paso 2 – Taxonomías

La Wikipedia define a la taxonomía como la ciencia de la clasificación; es decir, una forma de agrupar cosas. Lo has usado ya mucho: cada vez que creas una categoría en tus artículos o cuando introduces las etiquetas. Tal como ocurría con los tipos de posts, WordPress trae tres taxonomías creadas de forma predeterminada:

  1. Categorías – Las categorías que ya has usado para clasificar tus artículos.
  2. Etiquetas – Etiquetas (palabras clave) que añades a cada artículo.
  3. Categoría de enlace – Las categorías con las que clasificas los enlaces en WordPress.

¿Qué taxonomías podemos crear para clasificar los discos duros? Pues unas cuantas :) Pero en este ejemplo vamos a crear sólo una: fabricante. Y de nuevo, tal como sucedía al crear los tipos de posts, podemos crearlo o bien con código, o bien utilizando plugins de terceros sin código.

Método 1 – Con código

Podemos crearla mediante código utilizando la función register_taxonomy():

    // Y creamos un nueva taxonomía para el nuevo tipo de post
    add_action('init', 'register_df', 1);
    function register_df() {
        $labels = array(
            'name' => _x( 'Fabricantes', 'taxonomy general name' ),
            'singular_name' => _x( 'fabricante', 'taxonomy singular name' ),
            'search_items' =>  __( 'Buscar fabricantes' ),
            'popular_items' => __( 'Fabricantes' ),
            'all_items' => __( 'Todos' ),
            'edit_item' => __( 'Editar fabricante' ),
            'update_item' => __( 'Actualizar fabricante' ),
            'add_new_item' => __( 'Añadir nuevo fabricante' ),
            'new_item_name' => __( 'Nuevo nombre de fabricante' ),
            'separate_items_with_commas' => __( 'Separar fabricantes con comas' ),
            'add_or_remove_items' => __( 'Añadir o borrar fabricantes' ),
            'choose_from_most_used' => __( 'Elegir de entre los fabricantes más populares' )
        );
        $args = array(
            'hierarchical' => true,
            'public' => true,
            'labels' => $labels,
            'show_ui' => true,
            'rewrite' => array( 'slug' => 'fabricantes' ),
            'query_var' => true,
		);

        register_taxonomy('fabricantes', 'discosduros', $args);
    }

Viéndolo paso a paso:

  1. Atamos la función ‘register_df’()’ al evento ‘init’, de nuevo con alta prioridad.
  2. Definimos la función register_df():
    1. Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de taxonomía.
    2. Creamos otro array con todas las opciones:
      1. hierarchical – Es un tipo de taxonomía jerárquica. Por ejemplo, las categorías son jerárquicas, mientras que las etiquetas no lo son.
      2. public – Le damos visibilidad pública.
      3. labels – Por un lado, asignamos las etiquetas.
      4. show_ui – Indicamos que se mostrará la interfaz de usuario en el panel de control para gestionarlas.
      5. rewrite – Nos permite redefinir la estructura de las URLs dinámicas con las que se accede a cada fabricante.
      6. query_var – Permite realizar consultas SQL atacando a esta taxonomía.
    3. Finalmente, damos de alta el tipo de taxonomía, a la que llamamos ‘fabricantes’, y la vinculamos al tipo de post ‘discosduros’.
¿Qué cambio ha supuesto esto? En resumen, tenemos dos. Por un lado, nos aparecerá una nueva cajita en la página de añadir/editar disco duro, donde podremos establecer el fabricante:
Y por otro, tenemos un nuevo apartado en la columna izquierda desde donde podremos gestionar los fabricantes:

Método 2 – Sin código

Espera, ¿dije que la comunidad de desarrolladores de WordPress es genial? :) También existe un plugin que nos permita crear taxonomías desde el panel de control. En esta ocasión os presento a More Taxonomies (ojo, está en estado beta). Mediante formularios web podremos crear y ajustar tanto como queramos nuestros tipos de taxonomías personalizadas. Instálatelo y ve a Ajustes > More Taxonomies:

Como ves, al pie aparecen tanto las taxonomías por defecto, como las definidos por el usuario. Vamos a crear una nueva taxonomía definida por el usuario pulsando sobre “Add new Taxonomie”. Completamos los siguientes campos:

  • Taxonomy name singular: Disco duro.
  • Taxonomy name plural: Discos duros.
  • Hierarchical: Yes
  • Allow permalinks: Yes
  • Taxonomy slug: fabricante
  • Show tag cloud: No
  • Available to: Discos duro
Desplegamos ‘Advanced Settings’:
  • Allow queries: Yes.
  • Query variable: fabricante.
  • ‘Search’ label text: Buscar fabricantes.
  • ‘Popular’ label text: Fabricantes.
  • ‘All’ label text: Todos.
  • ‘Edit’ label text: Editar fabricante.
  • ‘Update’ label text: Actualizar fabricante.
  • ‘Add new’ label text: Añadir fabricante.
  • ‘Add new name’ label text: Nuevo nombre de fabricante.
  • ‘Separate with commas’ label text: Separar fabricantes con comas.
  • ‘Add or remove item’ label: Añadir o borrar fabricantes.
  • ‘Choose from most used’ label: Elegir de entre los fabricantes más populares.
Pulsamos sobre ‘Save’, y ya tenemos creada nuestra nueva taxonomía. De nuevo, el resultado es equivalente a realizarlo sin código:

Paso 3 – Añadir nuevos campos

Nuestro nuevo tipo de post ya es capaz de alojar 4 de los 7 campos que queríamos para cada disco duro:
  1. Nombre.
  2. Descripción.
  3. Imagen.
  4. Fabricante.
Pero nos quedan otros tres:
  1. Precio.
  2. Capacidad.
  3. Velocidad de rotación.

Dado que tanto la capacidad como la velocidad de rotación son cifras más o menos redondas que comparten muchos discos duros entre sí, podríamos haber creado una taxonomía para cada uno de ellos, tal como hemos hecho con los fabricantes. Sin embargo, y dado que se trata de un ejemplo didáctico, vamos a utilizar otro método.

Seguramente ya sepas que WordPress permite añadir campos personalizados a cada post (incluso en las entradas normales tipo blog). Puedes conocer mucho más sobre ellos en el apartado ‘Custom Fields‘ de la documentación de WordPress. Su funcionamiento es muy sencillo: Cuando estés editando un post, activa la vista de los campos personalizados. Pulsa sobre ‘Opciones de pantalla’ y activa el checkbox ‘Campos personalizados’. Ahora, al pie del formulario te aparecerá un nuevo apartado para gestionar los campos personalizados:

Su funcionamiento es de tipo clave-valor. Es decir, introduces un nombre, que será el nombre con el que más adelante podrás acceder al campo personalizados, y finalmente escribes el valor que contiene la variable.

Por ejemplo, podríamos crear el campo ‘size’, donde especificar el tamaño de cada disco duro. En ese caso, pondríamos:

  • Nombre: size
  • Valor: el tamaño, por ejemplo 1TB.

Y pulsamos sobre ‘Añadir un campo personalizado’.

Todo esto funciona muy bien, pero ¿y si nos confundimos al escribir el nombre del campo? ¿Y si no lo recordamos? ¿O si se nos olvida introducir un campo? A diferencia de los dos pasos anteriores, esta vez creo que es muy recomendable crear nuestros nuevos tipos de datos mediante plugins. Es decir, de nuevo, ¡la comunidad de WordPress sale al rescate! Si ya os he presentado More Types y More Taxonomies, ¿sabéis quién queda? Os presento a More Fields.

Con More Fields podremos crear campos personalizados de cualquier tipo (radio, checkbox, text, textarea, select, etc.), adjuntos a cualquiera de los tipos de post. En concreto vamos a crear nuestros tres campos (precio, capacidad, velocidad de rotación) a nuestro tipo de post personalizado (discos duros).

Una vez que lo hemos instalado, vamos a Ajustes > More Fields, y creamos un nuevo bloque de campos (caja donde ubicaremos los nuevos campos) llamado ‘Características’, vinculado al tipo de post ‘Disco duro’, y pulsamos sobre ‘Save’:

Ya creado, accedemos a nuestro nuevo bloque y pulsamos sobre ‘Add new Field’ para cada uno de los campos.

Precio

Introducimos estos valores:

  • Field title – Corresponde al título que aparecerá junto al campo: Precio.
  • Custom field key – Nombre que tendrá la clave cuando queramos acceder al campo desde la plantilla: price.
  • Caption – Texto con instrucciones junto al campo: Introduzca el precio en Euros.
  • Field type – Number
Y pulsamos sobre ‘Save’.

Capacidad

Introducimos estos valores:

  • Field title - Capacidad.
  • Custom field key - size.
  • Caption - Introduzca la capacidad del disco duro en GigaBytes.
  • Field type - Number
Y pulsamos sobre ‘Save’.

Velocidad de rotación

Introducimos estos valores:

  • Field title - Velocidad de rotación.
  • Custom field key - speed.
  • Caption - Seleccione la velocidad de rotación en revoluciones por minuto.
  • Field type - Select.
  • Values - 15000, 10000, 7200, 5400, 4800.

Y pulsamos sobre ‘Save’.

¡Y ya tenemos creados los tres campos que nos faltaban! Si ahora accedemos al formulario de añadir o editar disco duro, veremos esto:

Ya tenemos nuestro nuevo tipo de post creado al completo: Podemos crear nuevos discos duros, gestionar sus fabricantes, su imagen destacada, su título y descripción, y añadir las características técnicas del mismo. Mola, ¿verdad? :)

Paso 4 – Mejorando el panel de discos duros

Este paso no es estrictramente necesario, pero puede mejorar notablemente la experiencia de uso a la hora de trabajar con nuestros tipos de post personalizados. Vamos a hacer que el panel de control de discos duros sea mucho más amigable. Vamos a pasar de este panel:

a este otro:

mucho más adaptado a nuestras necesidades, con más columnas, todas ellas ordenables, y con nuevos filtros en función del fabricante. Estos códigos están extraídos de la web de Yoast. Simplemente copiamos y pegamos estos bloques de código al funcions.php de nuestra plantilla:

Añadiendo nuevas columnas

function change_columns( $cols ) {
  $cols = array(
    'cb'            => '<input type="checkbox" />',
    'title'         => __( 'Nombre', 'trans'),
    'manufacturer'  => __( 'Fabricante',      'trans' ),
    'size'          => __( 'Capacidad', 'trans' ),
    'price'         => __( 'Precio', 'trans' ),
  );
  return $cols;
}
add_filter( "manage_disco-duro_posts_columns", "change_columns" );

// Definir contenido de las columnas no estándar
function custom_columns( $column, $post_id ) {
  switch ( $column ) {
    case "manufacturer":
      $manufacturers = get_the_terms($post_id, 'fabricante');
      foreach($manufacturers as $item) {
        echo '<a href="/'.$item->taxonomy."/".$item->slug.'">'.$item->name."</a>";
        break;
      }
      break;
    case "size":
      echo get_post_meta( $post_id, 'size', true)." GB";
      break;
    case "price":
      echo get_post_meta( $post_id, 'price', true)." €";
      break;
  }
}
add_action( "manage_disco-duro_posts_custom_column", "custom_columns", 10, 2 );

Haciendo las columnas ordenables

function sortable_columns() {
  return array(
    'title' => 'title',
    'manufacturer'      => 'manufacturer',
    'size' => 'size',
    'price'     => 'price'
  );
}
add_filter( "manage_edit-disco-duro_sortable_columns", "sortable_columns" );

Añadir filtros para las taxonomías

function taxonomy_filter_restrict_manage_posts() {
    global $typenow;

    if ( $typenow == 'disco-duro' ) {
    	$filters = get_object_taxonomies( $typenow );

        foreach ( $filters as $tax_slug ) {
            $tax_obj = get_taxonomy( $tax_slug );
            wp_dropdown_categories( array(
                'show_option_all' => __('Mostrar todos los '.$tax_obj->label ),
                'taxonomy' 	  => $tax_slug,
                'name' 		  => $tax_obj->name,
                'orderby' 	  => 'name',
                'selected' 	  => $_GET[$tax_slug],
                'hierarchical' 	  => $tax_obj->hierarchical,
                'show_count' 	  => false,
                'hide_empty' 	  => true
            ) );
        }
    }
}
add_action( 'restrict_manage_posts', 'taxonomy_filter_restrict_manage_posts' );

function taxonomy_filter_post_type_request( $query ) {
  global $pagenow, $typenow;

  if ( 'edit.php' == $pagenow ) {
    $filters = get_object_taxonomies( $typenow );
    foreach ( $filters as $tax_slug ) {
      $var = &$query->query_vars[$tax_slug];
      if ( isset( $var ) ) {
        $term = get_term_by( 'id', $var, $tax_slug );
        $var = $term->slug;
      }
    }
  }
}
add_filter( 'parse_query', 'taxonomy_filter_post_type_request' );

¡Y ya tenemos nuestro panel de control personalizado para nuestro tipo de dato personalizado!

Paso 5 – Plantillas

Supongo que estarás familiarizado con el desarrollo de plantillas en WordPress. Por si acaso no lo estás, te recomiendo revisar la jerarquía de plantillas, para saber cuáles tenemos que definir. En concreto podríamos definir estas:

  • Lista de discos duros.
  • Vista de un disco duro.
  • Lista de fabricantes de discos duros.
  • Vista de un fabricante de discos duros.
¿Cómo sabemos qué ficheros debemos editar o crear? Si revisamos el diagrama de la jerarquía de plantillas de WordPress, lo veremos muy claro:

Pero antes de nada; vamos a asegurarnos de que ya podemos acceder a las páginas de nuestros discos duros, y al listado. Da de alta un nuevo elemento de tipo disco duro y, una vez guardado, pulsa sobre “Ver disco duro”. Te llevará a una URL similar a www.example.com/disco-duro/nombre-del-disco-duro. Si te fijas en el diagrama, verás que se está utilizando el fichero de plantilla single.php. Del mismo modo, para acceder a la lista de discos duros (www.example.com/disco-duro/) se utiliza el fichero por defecto archive.php.

¿Errores 404?

Si te sale un error 404 – página no encontrada, prueba a ir a Ajustes > Enlaces permanentes > Guardar. Es simplemente para refrescar la configuración de reescritura de URLs.

Ahora si, por ejemplo, quisiéramos editar la vista de un disco duro, editaríamos single-disco-duro.php. Un buen punto de partida suele ser copiar y pegar el contenido del fichero single.php para después adaptarlo a las nuevas necesidades. Por ejemplo, así podría quedarte:

<?php get_header(); ?>

<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
    <?php $manufacturers = get_the_terms(get_the_ID(), 'fabricante');?>
	<?php $custom = get_post_custom(); ?>
	<h1 class="entry-title"><?php the_title(); ?></h1>
    <?php
    if ( has_post_thumbnail() ) {
      the_post_thumbnail();
    }
    ?>
	<h2>Fabricante: <?php foreach($manufacturers as $item) { echo $item->name; break; } ?></h2>
    <?php the_content(); ?>
    <p>
        Precio: <?php echo $custom['price'][0]; ?>€<br />
        Capacidad: <?php echo $custom['size'][0]; ?>GB<br />
        Velocidad: <?php echo $custom['speed'][0]; ?> rpm<br />
    </p>
<?php endwhile; // end of the loop. ?>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Y procederíamos de igual manera para editar las vistas de categorías o del listado de discos duros (archive-disco-duro.php).

Pero un momento… Nos hemos saltado la explicación de cómo utilizar en nuestras plantillas los valores de los campos personalizados. En general, para utilizar estos valores, tenemos cuatro funciones disponibles:

  1. get_post_custom() – Devuelve un array que, para cada clave (cada campo personalizado) contiene otro array con todos los valores que se le han asignado.
  2. get_post_custom_values() – Útil para cuando un campo personalizado tiene más de un valor. Devuelve un array con todos los valores que se le ha asignado.
  3. get_post_custom_keys() – Devuelve un array con los nombres de claves (campos personalizados) que hay en uso en un determinado post.
  4. get_post_meta() – Devuelve el valor de los campos personalizados que tengan el nombre indicado.

¡Y esto es todo! Con un poco de suerte, todo esto te será de tanta utilidad como a mí a la hora de desarrollar nuevas páginas en WordPress. Ya no estás limitado a Páginas y a Entradas. Y lo mejor de todo: se puede hacer casi sin tocar una línea de código.