Enlaces permanentes: tipo de publicación personalizada -> taxonomía personalizada -> publicación
Estoy teniendo problemas trabajando con las reglas de reescritura de WordPress y necesito ayuda.
Tengo un tipo de publicación personalizada llamado _shows_
.
Todos los shows tienen una única categoría de taxonomía personalizada _show-category_
. Un _show_
nunca tendrá más de una _show-category_
.
Me gustaría que mis URLs se enruten de esta manera:
www.mysite.com/shows/ => archive-shows.php
www.mysite.com/shows/%category%/ => taxonomy-show-category.php
www.mysite.com/shows/%category%/%postname%/ => single-shows.php
Así que como ejemplo del mundo real, digamos que tenemos una _show-category_
"Foo" y una publicación _show_
titulada "Bar" que tiene "Foo" como su _show-category_
. Esperaría que mi aplicación WordPress se vea así:
www.mysite.com/shows/foo/ => muestra todas las publicaciones bajo la categoría foo
www.mysite.com/shows/foo/bar => muestra la publicación individual
Trato de evitar plugins cuando es posible, pero estoy abierto a cualquier solución.
Primero, registra tu taxonomía y establece el argumento slug
de rewrite
como shows
:
register_taxonomy(
'show_category',
'show',
array(
'rewrite' => array( 'slug' => 'shows', 'with_front' => false ),
// tus otros argumentos...
)
);
Luego, registra tu tipo de publicación y establece el slug como shows/%show_category%
, y configura el argumento has_archive
como shows
:
register_post_type(
'show',
array(
'rewrite' => array( 'slug' => 'shows/%show_category%', 'with_front' => false ),
'has_archive' => 'shows',
// tus otros argumentos...
)
);
Por último, añade un filtro a post_type_link
para sustituir la categoría del show en los enlaces permanentes individuales:
function wpa_show_permalinks( $post_link, $post ){
if ( is_object( $post ) && $post->post_type == 'show' ){
$terms = wp_get_object_terms( $post->ID, 'show_category' );
if( $terms ){
return str_replace( '%show_category%' , $terms[0]->slug , $post_link );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'wpa_show_permalinks', 1, 2 );
EDITADO
Olvidé mencionar el argumento has_archive
de register_post_type
anteriormente, que debe establecerse como shows
.

¡Milo, gracias! El filtro post_type_link era la pieza que me faltaba. Para cualquiera que lea este hilo con el mismo problema, lo único a tener en cuenta es que hay un pequeño error en la función wpa_show_permalinks, donde $post->post_type == 'show' debería ser en realidad 'shows'. ¡Gracias de nuevo Milo!

¡Gracias, Milo! Eso resolvió mi problema. Estaba intentando lograr algo similar usando este plugin y las URLs reescritas devolvían error 404. Supongo que hacerlo manualmente era el camino correcto.

@milo, viniendo desde http://wordpress.stackexchange.com/questions/199456/custom-taxonomy-post-slug-permalink, sigo obteniendo un 404
con este enfoque. Mi estructura de permalinks es %category%/%postname%

Si estás haciendo un cambio en una instancia existente de WordPress, asegúrate de ir a Ajustes > Enlaces permanentes y hacer clic en guardar. Los cambios que hayas hecho en functions.php no tendrán efecto hasta que lo hagas.

Esto casi funcionó para mí en el sentido de que la taxonomía se muestra en la página del tipo de entrada, la ruta /tipo_de_entrada/taxonomia/ es una página legítima (antes daba error 404) pero mi ruta /tipo_de_entrada/taxonomia/entrada sigue dando 404. Noté que al registrar la taxonomía anteriormente, tanto "show_category" como "show" se estaban registrando, aunque solo show_category es la taxonomía. Solo estoy registrando la taxonomía.

@Milo ¿hay alguna forma de hacer que esto funcione con sub-sub taxonomías como shows/taxonomia/subtaxonomia/entrada?

Yo también estaría interesado en saber cómo hacer que esto funcione con hijos de taxonomía como /shows/tax/subtax/postname

Esta es una técnica realmente valiosa, gracias. Sin embargo, hay un pequeño problema: al usar 'post_type_link', el botón de modificar/editar en la vista de edición de entradas del administrador desaparecerá. Esto significa que el slug de la entrada no será editable, por lo que ese slug quedará fijo y si cambias el post_title más adelante, no podrás reflejarlo en el slug.

¿Cómo (internamente) 'shows/%show_category%' se resuelve automáticamente a la taxonomía/término correcto? Solo por curiosidad. La documentación oficial de register_post_type no lo explica, ni te da información alguna y en su lugar hace creer que solo podemos pasar cadenas regulares en lugar de estructuras de permalinks completas. Además, no puedo encontrar documentación sobre la generación automática de etiquetas de estructura de permalinks al crear una taxonomía.

@Stratboy Tendré que intentarlo de nuevo, no recuerdo que el slug de la publicación no fuera editable en este caso. Sé que con estructuras más complejas he tenido que usar add_permastruct
en su lugar. WP no hace nada con %show_category%
en este caso, es solo un marcador de posición que tienes que reemplazar tú mismo en el filtro post_type_link
. Esto en realidad puede ser cualquier etiqueta de reescritura válida, por ejemplo si deseas usar un campo personalizado o algo más en la URL.

De hecho, si miras $wp_rewrite justo después de registrar los tipos de publicación pero antes del filtro post_type_link
, notarás que se ha generado la etiqueta %show_category%, así como las estructuras permanentes relacionadas. Así que es extraño, existen, por lo que son reconocidas pero probablemente WordPress no sabe cómo tratarlas.

@stratboy show_category tiene que ser una etiqueta de reescritura válida, que lo es, porque se agregó como parte del registro de la taxonomía, pero también puede ser una agregada mediante add_rewrite_tag. Está haciendo lo mismo detrás de escenas.

¿Qué sucede cuando necesitas un slug diferente en varios idiomas? (por ejemplo, WPML). Y cuando ciertas publicaciones no tienen una categoría asignada, ¿seguirán teniendo solo /shows/nombre-de-la-publicación? ¡Saludos!

En el caso de WPML, esto funciona para el idioma predeterminado pero desafortunadamente no en los otros

Realmente deseaba que esto funcionara para mí también, pero cada singular termina en un error 404...

Esto solo resulta en errores 404 para mí también, desafortunadamente... incluso después de refrescar los enlaces permanentes.

WordPress 5.2.4 y WordPress 5.3 también resultaron en errores 404 con esta solución. He publicado una pregunta en el foro de soporte de WP preguntando si alguien más podría tener conocimiento sobre qué cambió en las reescrituras en los últimos años que podría haber roto esta funcionalidad.
Ahora estoy usando un plugin para gestionar la estructura de enlaces permanentes y parece que el plugin está haciendo algún análisis de wp_query para que los enlaces permanentes funcionen correctamente.

Tuve el mismo problema de 404 en las páginas individuales de publicaciones de shows como comentaron otros usuarios, pero pude solucionarlo agregando add_rewrite_rule( 'shows/([^/]+)/([^/]+)', 'index.php?show =$matches[2]', 'top' );
a mis funciones. Esto hará coincidir la segunda porción del slug después de 'show' con el nombre de una publicación de show.

La solución de Milo casi funciona. Desafortunadamente, el tipo de publicación se pierde y se utiliza la plantilla predeterminada en lugar del CPT.

Esto casi funcionó para mí - la página principal del tipo de publicación y las páginas de categoría funcionaban bien, pero fallaba en las publicaciones individuales (WP pensaba que la publicación era una subcategoría y devolvía un error 404). El paso que faltaba era el filtro rewrite_rules_array
, como se describe aquí: https://stackoverflow.com/a/23702560/915762

Hay un problema: no puedes tener slugs idénticos para diferentes taxonomías, por ejemplo /tipo-de-publicacion/taxonomia-1/agencia-seo/
y /tipo-de-publicacion/taxonomia-2/agencia-seo/
no será posible

@Sarah ¡Dios mío, eres mi SALVADORA! ¡Ahora esto funciona, finalmente, oh Dios mío! ¡Gracias, gracias! Tenía un caso de uso muy similar en el que tenía un tipo de publicación de recurso con la taxonomía resource_category. Las páginas de taxonomía funcionaban y el archivo funcionaba, pero las individuales no. Esto funcionó: add_rewrite_rule( '^resources/([^/]+)/([^/]+)', 'index.php?resource=$matches[2]', 'top' );
