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:
- Entradas – Es el tipo predeterminado, para alojar nuevas entradas tipo blog.
- Páginas – Las páginas permanentes, fuera de la estructura cronológica de los posts.
- Adjuntos- Corresponde a la página que hay disponible para cada fichero adjunto.
- Revisiones – Una revisión es una versión antigua de otro documento, o un borrador.
- 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:
- Enganchamos la función “register_dd()” al evento “init”, dándole alta prioridad (cuanto más bajo, más prioritario).
- Definimos la función register_dd():
- Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de post.
- Creamos otro array con todas las opciones:
- labels – Por un lado, asignamos las etiquetas.
- public – Le damos visibilidad pública.
- hierarchical – No es un tipo de post jerárquico, donde pueda tener un post padre.
- menu_position – Introduciendo 5 hacemos que se muestre bajo el menú de entradas.
- has_archive – Permitimos acceder al archivo (listado) de discos duros.
- query_var – Indicamos que se podrán hacer consultas atacando a este tipo de post.
- 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.
- rewrite – Indicamos el nombre base que tendrán las URLs amigables.
- 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?
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’.
- 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:
- Categorías – Las categorías que ya has usado para clasificar tus artículos.
- Etiquetas – Etiquetas (palabras clave) que añades a cada artículo.
- 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:
- Atamos la función ‘register_df’()’ al evento ‘init’, de nuevo con alta prioridad.
- Definimos la función register_df():
- Creamos un array $labels con todas las etiquetas que acompañarán al panel de control de este nuevo tipo de taxonomía.
- Creamos otro array con todas las opciones:
- hierarchical – Es un tipo de taxonomía jerárquica. Por ejemplo, las categorías son jerárquicas, mientras que las etiquetas no lo son.
- public – Le damos visibilidad pública.
- labels – Por un lado, asignamos las etiquetas.
- show_ui – Indicamos que se mostrará la interfaz de usuario en el panel de control para gestionarlas.
- rewrite – Nos permite redefinir la estructura de las URLs dinámicas con las que se accede a cada fabricante.
- query_var – Permite realizar consultas SQL atacando a esta taxonomía.
- Finalmente, damos de alta el tipo de taxonomía, a la que llamamos ‘fabricantes’, y la vinculamos al tipo de post ‘discosduros’.
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
- 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.
Paso 3 – Añadir nuevos campos
- Nombre.
- Descripción.
- Imagen.
- Fabricante.
- Precio.
- Capacidad.
- 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
Capacidad
Introducimos estos valores:
- Field title - Capacidad.
- Custom field key - size.
- Caption - Introduzca la capacidad del disco duro en GigaBytes.
- Field type - Number
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:
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.
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:
- 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.
- 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.
- get_post_custom_keys() – Devuelve un array con los nombres de claves (campos personalizados) que hay en uso en un determinado post.
- 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.
el tema de lis filtros no funcionan, cuando seleccionas una categoria no te muestra solo los posts de esa categoria
Excelente!! gracias por este tuto, me sirvió un montón.
GRACIASS!!!!!!!!!!!!!!!
excelente post, muy buena explicacion, gracias.
Hola, este es un de los mejores tutoriales que he visto, aunque tengo una duda
yo quiero crear por ejemplo entradas personalizadas llamada “Noticias” que contenga 3 categorias
Noticias
Cultura
Tecnologia
Entretencion
_________________
La idea es que cuando el “editor” entre a alguna de las
categorias en este caso a cultura, pueda crear la noticia rapidamente
(sin agregar metatag, ni elegir categorias) la idea es que el enlace
permanente sea
wwww.miweb.com/noticias/cultura/nombre-de-la-entrada
Es posible?
Atento a los comentarios
Hola Juan Pablo
Gracias por tu comentario.
Para hacer lo que señalas puedes utilizar directamente las “Entradas” y “Categorías” que ofrece WordPress. Luego, desde el menú “Ajustes” > “Enlaces permanentes”, puedes definir la estructura de URLs personalizada que quieres usar.
Cuando un editor añada una noticia (entrada), tan solo deberá seleccionar una de entre las 3 categorías disponibles, y con eso ya está.
Pero si lo que quieres es evitar ese “clic” de seleccionar categoría, y que directamente añadan una noticia con la categoría ya seleccionada, lo cierto es que no se me ocurre ninguna forma elegante.
Hola, he encontrado tu post y es genial esto ante todo.
Soy nuevo en el tema wordpress y estaba buscando algo parecido, este post me ha encaminado para hacer lo que estoy buscando pero al mismo tiempo han surguido más dudas. Me explico, tengo una estructura similar a la siguiente:
1. NIEVE
1.1. Lugar Estación (Andorra)
1.1.1. Estación (GRANDVALIRA)
1.1.1.1. Precio (input number)
1.1.1.2. Duración viaje (select)
1.1.1.3. Apto para (Primaria, ESO, Bachiller) (input text)
1.1.1.4. Tabs información (No se si hacerlo programado o ponerlo desde un plugin)
2.1. Lugar Estación (Andorra)
2.1.1. Estación (VALLNORD)
2.1.1.1. Precio (input number)
2.1.1.2. Duración viaje (select)
2.1.1.3. Apto para (Primaria, ESO, Bachiller) (input text)
2.1.1.4. Tabs información (No se si hacerlo programado o ponerlo desde un plugin)
etc….
Bueno, dentro de cada estación habrán varios packs tengo claro que el precio, duración, apto, lo voy a desarrollar como explicabas.
Pero mi duda la siguiente, creo un nuevo tipo de post que se llame nieve, y habilito las categorias y dento de ahi anido la estación.
El problema viene porque quiero hacer busquedas de listas anidadas, que cuando seleccione andorra, luego salgan en otro campo solo sus estaciones.
Es así de la forma que tengo que proceder o hay una forma más sencilla. No se si me estoy liando yo solo.
Gracias, de antemano
Hola Juan
Supongo que depende de cómo lo quieras implementar; es decir, con recarga de página o sin ella (JavaScript).
Si lo haces con recarga de página, te diría que una vez que el usuario seleccione una categoría, se le redirija a la página de la propia categoría (taxonomía). Y una vez en esta página, muestras el desplegable para elegir el post en concreto. Es la forma más sencilla.
Si lo quieres de forma dinámica, sin recargar toda la página, a priori veo dos enfoques: o (1) hacer tú mismo la consulta para cargar todas las categorías y estaciones en un objeto JSON dentro de la propia petición (poco escalable), o (2) hacerlo igual pero de forma asíncronona: cuando el usuario elige categoría, realizas una petición AJAX a tu plugin/plantilla y que te devuelva un objeto JSON con las estaciones de la categoría.
¡Espero haberte sido de ayuda!
Hola Jesús,
Gracias por contestar, mi decisión es hacerlo con ajax para cuando en el buscador se seleccione un lugar de la estación salgan solo las estaciones pertenecientes a ella para seleccionar y además que tengan contenido.
Sobre la estructura para organizar los contenidos te parece correcta la que comentaba??
Para Nieve (un nuevo tipo de post), lugar de la estación (categoria), estación (subcategoria), y las caracteristicas(precio, duración, apto, tabs) son los fields.
Gracias por la ayuda
Otra pregunta que me ha sugido al largo del día, si yo quiero utilizar el campo duración, por ejemplo, que lo he creado mediente More fields y quiero despues utilizarlo en un buscador para acotar la entrada que quiero funcionara o deberia ponerlo como una taxonomia??? Igual que si quisiera buscar mediante el precio, funcionaria…???
Gracias por todo.