Mezclar estructuras de reescritura de tipos de contenido personalizado y taxonomías

25 jun 2011, 18:03:17
Vistas: 26.2K
Votos: 32

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');
0
Todas las respuestas a la pregunta 2
8
35

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 de sumo-glossary-term
  • /glossary/[letra]/ debe ser una página de archivo para entradas con el término de taxonomía [letra] en la taxonomía sumo-glossary-letter
  • /glossary/[letra]/[nombre-del-termino]/ debe ser una entrada individual de sumo-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;
}
9 jul 2011 15:43:12
Comentarios

Lo probaré mañana para ver si funciona y volveré aquí. ¡Gracias!

maryisdead maryisdead
9 jul 2011 19:37:47

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!

maryisdead maryisdead
16 jul 2011 17:40:44

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

Jeff Jeff
9 feb 2012 02:01:11

¡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.

maryisdead maryisdead
11 feb 2012 15:50:20

El mismo problema aquí, usando WP 3.2.1. ¿Todavía no hay solución?

Richard B Richard B
5 mar 2012 17:42:32

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?

Gerben van Dijk Gerben van Dijk
27 may 2014 12:12:52

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

FullStack Alex FullStack Alex
19 sept 2019 06:50:51

Esto sigue funcionando muy bien. Estoy creando publicaciones de forma programática, y el filtro post_type_link se activa al usar wp_insert_post(). Pero pude solucionarlo definiendo el guid al hacer wp_insert_post().

Daan van den Bergh Daan van den Bergh
2 mar 2025 16:07:32
Mostrar los 3 comentarios restantes
1

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.

29 jun 2011 21:57:41
Comentarios

De hecho, estoy usando add_rewrite_rule, solo desplázate hasta el final de mi código. :-) Hasta ahora funciona bien, lo único es que con esta forma de hacerlo se llaman las plantillas incorrectas.

maryisdead maryisdead
30 jun 2011 07:25:18