Mezclar estructuras de reescritura de tipos de contenido personalizado y taxonomías
Básicamente quiero crear un glosario utilizando tipos de contenido personalizado y tengo algunos problemas configurando las reescrituras de la manera que quiero. Lo quiero así:
La URL principal del glosario:
http://example.com/glossary/
Términos del glosario que comienzan con la letra A:
http://example.com/glossary/a/
La URL para un término individual del glosario:
http://example.com/glossary/a/atomic/
En realidad logré esto usando el código de abajo, pero estoy seguro de que es una forma muy incómoda de hacerlo y sé que está funcionando mal en alguna parte ya que se llaman a las plantillas incorrectas al ver las páginas. Excepto por http://example.com/glossary/, donde archive-sumo-glossary-term.php se llama como se espera, las otras dos simplemente activan index.php en mi tema.
Aquí está el código (functions.php
en el tema):
add_action('init', 'create_glossary');
function create_glossary()
{
register_post_type
(
'sumo-glossary-term',
array
(
'labels' => array
(
'name' => _x('Términos del Glosario', 'nombre general del tipo de contenido'),
'singular_name' => _x('Término del Glosario', 'nombre singular del tipo de contenido')
# Y así sucesivamente...
),
'supports' => array('title', 'editor', 'thumbnail'),
'public' => true,
'rewrite' => array
(
'slug' => 'glossary',
'with_front' => false
),
'query_var' => 'glossary-term',
'has_archive' => true
)
);
register_taxonomy
(
'sumo-glossary-letter',
'sumo-glossary-term',
array
(
'hierarchical' => true,
'labels' => array
(
'name' => _x('Letras', 'nombre general de taxonomía'),
'singular_name' => _x('Letra', 'nombre singular de taxonomía')
# Y así sucesivamente...
),
'show_ui' => true,
'query_var' => 'glossary-letter',
'rewrite' => false
)
);
}
add_filter('post_type_link', 'glossary_term_permalink', 10, 4);
function glossary_term_permalink($post_link, $post, $leavename, $sample)
{
if ($post->post_type == 'sumo-glossary-term')
{
$permalink = str_replace('glossary/', 'glossary/' . $post->post_name[0] . '/', $post_link);
}
return $permalink;
}
add_rewrite_rule('^glossary/([^/]*)?$','index.php?glossary-letter=$matches[1]','top');
add_rewrite_rule('^glossary/([^/]*)/([^/]*)?$','index.php?glossary-term=$matches[2]','top');
Siempre puedes anular la plantilla que se llamará con el filtro template_include
o uno relacionado, pero esto podría ocultar problemas más profundos con archivos personalizados.
Según lo entiendo, quieres usar la siguiente estructura:
/glossary/
debe ser una página de archivo para todas las entradas desumo-glossary-term
/glossary/[letra]/
debe ser una página de archivo para entradas con el término de taxonomía[letra]
en la taxonomíasumo-glossary-letter
/glossary/[letra]/[nombre-del-termino]/
debe ser una entrada individual desumo-glossary-term
Esto significa que el primero cargará la plantilla archive-sumo-glossary-term.php
, el segundo cargará taxonomy-sumo-glossary-letter.php
, y el tercero cargará single-sumo-glossary-term.php
.
Logré esto en WordPress 3.2 configurando explícitamente el slug de reescritura de la taxonomía, y tanto el slug de reescritura como el slug de archivo para el tipo de entrada, sin otras reglas de reescritura. Además, registré la taxonomía primero y el tipo de entrada después, para asegurarme de que las prioridades fueran correctas (de lo contrario, una URL como /glossary/f/page/2
iría al término de glosario page
en lugar de la página 2 de la letra de glosario f
).
add_action('init', 'create_glossary');
function create_glossary()
{
register_taxonomy
(
'sumo-glossary-letter',
array(),
array
(
'hierarchical' => true,
'labels' => array
(
'name' => _x('Letras', 'nombre general de taxonomía'),
'singular_name' => _x('Letra', 'nombre singular de taxonomía')
# Y así sucesivamente
),
'show_ui' => true,
'query_var' => 'glossary-letter',
'rewrite' => array(
'slug' => 'glossary',
),
)
);
register_post_type
(
'sumo-glossary-term',
array
(
'labels' => array
(
'name' => _x('Términos del Glosario', 'nombre general de tipo de entrada'),
'singular_name' => _x('Término del Glosario', 'nombre singular de tipo de entrada')
# Y así sucesivamente …
),
'supports' => array('title', 'editor', 'thumbnail'),
'public' => true,
'rewrite' => array
(
'slug' => 'glossary/%sumo-glossary-letter%',
'with_front' => false
),
'query_var' => 'glossary-term',
'has_archive' => 'glossary',
'taxonomies' => array( 'sumo-glossary-letter' ),
)
);
}
add_filter('post_type_link', 'glossary_term_permalink', 10, 4);
function glossary_term_permalink($post_link, $post, $leavename, $sample)
{
if ( false !== strpos( $post_link, '%sumo-glossary-letter%' ) ) {
$glossary_letter = get_the_terms( $post->ID, 'sumo-glossary-letter' );
$post_link = str_replace( '%sumo-glossary-letter%', array_pop( $glossary_letter )->slug, $post_link );
}
return $post_link;
}

Ok, no exactamente mañana... ¡Funcionó, casi perfectamente! ¡Gracias!
Lo que no funciona es /glossary/
. Me da un error 404 (archive-sumo-glossary-term.php
está configurado). ¿Alguna idea? Debo decir que estoy atascado en WP 3.0.1 y tal vez sea un problema de versión. Tendré que probarlo de nuevo cuando pueda actualizar.
De todos modos, en su mayor parte funciona y por ahora no necesito necesariamente /glossary/
y simplemente redirijo a la letra A. ¡Gracias de nuevo!

oye @maryisdead, tuve exactamente el mismo problema y llegué exactamente a la misma solución, pero me quedé con exactamente el mismo problema que tú: ¿cómo haces que /glossary vaya a la plantilla archive-glossery.php?
Acabo de encontrar la respuesta: usa 'has_archive' => 'glossary'
, en lugar de has_archive => true
Acabo de notar que Jan lo tiene así en su respuesta, pero tú no lo tienes así en tu código original - ¿actualizaste esa parte? Comenzó a funcionar para mí tan pronto como hice ese cambio

¡Hola Jeff! Sí, actualicé esa parte. Acabo de verificar nuevamente, todavía no funciona. La instalación de WordPress en cuestión aún no está actualizada (3.0.1), así que quizás ese siga siendo el origen del problema.

Código aún relevante: todavía lo uso como mi solución preferida para lograr esta estructura.
Una pregunta: si hay una publicación creada que no tiene asignado ningún término de taxonomía (por lo que la URL sería como customposttypeslug/postslug), obtengo un error 404. ¿Hay alguna manera (probablemente mediante reglas de enlaces permanentes) de lograr que esto también funcione?

¡FUNCIONA PERFECTAMENTE! El orden del registro de la taxonomía y el CPT fue la clave en mi caso.

No lo he usado personalmente, pero lo que podrías considerar es "add_rewrite_rule"
http://codex.wordpress.org/Rewrite_API/add_rewrite_rule
tampoco olvides guardar los enlaces permanentes una vez que los hayas modificado.
