Articles

La guía completa de los Custom Post Types de WordPress

Posted on
Daniel Pataki
Sobre el autor

Hola, Soy Daniel y hago cosas para la web. Soy el CTO en Kinsta y escribo para varias publicaciones increíbles como Smashing Magazine y …More aboutDaniel↬

  • 15 min de lectura
  • WordPress,Técnicas
  • Se puede guardar para leer sin conexión
  • Compartir en Twitter, LinkedIn
WordPress ha ido ganando terreno en el juego general de los CMS desde hace unos años, pero el verdadero avance fue el mecanismo de tipo de puesto personalizado que permite la creación de una amplia variedad de contenido. Vamos a echar un vistazo a cómo llegó a ser y todas las opciones que ofrece esta gran funcionalidad.

WordPress ha ido ganando terreno en el juego de los sistemas de gestión de contenidos (CMS) en general desde hace unos años, pero el verdadero avance fue el mecanismo de tipos de post personalizados que permite crear una gran variedad de contenidos. Echemos un vistazo a cómo surgió y a todas las opciones que ofrece esta gran funcionalidad.

wordpress custom post type
Algunos de los tipos de post personalizados que puedes crear en WordPress.

Cómo era antes

En la práctica, los custom post types existen desde hace mucho tiempo, más concretamente desde el 17 de febrero de 2005, cuando WordPress 1.5 añadió soporte para páginas estáticas, creando el campo de base de datos post_type.

Más lecturas en SmashingMag:

  • Ampliación de WordPress con tipos de contenido personalizados
  • Guía detallada de las plantillas de páginas personalizadas de WordPress
  • Personalización de los archivos de WordPress para categorías, etiquetas
  • Construcción de una página de archivos personalizada para WordPress
  • La función wp_insert_post() existe desde WordPress 1.0, por lo que cuando se implementó el campo post_type en la 1.5, simplemente se podía establecer el valor de post_type al insertar un post. Por supuesto, la creación y gestión de tipos de entradas personalizadas requería mucho más que eso, pero la cantidad de codificación necesaria fue disminuyendo a medida que las funciones de WordPress se volvían más y más flexibles.

    Para la versión 2.8, la función register_post_type() y algunas otras cosas útiles se añadieron a las compilaciones nocturnas, y cuando salió la 2.9, las funciones estuvieron disponibles para todos. En este punto, no se necesitaba una codificación extensa y hacks para hacer de WordPress un CMS completo; usted podría utilizar un montón de grandes funciones incorporadas para hacer que WordPress haga su voluntad.

    Lo que WordPress puede hacer por usted ahora

    Un tipo de post personalizado no es más que un post regular con un valor diferente post_type en la base de datos. El tipo de entrada de los posts normales es post, las páginas usan page, los archivos adjuntos usan attachment y así sucesivamente. Ahora puedes crear los tuyos propios para indicar el tipo de contenido creado. Podrías crear tipos de post personalizados para libros, películas, reseñas, productos y así sucesivamente.

    Si se crea correctamente, puedes lograr lo siguiente con unas pocas líneas de código:

    • El tipo de post personalizado se mostrará en el back end como un elemento de menú separado con su propia lista de post y página de «añadir nuevo»
    • Navegar a http://mysite.com/customposttype/ te llevará a la página de archivo para el tipo de post. Esto es similar a visitar la página de entrada para los últimos mensajes del tipo de post «post».
    • Las categorías y etiquetas pueden estar disponibles para el tipo de post personalizado, o puede crear taxonomías personalizadas.
      • Aparte de estos, puedes modificar innumerables opciones, como dónde debe colocarse el tipo de post personalizado en el menú, si debe ser buscable, qué nivel de usuario puede acceder a él, si debe ser jerárquico, reglas de reescritura personalizadas, etc.

        Los diferentes tipos de contenido tienen diferentes requisitos de datos. Para los posts regulares, querrás especificar el autor, la categoría, la fecha, etc. Para un tipo de post personalizado «libro», idealmente le gustaría tener la opción de especificar el autor del libro, el número de páginas, el género, la editorial y otros datos específicos del libro. Usando los meta boxes personalizados, esto se consigue fácilmente y se gestiona también.

        Los meta boxes personalizados te permiten añadir cajas adicionales a la pantalla de edición de un post. Por lo general, utilizan campos personalizados, por lo que podría simplemente utilizar campos personalizados también, pero al separar algunos campos personalizados como meta boxes, puede crear un admin mucho más suave y utilizable.

        Trabajando con tipos de post personalizados

        Para crear y utilizar eficazmente los tipos de post personalizados, necesitarás estar familiarizado con lo siguiente:

        • Crear tipos de post personalizados,
        • Crear taxonomías personalizadas,
        • Crear meta boxes personalizados.

        Creando tipos de post personalizados

        Lo primero en nuestra agenda es crear el propio tipo de post. Lo ideal es crear un plugin cuando se trabaja con tipos de post personalizados, pero si no sabes cómo, o simplemente necesitas una prueba rápida, puedes utilizar el archivo functions.php de tu tema.

function my_custom_post_product() { $args = array(); register_post_type( 'product', $args ); }add_action( 'init', 'my_custom_post_product' );

En su forma más simple, creará un tipo de post que no tiene casi ninguna personalización. No será público, no se mostrará en el admin, los mensajes de interacción serán los mismos que los posts («post guardado», «post actualizado», etc.) y así sucesivamente. Para adaptar nuestro nuevo tipo de post a nuestras necesidades, repasaré algunas de las opciones más utilizadas y las añadiré a la matriz $args previamente vacía.

function my_custom_post_product() { $labels = array( 'name' => _x( 'Products', 'post type general name' ), 'singular_name' => _x( 'Product', 'post type singular name' ), 'add_new' => _x( 'Add New', 'book' ), 'add_new_item' => __( 'Add New Product' ), 'edit_item' => __( 'Edit Product' ), 'new_item' => __( 'New Product' ), 'all_items' => __( 'All Products' ), 'view_item' => __( 'View Product' ), 'search_items' => __( 'Search Products' ), 'not_found' => __( 'No products found' ), 'not_found_in_trash' => __( 'No products found in the Trash' ), 'parent_item_colon' => ’, 'menu_name' => 'Products' ); $args = array( 'labels' => $labels, 'description' => 'Holds our products and product specific data', 'public' => true, 'menu_position' => 5, 'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ), 'has_archive' => true, ); register_post_type( 'product', $args ); }add_action( 'init', 'my_custom_post_product' );
  • labels La opción labels debe ser un array que defina las diferentes etiquetas que puede tener un custom post type. He separado esto arriba sólo para hacer los argumentos para registrar un tipo de post más claro.
  • description Una breve explicación de nuestro tipo de post personalizado; lo que hace y por qué lo estamos usando.
  • public Esta opción controla un montón de cosas en una sola vez. Si se pone a true, se pondrán a true un montón de otras opciones (todas relacionadas con la visibilidad). Por ejemplo, es posible tener el tipo de post personalizado visible pero no consultable. Más sobre esto más adelante.
  • menu_position Define la posición del menú de tipo de puesto personalizado en el back end. Si lo estableces en «5» lo colocas debajo del menú «posts»; cuanto más alto lo establezcas, más abajo se colocará el menú.
  • supports Esta opción configura los controles por defecto de WordPress que están disponibles en la pantalla de edición del tipo de post personalizado. Por defecto, sólo se muestran el campo de título y el editor. Si quieres añadir soporte para comentarios, revisiones, formatos de entrada y demás tendrás que especificarlos aquí. Para una lista completa echa un vistazo a la sección de argumentos en el Códice.
  • has_archive Si se establece en true, se crearán reglas de reescritura para ti, permitiendo un archivo de tipo de post en http://mysite.com/posttype/ (por defecto)
Un tipo de post personalizado en el menú.
Un tipo de post personalizado en el menú.

Después de configurar esto, deberías ver la entrada del menú para el tipo de post personalizado. Deberías poder añadir posts, ver la lista de posts en el admin y también visitar los posts publicados en el sitio web.

Como mencioné hay muchas cosas que puedes modificar al crear un post type. Sugiero mirar la lista de argumentos en el Codex para una descripción completa de cada opción y los posibles valores.

Mensajes de interacción personalizados

WordPress genera una serie de mensajes desencadenados por las acciones del usuario. Actualizar, publicar, buscar, etc., en el back-end, todo ello conduce a mensajes que -por defecto- se adaptan a los mensajes regulares. Puedes cambiar el texto de estos mensajes fácilmente utilizando el hook post_updated_messages.

function my_updated_messages( $messages ) { global $post, $post_ID; $messages = array( 0 => ’, 1 => sprintf( __('Product updated. <a href="%s">View product</a>'), esc_url( get_permalink($post_ID) ) ), 2 => __('Custom field updated.'), 3 => __('Custom field deleted.'), 4 => __('Product updated.'), 5 => isset($_GET) ? sprintf( __('Product restored to revision from %s'), wp_post_revision_title( (int) $_GET, false ) ) : false, 6 => sprintf( __('Product published. <a href="%s">View product</a>'), esc_url( get_permalink($post_ID) ) ), 7 => __('Product saved.'), 8 => sprintf( __('Product submitted. <a target="_blank" href="%s">Preview product</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), 9 => sprintf( __('Product scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview product</a>'), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ), 10 => sprintf( __('Product draft updated. <a target="_blank" href="%s">Preview product</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ), ); return $messages;}add_filter( 'post_updated_messages', 'my_updated_messages' );
Un mensaje personalizado tras guardar un producto.
Un mensaje personalizado después de guardar un producto.

Como puedes ver, este no es el método más fácil de gestionar los mensajes. Un array asociativo sería mucho mejor; podríamos ver para qué sirve cada mensaje sin tener que leer el mensaje real.

Nota que puedes cambiar los mensajes para todos los tipos de post personalizados usando esta única función. El array $messages contiene los mensajes para todos los tipos de post, así que puedes modificarlos todos aquí. Personalmente creo una función para cada tipo de post sólo para poder agrupar la creación del tipo de post y los mensajes personalizados fácilmente.

Ayuda contextual

Una característica que rara vez veo implementada es la ayuda contextual personalizada. Como usuario, en realidad nunca he utilizado esta característica, pero estoy seguro de que mucha gente lo hace; en cualquier caso, es bueno proporcionar un poco de ayuda para los usuarios menos experimentados.

La característica de ayuda contextual es una pestaña descendente que se puede ver en la parte superior derecha de las páginas donde está disponible. Echemos un vistazo a cómo se puede cambiar el contenido.

function my_contextual_help( $contextual_help, $screen_id, $screen ) { if ( 'product' == $screen->id ) { $contextual_help = '<h2>Products</h2> <p>Products show the details of the items that we sell on the website. You can see a list of them on this page in reverse chronological order - the latest one we added is first.</p> <p>You can view/edit the details of each product by clicking on its name, or you can perform bulk actions using the dropdown menu and selecting multiple items.</p>'; } elseif ( 'edit-product' == $screen->id ) { $contextual_help = '<h2>Editing products</h2> <p>This page allows you to view/modify product details. Please make sure to fill out the available boxes with the appropriate details (product image, price, brand) and <strong>not</strong> add these details to the product description.</p>'; } return $contextual_help;}add_action( 'contextual_help', 'my_contextual_help', 10, 3 );

Esto también es un poco difícil porque tienes que saber el ID de la pantalla en la que estás. Si imprimes el contenido de la variable $screen, deberías poder determinar el ID fácilmente. Esta es también una función que puedes utilizar para modificar la ayuda contextual de todos los custom post types a la vez, pero personalmente recomiendo agrupar esto junto con los dos bloques anteriores y utilizarlo sólo para un custom post type a la vez.

Resumen

Para recapitular rápidamente, hemos utilizado tres funciones para crear un custom post type «completo». Usamos register_post_type() para crear el tipo de post en sí mismo y dos hooks – contextual_help y post_updated_messages – para crear una guía útil y mensajes relevantes respectivamente.

Taxonomías personalizadas

Tus posts regulares del blog usan categorías y etiquetas para crear una estructura de organización. Sin embargo, la misma organización no tiene necesariamente sentido para los tipos de post personalizados. Las entradas de tu blog podrían ser sobre tu «Vida», tus «Pensamientos» o tus «Sueños». Estos obviamente no son apropiados para los productos.

Este es el problema que llevó a los desarrolladores a crear taxonomías personalizadas. Puedes crear una taxonomía separada llamada «Categorías de productos» para albergar las categorías que sólo utilizas para los productos. Kevin Leary escribió un gran artículo sobre las taxonomías personalizadas en WordPress que recomiendo encarecidamente, así que sólo entraré en detalles menores aquí.

function my_taxonomies_product() { $args = array(); register_taxonomy( 'product_category', 'product' $args );}add_action( 'init', 'my_taxonomies_product', 0 );

De forma similar a los tipos de entradas personalizadas, puedes crear una taxonomía muy fácilmente, pero necesitas trabajar en ella un poco para adaptarla a tus necesidades. Las taxonomías personalizadas se comportan un poco mejor fuera de la caja, ya que son públicas por defecto, por lo que lo anterior es realmente suficiente para atar esta taxonomía a los puestos de productos. Veamos un ejemplo personalizado.

function my_taxonomies_product() { $labels = array( 'name' => _x( 'Product Categories', 'taxonomy general name' ), 'singular_name' => _x( 'Product Category', 'taxonomy singular name' ), 'search_items' => __( 'Search Product Categories' ), 'all_items' => __( 'All Product Categories' ), 'parent_item' => __( 'Parent Product Category' ), 'parent_item_colon' => __( 'Parent Product Category:' ), 'edit_item' => __( 'Edit Product Category' ), 'update_item' => __( 'Update Product Category' ), 'add_new_item' => __( 'Add New Product Category' ), 'new_item_name' => __( 'New Product Category' ), 'menu_name' => __( 'Product Categories' ), ); $args = array( 'labels' => $labels, 'hierarchical' => true, ); register_taxonomy( 'product_category', 'product', $args );}add_action( 'init', 'my_taxonomies_product', 0 );

Como puedes ver, no ha cambiado mucho. Hemos añadido algunas etiquetas y hemos puesto la opción jerárquica en true. Esto habilita las taxonomías «estilo categoría». Cuando se establece en falso (esto es el valor predeterminado), su taxonomía será como las etiquetas por defecto.

Hay algunas otras opciones de poder disponibles que usted puede leer en el artículo de Leary, o puede ir a la entrada del Códice en register_taxonomy().

La taxonomía personalizada Categorías de productos.
La taxonomía personalizada Categorías de productos.

Meta Boxes

Los meta boxes son las cajas que se pueden arrastrar en la pantalla de edición de un post de WordPress. Hay numerosas cajas meta incorporadas como los controles de publicación, las taxonomías, la caja de autor, etc., pero puedes crear algunas por ti mismo.

Las cajas meta suelen utilizarse para gestionar los datos de los campos personalizados de una manera mucho más fácil de usar que lo que hace la caja de campos personalizados incorporada. Ya que usted pone los controles en su lugar, puede agregar la comprobación de errores del lado del cliente y muchas otras cosas de fantasía.

Justin Tadlock escribió el artículo de meta caja personalizada que lo abarca todo aquí en Smashing Magazine, que es un gran artículo en profundidad sobre el tema. Recomiendo leerlo para obtener la imagen completa, pero voy a empezar aquí.

Crear una meta caja requiere tres pasos:

  • Definir la propia caja,
  • Definir el contenido de la meta caja,
  • Definir cómo se manejan los datos de la caja.

Definiendo la meta caja

add_action( 'add_meta_boxes', 'product_price_box' );function product_price_box() { add_meta_box( 'product_price_box', __( 'Product Price', 'myplugin_textdomain' ), 'product_price_box_content', 'product', 'side', 'high' );}

El código anterior crea la meta caja con los siguientes parámetros (en el orden indicado):

  • El identificador único para la meta caja (no tiene que coincidir con el nombre de la función),
  • El título de la meta caja (visible para los usuarios),
  • La función que mostrará el contenido de la caja,
  • El tipo de post al que pertenece la meta caja,
  • La colocación de la meta caja,
  • La prioridad de la meta caja (determina «cuán alto» se coloca).

Definiendo el contenido de la meta caja

function product_price_box_content( $post ) { wp_nonce_field( plugin_basename( __FILE__ ), 'product_price_box_content_nonce' ); echo '<label for="product_price"></label>'; echo '<input type="text" name="product_price" placeholder="enter a price" />';}

Se trata de una caja sencilla que sólo contiene el precio, por lo que hemos creado una etiqueta y un input para gestionarla. También está presente un campo nonce, que añade seguridad al envío de datos.

Manejo de los datos enviados

En la mayoría de los casos, querrás guardar los datos como un campo personalizado, pero no estás en absoluto limitado a este método. Podrías usar la entrada para hacer una llamada a la API de un tercero, para generar un archivo XML o lo que quieras. El uso más común es guardar los datos de la entrada personalizada, así que vamos a echar un vistazo a cómo se hace.

add_action( 'save_post', 'product_price_box_save' );function product_price_box_save( $post_id ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( !wp_verify_nonce( $_POST, plugin_basename( __FILE__ ) ) ) return; if ( 'page' == $_POST ) { if ( !current_user_can( 'edit_page', $post_id ) ) return; } else { if ( !current_user_can( 'edit_post', $post_id ) ) return; } $product_price = $_POST; update_post_meta( $post_id, 'product_price', $product_price );}

La mayor parte de esta función es todo acerca de la seguridad. En primer lugar, si se está realizando un autoguardado, no pasa nada porque el usuario no ha enviado realmente el formulario. Luego se comprueba el nonce, seguido de la comprobación de permisos. Si todo esto se pasa, tomamos nuestros datos y los añadimos al post usando la función update_post_meta().

Un ejemplo de meta box para un post tipo apartamento.
Un ejemplo de meta box para un tipo de post de apartamento.

Mostrando tu contenido

Aunque hay un montón de matices en todo lo anterior, deberías estar familiarizado con lo básico. Todo lo que queda es utilizar realmente los datos que tenemos ahora y mostrar las cosas al usuario. Esto implica mostrar las entradas -quizás de varios tipos de entradas y taxonomías personalizadas- y utilizar nuestros metadatos de las entradas.

Mostrando entradas

Si has creado un tipo de entrada con el parámetro has_archive configurado como «true», WordPress mostrará tus entradas en la página de archivo del tipo de entrada. Si tu tipo de entrada se llama «libros», puedes simplemente ir a http://mysite.com/books/ y verás tu lista de entradas.

Esta página utiliza archive-.php para la visualización si existe (archive-books.php en nuestro caso). Si no existe, utilizará archive.php y si no existe utilizará index.php.

Otra forma de mostrar el contenido del post type personalizado es utilizar una consulta personalizada con la clase WP_Query. Para mostrar los posts de un determinado tipo de post y taxonomía personalizada, podrías hacer algo como esto:

<?php $args = array( 'post_type' => 'product', 'tax_query' => array( array( 'taxonomy' => 'product_category', 'field' => 'slug', 'terms' => 'boardgames' ) ) ); $products = new WP_Query( $args ); if( $products->have_posts() ) { while( $products->have_posts() ) { $products->the_post(); ?> <h1><?php the_title() ?></h1> <div class='content'> <?php the_content() ?> </div> <?php } } else { echo 'Oh ohm no products!'; } ?>

Mostrando Metadatos

Los metadatos pueden ser recuperados fácilmente usando la función get_post_meta(). En nuestro ejemplo anterior, hemos guardado un campo meta del post llamado product_price. Podemos recuperar el valor de este campo para un post dado usando el siguiente código:

<?php // If we are in a loop we can get the post ID easily $price = get_post_meta( get_the_ID(), 'product_price', true ); // To get the price of a random product we will need to know the ID $price = get_post_meta( $product_id, 'product_price', true );?>

Palabras finales

Como puedes ver, crear un CMS es bastante fácil debido a la naturaleza modular de los controles y funciones de WordPress. Los métodos descritos aquí se pueden utilizar extremadamente bien para crear admins personalizados para casi cualquier cosa que se te ocurra.

Dado que la definición del contenido de los meta boxes depende completamente de ti, tienes el poder de crear características adicionales para tus controles, haciéndote a ti o a tus clientes muy felices.

Puedes llevar esto un paso más allá con páginas de admins personalizadas y contenido completamente personalizado, pero esa es una historia para otro día.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *