Plantillas personalizadas para taxonomías de Custom Post Types en WordPress
He creado un Custom Post Type llamado "Ad" (Anuncio) y luego una taxonomía bajo ese tipo llamada "type" (tipo). He añadido algunos términos en la categoría Type como "Radio", "TV", "Print" (Impreso).
Me gustaría que WordPress use una plantilla single.php
diferente para cada término. Quiero tener una plantilla para Radio que sea diferente a la de Print.
He probado con taxonomy-ad-type-radio.php
, también con single-ad-type-radio.php
y todas las variantes posibles. ¿Alguien puede decirme cuál es la mejor manera de lograr esto?
También he añadido filtros en mi archivo functions.php
sin éxito. Sé que debo estar pasando por alto algo muy simple. Muchas gracias por su ayuda.
<?php
/** Registrar el tipo de contenido para los anuncios **/
add_action( 'init', 'register_cpt_ad' );
function register_cpt_ad() {
$labels = array(
'name' => _x( 'Anuncios', 'ad' ),
'singular_name' => _x( 'Anuncio', 'ad' ),
'add_new' => _x( 'Añadir nuevo', 'ad' ),
'add_new_item' => _x( 'Añadir nuevo anuncio', 'ad' ),
'edit_item' => _x( 'Editar anuncio', 'ad' ),
'new_item' => _x( 'Nuevo anuncio', 'ad' ),
'view_item' => _x( 'Ver anuncio', 'ad' ),
'search_items' => _x( 'Buscar anuncios', 'ad' ),
'not_found' => _x( 'No se encontraron anuncios', 'ad' ),
'not_found_in_trash' => _x( 'No se encontraron anuncios en la papelera', 'ad' ),
'parent_item_colon' => _x( 'Anuncio padre:', 'ad' ),
'menu_name' => _x( 'Anuncios', 'ad' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => 'Sistema de anuncios',
'supports' => array( 'title', 'excerpt', 'editor', 'thumbnail', 'custom-fields' ),
'taxonomies' => array( 'category', 'type', 'campaign', 'post_tag' ),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'menu_position' => 3,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post'
);
register_post_type( 'ad', $args );
}
/** Registrar la taxonomía para los tipos de anuncio **/
add_action( 'init', 'register_taxonomy_type' );
function register_taxonomy_type() {
$labels = array(
'name' => _x( 'Tipo de Anuncio', 'type' ),
'singular_name' => _x( 'Tipos de Anuncio', 'type' ),
'search_items' => _x( 'Buscar tipo de anuncio', 'type' ),
'popular_items' => _x( 'Tipos de anuncio populares', 'type' ),
'all_items' => _x( 'Todos los tipos de anuncio', 'type' ),
'parent_item' => _x( 'Tipo de anuncio padre', 'type' ),
'parent_item_colon' => _x( 'Tipo de anuncio padre:', 'type' ),
'edit_item' => _x( 'Editar tipo de anuncio', 'type' ),
'update_item' => _x( 'Actualizar tipo de anuncio', 'type' ),
'add_new_item' => _x( 'Añadir nuevo tipo de anuncio', 'type' ),
'new_item_name' => _x( 'Nuevo tipo de anuncio', 'type' ),
'separate_items_with_commas' => _x( 'Separar tipos de anuncio con comas', 'type' ),
'add_or_remove_items' => _x( 'Añadir o eliminar tipos de anuncio', 'type' ),
'choose_from_most_used' => _x( 'Elegir entre los tipos de anuncio más usados', 'type' ),
'menu_name' => _x( 'Tipo de Anuncio', 'type' ),
);
$args = array(
'labels' => $labels,
'public' => true,
'show_in_nav_menus' => true,
'show_ui' => true,
'show_tagcloud' => true,
'hierarchical' => true,
'rewrite' => true,
'query_var' => true
);
register_taxonomy( 'type', array('ad'), $args );
}
/** Registrar la taxonomía para las campañas **/
add_action( 'init', 'register_taxonomy_campaign' );
function register_taxonomy_campaign() {
$labels = array(
'name' => _x( 'Campañas', 'campaign' ),
'singular_name' => _x( 'Campaña', 'campaign' ),
'search_items' => _x( 'Buscar campañas', 'campaign' ),
'popular_items' => _x( 'Campañas populares', 'campaign' ),
'all_items' => _x( 'Todas las campañas', 'campaign' ),
'parent_item' => _x( 'Campaña padre', 'campaign' ),
'parent_item_colon' => _x( 'Campaña padre:', 'campaign' ),
'edit_item' => _x( 'Editar campaña', 'campaign' ),
'update_item' => _x( 'Actualizar campaña', 'campaign' ),
'add_new_item' => _x( 'Añadir nueva campaña', 'campaign' ),
'new_item_name' => _x( 'Nueva campaña', 'campaign' ),
'separate_items_with_commas' => _x( 'Separar campañas con comas', 'campaign' ),
'add_or_remove_items' => _x( 'Añadir o eliminar campañas', 'campaign' ),
'choose_from_most_used' => _x( 'Elegir entre las campañas más usadas', 'campaign' ),
'menu_name' => _x( 'Campañas', 'campaign' ),
);
$args = array(
'labels' => $labels,
'public' => true,
'show_in_nav_menus' => true,
'show_ui' => true,
'show_tagcloud' => true,
'hierarchical' => true,
'rewrite' => true,
'query_var' => true
);
register_taxonomy( 'campaign', array('ad'), $args );
}
function query_post_type($query) {
$post_types = get_post_types();
if ( is_category() || is_tag()) {
$post_type = get_query_var('ad');
if ( $post_type ) {
$post_type = $post_type;
} else {
$post_type = $post_types;
}
$query->set('post_type', $post_type);
return $query;
}
}
add_filter('pre_get_posts', 'query_post_type');
/* NUEVAS FUNCIONALIDADES */
// Registrar la columna
function price_column_register( $columns ) {
$columns['level'] = __( 'Nivel de Usuario', 'my-plugin' );
return $columns;
}
add_filter( 'manage_edit-ad_columns', 'price_column_register' );
// Mostrar el contenido de la columna
function price_column_display( $column_name, $post_id ) {
if ( 'level' != $column_name )
return;
$roles = get_post_meta( $post->ID, '_members_access_role', true );
if ($roles == 'level1') echo 'level1';
echo 'hola';
}
add_action( 'manage_posts_custom_column', 'price_column_display', 10, 2 );
/**
* Añadir los términos de múltiples taxonomías a la lista
* de clases generadas por post_class().
*
* @since 2010-07-10
* @alter 2012-01-06
*/
function mysite_post_class( $classes, $class, $ID ) {
$taxonomies = array(
'type',
'campaign',
);
$terms = get_the_terms( (int) $ID, $taxonomies );
if ( is_wp_error( $terms ) || empty( $terms ) )
return $classes;
foreach ( (array) $terms as $term ) {
if ( ! in_array( $term->slug, $classes ) )
$classes[] = $term->slug;
}
return $classes;
}
add_filter( 'post_class', 'mysite_post_class', 10, 3 );
add_filter( 'tpicker_taxonomies', 'my_tpicker_taxonomies' );
function my_tpicker_taxonomies( $old_taxies) { // Filtrar orden de taxonomías
foreach( array("Categorías ", "Campañas ", "Tipo de Anuncio " ) as $tax_label) {
$new_taxies[$tax_label] = $old_taxies[$tax_label];
}
return $new_taxies;
}
Creo que estás pasando por alto algunos conceptos o no los entiendes completamente.
- Una taxonomía es una forma de agrupar cosas, es decir, publicaciones. La misma taxonomía puede usarse para varios tipos de publicaciones, por lo que una taxonomía no está bajo una publicación.
- Los archivos de plantilla
single
se usan para la vista de una publicación individual. Puedes crear una plantilla single diferente para cada tipo de publicación, incluso para cada publicación individual. - La plantilla específica para un término de una taxonomía es
taxonomy-{tu_taxonomía}-{término}.php
, en tu caso, sería por ejemplotaxonomy-type-radio.php
. Esta plantilla mostrará todas las publicaciones dentro del término radio de la taxonomía 'type'.
Creo que lo que realmente quieres es usar una plantilla single
diferente basada en el término de la taxonomía "type" asociado a una publicación de 'Ad'. Asumo que solo se puede seleccionar un término de la taxonomía 'type' por publicación. Puedes usar el filtro template_include, o más específicamente, el filtro single_template:
<?php
function get_custom_single_template($single_template) {
global $post;
if ($post->post_type == 'ad') {
$terms = get_the_terms($post->ID, 'type');
if($terms && !is_wp_error( $terms )) {
//Hacer un foreach porque $terms es un array pero se supone que solo hay un término
foreach($terms as $term){
$single_template = dirname( __FILE__ ) . '/single-'.$term->slug.'.php';
}
}
}
return $single_template;
}
add_filter( "single_template", "get_custom_single_template" ) ;
?>
Coloca esto en el archivo functions.php de tu tema. No olvides crear los archivos single-*.php para cada término (single-radio.php, single-tv.php, etc).
Si no necesitas un archivo de plantilla completo y solo requieres pequeñas modificaciones, como diferentes clases CSS, puedes verificar si la publicación tiene el término y asignar una clase diferente. Por ejemplo, en una plantilla single común:
<div class="<?php echo class="<?php echo has_term( 'radio', 'type' ) ? 'radio' : ''; ?>">
<?php the_cotent();?>
</div>
O
<?php
$terms = get_the_terms($post->ID, 'type');
$class = '';
//Hacer un foreach porque $terms es un array pero se supone que solo hay un término
foreach($terms as $term){
$class = $term->slug;
}
?>
<div class="<?php echo $class; ?>">
<?php the_cotent();?>
</div>

¡Sí! Quiero tener una plantilla diferente para cada "tipo". Así que si el post individual está en la categoría de radio, entonces que cargue la plantilla single-radio. Perdona mi ignorancia, ¿pero dónde pongo tu código? ¿En el archivo functions?

Sí, en el archivo functions.php. También tienes que crear single-radio.php, single-tv.php y así sucesivamente... en la carpeta de tu tema.

Eso es lo que pensé e hice todo esto, y por alguna razón solo está tomando el single-ad.php. Se niega a mirar cualquier otra plantilla single. Incluso cuando elimino el single-ad.php, no busca ningún otro archivo single. Tal vez el desarrollador del tema puso algo aquí para decir que solo tome ese. Simplemente no puedo encontrarlo ;-(

Para poder ayudarte mejor, necesito ver el código que estás utilizando para registrar el tipo de contenido personalizado y la taxonomía personalizada. ¿Puedes editar tu pregunta y agregar el código?

Acabo de agregarlo todo pero hizo que se rompiera en lugares extraños debido a los {}. Espero que puedas leerlo bien. Solo léelo todo como un functions.php largo. Muchas gracias... ¡si puedes resolver esto serás mi héroe!

¿Has probado nuevamente el código de mi respuesta? Lo edité y te pedí que lo intentaras de nuevo, pero no mencionaste si lo probaste o no.

Por alguna razón, ese código simplemente me muestra una página en blanco sin nada. Afecta a todas las entradas individuales, no solo a las de radio.

Lo siento, tenía un error de escritura. Inténtalo de nuevo, lo he probado y aquí está funcionando.
