Taxonomía personalizada específica para un tipo de entrada personalizada
Quiero crear una taxonomía personalizada que se comporte de manera similar al tipo de entrada como una categoría se comporta con las entradas predeterminadas (basado en la estructura de enlaces permanentes /%category%/%postname%/), de modo que las entradas en los tipos de entrada personalizados se muestren como www.example.com/custom-post-type/custom-taxonomy-name/post-name También quiero que el cuadro meta de categorías aparezca solamente cuando agregamos una nueva entrada predeterminada y no cuando agregamos una nueva entrada en el tipo de entrada personalizada, y que el cuadro de taxonomía personalizada aparezca solo cuando agregamos una nueva entrada en el tipo de entrada personalizada y no cuando agregamos una nueva entrada predeterminada.

En primer lugar, si deseas mostrar el metabox de taxonomía solo para tu tipo de publicación personalizado, entonces registra la taxonomía únicamente para ese tipo de publicación personalizado pasando el nombre del tipo de publicación como argumento en la función register_taxonomy()
. Al hacer esto, el metabox de taxonomía aparecerá solo para el tipo de publicación personalizado. Si no deseas mostrar el metabox de categorías para tu tipo de publicación personalizado, entonces elimina el término "category" como argumento al registrar tu tipo de publicación personalizado e incluye en su lugar el nombre del slug de la taxonomía así: 'taxonomies' => array( 'post_tag', 'nombre_de_tu_taxonomia')
. Aquí está el código de cómo logré eso.
He registrado una taxonomía personalizada con el slug "themes_categories" bajo el tipo de publicación personalizado "themes":
function themes_taxonomy() {
register_taxonomy(
'themes_categories', // El nombre de la taxonomía. Debe estar en formato slug (no debe contener mayúsculas o espacios).
'themes', // nombre del tipo de publicación
array(
'hierarchical' => true,
'label' => 'Tienda de temas', // nombre a mostrar
'query_var' => true,
'rewrite' => array(
'slug' => 'themes', // Esto controla el slug base que se mostrará antes de cada término
'with_front' => false // No mostrar la base de categoría antes
)
)
);
}
add_action( 'init', 'themes_taxonomy');
Luego, para cambiar el permalink, he creado la siguiente función:
function filter_post_type_link( $link, $post ) {
if ( $post->post_type !== 'themes' )
return $link;
if ( $cats = get_the_terms($post->ID, 'themes_categories') )
$link = str_replace('%themes_categories%', array_pop($cats)->slug, $link);
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
Luego registré un tipo de publicación personalizado con el slug "themes" como se muestra a continuación:
// Registrando el Tipo de Publicación Personalizado Themes
add_action( 'init', 'register_themepost', 20 );
function register_themepost() {
$labels = array(
'name' => _x( 'Temas', 'my_custom_post','custom' ),
'singular_name' => _x( 'Tema', 'my_custom_post', 'custom' ),
'add_new' => _x( 'Agregar nuevo', 'my_custom_post', 'custom' ),
'add_new_item' => _x( 'Agregar nuevo ThemePost', 'my_custom_post', 'custom' ),
'edit_item' => _x( 'Editar ThemePost', 'my_custom_post', 'custom' ),
'new_item' => _x( 'Nuevo ThemePost', 'my_custom_post', 'custom' ),
'view_item' => _x( 'Ver ThemePost', 'my_custom_post', 'custom' ),
'search_items' => _x( 'Buscar ThemePosts', 'my_custom_post', 'custom' ),
'not_found' => _x( 'No se encontraron ThemePosts', 'my_custom_post', 'custom' ),
'not_found_in_trash' => _x( 'No se encontraron ThemePosts en la papelera', 'my_custom_post', 'custom' ),
'parent_item_colon' => _x( 'ThemePost padre:', 'my_custom_post', 'custom' ),
'menu_name' => _x( 'Posts de Temas', 'my_custom_post', 'custom' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => false,
'description' => 'Posts personalizados de Temas',
'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'post-formats', 'custom-fields' ),
'taxonomies' => array( 'post_tag','themes_categories'),
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'menu_icon' => get_stylesheet_directory_uri() . '/functions/panel/images/catchinternet-small.png',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'query_var' => true,
'can_export' => true,
'rewrite' => array( 'slug' => 'themes/%themes_categories%', 'with_front' => FALSE ),
'public' => true,
'has_archive' => 'themes',
'capability_type' => 'post'
);
register_post_type( 'themes', $args ); // máximo 20 caracteres, no puede contener mayúsculas ni espacios
}
Hay algunas cosas que debes recordar al registrar un tipo de publicación personalizado. Cambia el parámetro "has_archive" al nombre del slug del tipo de publicación personalizado y el nombre del slug en rewrite como 'slug' => 'slug_del_tipo_de_publicacion_personalizado/%slug_de_taxonomia%
.
Ahora, cuando agregues un nuevo post en la página correcta del tipo de publicación, verás el permalink como http://www.example.com/wordpress/themes/%themes_categories%/nombre-del-post/
. Si no se selecciona la taxonomía personalizada para este post, el permalink permanecerá como http://www.example.com/wordpress/themes/%themes_categories%/nombre-del-post/
, lo que mostrará un error de solicitud incorrecta.
Para corregir esto, creamos un término por defecto en la taxonomía personalizada (igual que "sin categorizar" en las categorías).
Añade esto a functions.php:
function default_taxonomy_term( $post_id, $post ) {
if ( 'publish' === $post->post_status ) {
$defaults = array(
'themes_categories' => array('otros'),
);
$taxonomies = get_object_taxonomies( $post->post_type );
foreach ( (array) $taxonomies as $taxonomy ) {
$terms = wp_get_post_terms( $post_id, $taxonomy );
if ( empty($terms) && array_key_exists( $taxonomy, $defaults ) ) {
wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy );
}
}
}
}
add_action( 'save_post', 'default_taxonomy_term', 100, 2 );
Ahora, cuando la taxonomía personalizada se deje en blanco, el permalink se convertirá automáticamente en http://www.example.com/wordpress/themes/otros/nombre-del-post/
.
Por último, no olvides actualizar las reglas de rewrite haciendo clic en el botón "Guardar cambios" en la configuración de permalinks de la sección de administración de WordPress, de lo contrario serás redirigido a un error 404. Espero que esto te ayude.

Hola, tenía un problema... cuando mostramos el enlace al archivo de taxonomía usando echo get_the_term_list( $post->ID, $taxonomy, '', ', ', '' ); entonces el enlace aparece como www.example.com/taxonomy-term y no como www.example.com/themes/taxonomy-term. Creo que necesitamos escribir una regla HTACCESS para esto.

+1, gran explicación, seguí paso a paso y funciona, probado en WordPress 3.4.2

Me preguntaba: ¿hay que añadir la taxonomía personalizada al array de taxonomías al registrar un tipo de contenido personalizado? Porque parece funcionar sin añadirlo allí también (si ya registraste una taxonomía para el tipo de contenido personalizado). Solo por curiosidad.

Probé esto con el plugin CPT UI mientras seguía usando tu rewrite para cambiar la URL. Todo se ve bien. Las URLs son todas correctas y reinicié los enlaces permanentes, pero las entradas reales están mostrando un error 404. :( EDIT: no importa. Revisé y eliminé Hierarchical de la taxonomía y también me aseguré de guardar las cosas en el orden correcto, y ahora las entradas parecen funcionar. ¡Sí!

ej. registrar una taxonomía personalizada MY_NEW_CARSS
para tipos de posts personalizados:
$my_taxon_name = 'MY_NEW_CARSS';
$my_post_types = array('SUB_CAT_1','SUB_CAT_2','SUB_CAT_3');
//REGISTRAR TAXONOMÍA PERSONALIZADA ( http://codex.wordpress.org/Function_Reference/register_taxonomy )
//Si deseas registrar un tipo de post JERÁRQUICO (con padre), lee esta advertencia: https://codex.wordpress.org/Function_Reference/register_post_type#hierarchical
add_action( 'init', 'my_f32' ); function my_f32() {
register_taxonomy( $GLOBALS['my_taxon_name'], array(),
array(
'label'=>$GLOBALS['my_taxon_name'], 'public'=>true, 'show_ui'=>true, 'show_admin_column'=>true, 'query_var'=>true,
'hierarchical'=>true, 'rewrite'=>array('with_front'=>true,'hierarchical'=>true),
));
}
//REGISTRAR TIPO DE POST PERSONALIZADO ( http://codex.wordpress.org/Function_Reference/register_post_type )
add_action( 'init', 'myf_63' );function myf_63() {
foreach ($GLOBALS['my_post_types'] as $each_Type) {
register_post_type( $each_Type,
array(
'label'=>$each_Type, 'labels' => array('name'=>$each_Type.' páginas', 'singular_name'=>$each_Type.' página'), 'public' => true, 'publicly_queryable'=> true, 'show_ui'=>true, 'capability_type' => 'post', 'has_archive' => true, 'query_var'=> true, 'can_export' => true, //'exclude_from_search' => false, 'show_in_nav_menus' => true, 'show_in_menu' => 'edit.php?post_type=page',//true, 'menu_position' => 5,
'hierarchical' =>true,
'supports' =>array( 'page-attributes', 'title', 'editor', 'thumbnail' ),
'rewrite' => array('with_front'=>true, ), // 'rewrite' => array("ep_mask"=>EP_PERMALINK ...) OR 'permalink_epmask'=>EP_PERMALINK,
));
register_taxonomy_for_object_type('category',$each_Type); //categorías estándar
register_taxonomy_for_object_type($GLOBALS['my_taxon_name'] ,$each_Type); //Categorías personalizadas
}
}
