¡Hola de nuevo! En la programación hay que mantenerse al día, no nos podemos quedar estancados. Así que ya estoy por aquí de nuevo jugueteando con WordPress, poniéndome al día, para traer este howto. Hoy traigo este codekata para montar un sistema de administración para la información que quieras para WordPress.
Vamos al grano..
Comenzando, qué son los custom post types?
Antes de nada, saber que WordPress es un CMS, un gestor de contenidos, que inicialmente se creó para construir blogs. Por esto que el elemento básico son los posts, que son elementos de tipo ‘post’. Después se crearon los elementos de tipo ‘page’, que son las páginas estáticas, que simplemente son lo mimo pero sin fechas y alguna otra cosa.
Pues este mismo sistema para crear tipos de posts, nos sirve para crear los elementos que queramos. Así podemos aumentar las funcionalidades del WordPress en el que estemos trabajando.
Por ejemplo, podemos querer crear un custom post type para opciones como:
- Descargas.
- Productos.
- Días festivos.
- Próximas promociones u ofertas.
- Equipo de trabajo de la compañía.
- Lugares en donde hay locales.
- Etcétera..
Estos tipos de posts tendrán su sección en el panel de administración. Se podrán añadir elementos, listar, ordenar, editar, etiquetar, categorizar, mostrar en el frontend de forma personalizada, ponerle campos de edición de su información personalizada. Etcétera..
Después dejo unos códigos fuentes para hacer esto..
Qué son las categorías
A estos tipos de posts personalizados, podemos a su vez categorizarlos. Podemos categorizarlos de forma que estas categorías engloben a varios posts, tengan unas categorías aparte o compartidas con los tipos de posts.
Las categorías tienen de especial que se pueden organizar jerárquicamente en forma de árbol.
Qué son las etiquetas o tags
Al uso, las etiquetas o tags, son lo mismo que las categorías pero se diferencian en que no se pueden organizar jerárquicamente. De forma que simplemente se pueden asociar un conjunto de etiquetas a cada elemento de un tipo de post.
Estos tags y las categorías son lo que pertenece a lo llamado en WordPress las taxonomías. Después dejo unos códigos fuentes de uso de esto.
Qué son los campos personalizados
Los campos personalizados son campos extra que cada tipo de post puede tener. Se pueden asociar a cada item de un tipo, de forma que incluso se pueden usar en forma de ficha como en la imagen del principio.
Hay plugins para un manejo más automático como por ejemplo, sobre el escribí en un post anterior sobre campos personalizados y el ACF.
Qué son los metabox
Finalmente como explicaciones necesarias antes de entrar al código fuente, quedan los metabox. Son las cajas que aparecen a la derecha y bajo de cada post, de cada página, o de cada tipo de post personalizado.
Por ejemplo la caja lateral donde se definen las categorías de un post es un metabox. También están en metaboxes la imagen destacada, los tags, etc.. y numerosas configuraciones o datos que añaden muchos plugins para sus funcionalidades.
Cómo dar de alta un tipo de post nuevo
Al grano entonces, un custom post type de ejemplo para protectoras de animales que tengan mascotas en adopción podría ser algo como lo siguiente. En un plugin se podría llamar a una función que creara todo junto así:
add_action('init', 'create_custom_post_type');
Esta función podría ser algo tal que así:
public function create_custom_post_type()
{
$category_labels = [
'name' => 'Categories',
'singular_name' => 'Category',
'menu_name' => 'Categories',
'all_items' => 'All categories',
'edit_item' => 'Edit category',
'view_item' => 'View category',
'update_item' => 'Update category',
'add_new_item' => 'Add category',
'new_item_name' => 'New category name',
'parent_item' => null,
'parent_item_colon' => null,
'search_items' => 'Search categories',
'popular_items' => 'Popular categories',
'separate_items_with_commas' => 'Separate items with commas',
'add_or_remove_items' => 'Add or remove items',
'choose_from_most_used' => 'Choose from most used',
'not_found' => 'Not found',
'back_to_items' => 'Back to items',
];
register_taxonomy('saitems_category', ['saitem'], [
'labels' => $category_labels,
'hierarchical' => true, // false like tags, true like categories
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
]);
$tag_labels = [
'name' => 'Taxonomies',
'singular_name' => 'Taxonomy',
'menu_name' => 'Taxonomies',
'all_items' => 'All taxonomies',
'edit_item' => 'Edit taxonomy',
'view_item' => 'View taxonomy',
'update_item' => 'Update taxonomy',
'add_new_item' => 'Add taxonomy',
'new_item_name' => 'New taxonomy name',
'parent_item' => null,
'parent_item_colon' => null,
'search_items' => 'Search taxonomies',
'popular_items' => 'Popular taxonomies',
'separate_items_with_commas' => 'Separate items with commas',
'add_or_remove_items' => 'Add or remove items',
'choose_from_most_used' => 'Choose from most used',
'not_found' => 'Not found',
'back_to_items' => 'Back to items',
];
register_taxonomy('saitems_taxonomy', ['saitem'], [
'labels' => $tag_labels,
'hierarchical' => false, // false like tags, true like categories
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
]);
$post_type_labels = [
'name' => 'Animals',
'singular_name' => 'animal',
'add_new' => 'Add animal',
'add_new_item' => 'Add new animal',
'edit_item' => 'Edit animal',
'new_item' => 'New animal',
'view_item' => 'View animal',
'search_items' => 'Search animal',
'not_found' => 'Animal not found',
'not_found_in_trash' => 'Animals not found in trash',
'parent_item_colon' => '',
];
$args = [
'label' => 'Services Animals',
'labels' => $post_type_labels,
'description' => 'Services Animals..',
'public' => false,
'hierarchical' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'show_in_rest' => false,
//'rest_base' => 'post_type',
//'rest_controller_class' => 'WP_REST_Posts_Controller',
'menu_position' => 40,
'menu_icon' => 'dashicons-admin-tools',
'capability_type' => 'post',
'capabilities' => ['edit_post', 'read_post', 'delete_post', 'edit_posts', 'edit_others_posts',
'delete_posts', 'publish_posts', 'read_private_posts', ],
'map_meta_cap' => true,
/*'supports' => [
'title',
'editor',
'comments',
'revisions',
'trackbacks',
'author',
'excerpt',
'page-attributes',
'thumbnail',
'custom-fields',
'post-formats',
],*/
'supports' => ['title', 'editor'],
'register_meta_box_cb' => null, //'register_meta_box_cb' => [$this, 'sa_metabox_add'],
'taxonomies' => ['saitems_category', 'saitems_taxonomy'],
'has_archive' => false,
'rewrite' => true, //'rewrite' => ['slug' => 'saitem', 'with_front' => true],
'slug' => 'saitem',
'with_front' => true,
'feeds' => true,
'pages' => true,
//'ep_mask' => EP_PERMALINK,
//'query_var' => 'saitem',
//'can_export' => true,
//'delete_with_user' => false,
'_builtin' => false,
//'_edit_link' => 'post.php?post=%d',
];
register_post_type('saitem', $args);
}
He puesto todo junto, luego desgloso lo que son tags y categorías.
Cómo dar de alta taxonomías de tipo categorías o de tipo etiqueta
Al grano, la parte del código anterior que crea dos taxonomias, una de tipo etiqueta/tag y otra de tipo de categoría es la parte inicial del código anterior. Por ejemplo para las categorías es:
$category_labels = [
'name' => 'Categories',
'singular_name' => 'Category',
'menu_name' => 'Categories',
'all_items' => 'All categories',
'edit_item' => 'Edit category',
'view_item' => 'View category',
'update_item' => 'Update category',
'add_new_item' => 'Add category',
'new_item_name' => 'New category name',
'parent_item' => null,
'parent_item_colon' => null,
'search_items' => 'Search categories',
'popular_items' => 'Popular categories',
'separate_items_with_commas' => 'Separate items with commas',
'add_or_remove_items' => 'Add or remove items',
'choose_from_most_used' => 'Choose from most used',
'not_found' => 'Not found',
'back_to_items' => 'Back to items',
];
register_taxonomy('saitems_category', ['saitem'], [
'labels' => $category_labels,
'hierarchical' => true, // false like tags, true like categories
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
]);
Y para las etiquetas:
$tag_labels = [
'name' => 'Taxonomies',
'singular_name' => 'Taxonomy',
'menu_name' => 'Taxonomies',
'all_items' => 'All taxonomies',
'edit_item' => 'Edit taxonomy',
'view_item' => 'View taxonomy',
'update_item' => 'Update taxonomy',
'add_new_item' => 'Add taxonomy',
'new_item_name' => 'New taxonomy name',
'parent_item' => null,
'parent_item_colon' => null,
'search_items' => 'Search taxonomies',
'popular_items' => 'Popular taxonomies',
'separate_items_with_commas' => 'Separate items with commas',
'add_or_remove_items' => 'Add or remove items',
'choose_from_most_used' => 'Choose from most used',
'not_found' => 'Not found',
'back_to_items' => 'Back to items',
];
register_taxonomy('saitems_taxonomy', ['saitem'], [
'labels' => $tag_labels,
'hierarchical' => false, // false like tags, true like categories
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
]);
Cómo dar de alta campos personalizados
Mucha información dentro de la BD de WordPress se organiza a base de metadata. Si miramos por ejemplo los metadatos para los post, tenemos dos tablas para esto principalmente: wp_posts y wp_postmeta. Estos campos personalizados normales, junto con muchas configuraciones de cada post, acaban almacenándose en esta tabla wp_postmeta.
Luego con el metabox se puede consultar y actualizar estos valores para cada post personalizado, usando las funciones: get_post_meta y update_post_meta.
También se pueden dar de alta de forma manual y usar estos campos personalizados en el backend de WordPress. Sobre esta forma manual escribí un post anteriormente. En el siguiente apartado, mediante el metabox dejo código fuente para usar estos campos.
Cómo dar de alta una metabox y actualizar los campos
Finalmente, una forma para dar de alta 2 procesos, la visualización y el guardado de los datos de un metabox se puede hacer con las funciones siguientes:
add_action('add_meta_boxes', 'sa_metabox_add'); add_action('save_post', 'sa_metabox_save');
La función add_meta_boxes pinta en el momento adecuado la caja del metabox en el lugar adecuado, cuando corresponde. Por ejemplo:
function sa_metabox_add()
{
add_meta_box(
'saitem_metabox_id',
'Services Animals',
'sa_metabox_view',
'saitem',
'normal',
'default'
);
}
function sa_metabox_view($post)
{
$sa_custom_fields = [
'name' => 'text',
'description' => 'text',
'type' => 'text',
'specie' => 'text',
'breed' => 'text',
'birthdate' => 'text',
'created_at' => 'text',
'updated_at' => 'text',
'gender' => 'text',
'adopter_id' => 'text',
'internal_id' => 'text',
'public_phone_number' => 'text',
'public_email' => 'text',
'share_counter' => 'text',
'number_of_offspring' => 'text',
];
foreach ($sa_custom_fields as $key => $type) {
$$key = get_post_meta($post->ID, $key, true);
}
wp_nonce_field('sa_nonce_metabox_action', 'sa_nonce_metabox_name');
include SA_PATH.'view/metabox.php';
}
La primera parte de lo anterior declara unas variables para almacenar los valores de los custom fields. Si todavía no se han guardado estarán vacíos. para acto seguido pintar la vista del plugin para el metabox en view/metabox.php. Luego dejo enlace a todo el código fuente junto.
El contenido para la función de guardado es muy parecido:
public function sa_metabox_save($post_id)
{
if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
or !isset($_POST['sa_nonce_metabox_name'])
or !wp_verify_nonce($_POST['sa_nonce_metabox_name'], 'sa_nonce_metabox_action')
or !current_user_can('edit_post')) {
return;
}
$sa_custom_fields = [
'name' => 'text',
'description' => 'text',
'type' => 'text',
'specie' => 'text',
'breed' => 'text',
'birthdate' => 'text',
'created_at' => 'text',
'updated_at' => 'text',
'gender' => 'text',
'adopter_id' => 'text',
'internal_id' => 'text',
'public_phone_number' => 'text',
'public_email' => 'text',
'share_counter' => 'text',
'number_of_offspring' => 'text',
];
foreach ($sa_custom_fields as $key => $type) {
if ('text' == $type) {
update_post_meta($post_id, $key, sanitize_text_field($_POST[$key]));
}
}
}
Terminando
Para terminar con todo este post sólo me queda remitirte a la documentación oficial para que puedas seguir avanzando con el tema:
https://developer.wordpress.org/plugins/
Un plugin completo que hace todo lo del post sería como el siguiente:
https://github.com/jaimenj/services-animals-wp
..y el resultado sería como el de la imagen del principio.