Obteniendo permalinks de tipo de publicación personalizados jerárquicos para que funcionen como las páginas

13

He investigado todas las preguntas aquí sobre los enlaces permanentes de tipo de publicación personalizada, pero la mayoría parecen tener problemas con la reescritura de taxonomía personalizada o la falta evidente de flush_rewrite_rules (). Pero en mi caso, solo estoy usando un tipo de publicación personalizada (sin taxonomía), configurada para ser jerárquica (para que pueda asignar relaciones padre-hijo), con el "soporte" adecuado para los atributos metabox, etc., etc. He lavado las reglas de reescritura de mil maneras diferentes. He intentado diferentes estructuras de permalink. ¡Pero las URLs infantiles siempre dan como resultado 404!

Originalmente tenía tipos de publicaciones personalizadas independientes para los elementos "padre" e "hijo" (usando p2p), y probablemente no habría tenido problemas usando una taxonomía para la agrupación "padre". Sé que serían semánticamente más preciso. Pero para el cliente, es más fácil para ellos visualizar la jerarquía cuando las "publicaciones" se muestran en el administrador, al igual que las páginas son: un árbol simple en el que aparecen los hijos debajo del padre, con el prefijo "-" y en el orden apropiado. Además, se pueden utilizar varios métodos para asignar orden mediante arrastrar y soltar. La agrupación a través de taxonomía (o p2p) da como resultado una lista plana de "publicaciones" en las listas de administradores, que simplemente no es tan visualmente obvia.

Entonces, lo que busco es, literalmente, el mismo comportamiento que las "páginas" del núcleo, pero con mi tipo de publicación personalizada. He registrado el tipo de publicación tal como se esperaba, y en el administrador funciona perfectamente. Puedo asignar un padre y un menú para cada "publicación" del boletín, aparecen correctamente en las listas de edición:

Spring 2012
— First Article
— Second Article

Y sus enlaces permanentes parecen para construirse correctamente. De hecho, si cambio algo en la estructura, o incluso modifico la barra de reescritura al registrar el tipo de publicación, se actualizan automáticamente correctamente, por lo que sé que algo funciona:

http://mysite.com/parent-page/child-page/                  /* works for pages! */
http://mysite.com/post-type/parent-post/child-post/        /* should work? */
http://mysite.com/newsletter/spring-2012/                  /* works! */
http://mysite.com/newsletter/spring-2012/first-article/    /* 404 */
http://mysite.com/newsletter/spring-2012/second-article/   /* 404 */

También tengo "páginas" de núcleo estándar con relaciones jerárquicas creadas, y se ven igual en el administrador, pero en realidad también funcionan en el front-end (tanto las URL principales como las secundarias funcionan bien).

Mi estructura de enlace permanente está establecida en:

http://mysite.com/%postname%/

También intenté esto (solo porque muchas otras respuestas parecían indicar que era necesario, aunque no tenía sentido en mi caso):

http://mysite.com/%category%/%postname%/

Mi registro CPT args incluye:

$args = array(
    'public'                => true,
    'publicly_queryable'    => true,
    'show_ui'               => true,
    'has_archive'           => 'newsletter',
    'hierarchical'          => true,
    'query_var'             => true,
    'supports'              => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
    'rewrite'               => array( 'slug' => 'newsletter', 'with_front' => false ),

La única diferencia visible entre mi tipo de publicación personalizada children y normal page , es que mi CPT tiene la bala al principio de la estructura de enlace permanente, seguida de las barras primarias / secundarias (donde las páginas comienzan con las barras primarias / secundarias, sin "prefijo"). Por qué esto arruinaría las cosas, no lo sé. Muchos artículos parecen indicar que esto es exactamente cómo deben comportarse los enlaces permanentes de CPT jerárquicos, pero los míos, aunque bien formados, no funcionan.

Lo que también me desconcierta es que cuando examino el query_vars para esa página 404, parecen contener los valores correctos para que WP "encuentre" mis páginas secundarias, pero algo no funciona.

$wp_query object WP_Query {46}
public query_vars -> array (58)
'page' => integer 0
'newsletter' => string(25) "spring-2012/first-article"
'post_type' => string(10) "newsletter"
'name' => string(13) "first-article"
'error' => string(0) ""
'm' => integer 0
'p' => integer 0
'post_parent' => string(0) ""
'subpost' => string(0) ""
'subpost_id' => string(0) ""
'attachment' => string(0) ""
'attachment_id' => integer 0
'static' => string(0) ""
'pagename' => string(13) "first-article"
'page_id' => integer 0
[...]

He intentado esto con varios temas, entre ellos veinte y doce, solo para asegurarme de que no falte una plantilla de mi parte.

Usando Rewrite Rules Inspector, esto es lo que aparece para la url:      enlace

newsletter/(.+?)(/[0-9]+)?/?$   
       newsletter: spring-2012/first-article
           page: 
(.?.+?)(/[0-9]+)?/?$    
       pagename: newsletter/spring-2012/first-article
           page: 

cómo se muestra en otra página de inspector:

RULE:
newsletter/(.+?)(/[0-9]+)?/?$
REWRITE:
index.php?newsletter=$matches[1]&page=$matches[2]
SOURCE:
newsletter

Este resultado de reescritura me haría creer que el siguiente enlace permanente "no bonito" funcionaría:

enlace

No lo hace 404, pero muestra el elemento "boletín" de CPT principal, no el elemento secundario. La solicitud se ve así:

Array
(
    [page] => first-article
    [newsletter] => spring-2012
    [post_type] => newsletter
    [name] => spring-2012
)
    
pregunta somatic 28.12.2012 - 14:52

5 respuestas

1

Entonces, después de confirmar que pude obtener el comportamiento de página jerárquico esperado con una instalación completamente limpia y solo con una sola declaración de CPT, supe que la falla estaba en algún lugar dentro de mi propio complemento que uso para manejar la creación de CPT (muy complejo, se encarga de la costumbre) metaboxes, taxonomías, etc). El problema era que, a pesar de todos los consejos para revisar los problemas de reescritura o consulta, no podía ver nada obviamente mal. Revisé todos los filtros y enlaces, viendo la consulta en cada punto y sin ver nada que pudiera causar el 404.

Así que me quedé con la tarea de deshabilitar / habilitar manualmente cada una de las 9 clases grandes, y luego, encontrar al menos 2 de ellas causando el 404, revisar cada función una por una y deshabilitarlas / habilitarlas, y luego rastrear línea por línea dentro de esas funciones: un intento de fuerza bruta para ver exactamente qué causaba el 404, incluso si no supiera por qué.

Ahí es cuando encontré que hay una consecuencia al usar $query->get_queried_object() . Parece que el uso de esta función de envoltura en realidad modifica $ consulta, lo que pensé que estaba devolviendo sin cambios al final de mi función. Se involucraron tres filtros en 2 clases que modificaron la consulta: parse_query , posts_orderby , posts_join - y todas las funciones de devolución de llamada llamaron a $query->get_queried_object() en el $query arg pasado para luego ejecutar algunas pruebas condicionales y algunas veces modificar las vars de consulta (como para casos especiales de orden de clasificación). Por extraño que parezca, estas funciones realmente funcionaron bien en lo que fueron diseñadas para hacer, a pesar de mi uso de la función. Nunca he notado nada malo con la consulta $ devuelta antes!

De alguna manera, después de más de un año de desarrollo y uso en docenas de sitios de producción en vivo, nunca había experimentado ningún efecto adverso por este error. Solo cuando me aventuré en CPT jerárquicos esta pequeña diferencia rompió las cosas de repente. Eso es parte de lo que me tiró tan duro con esto: lo mejor que pude ver, ¡mis filtros de consulta eran confiables!

Confieso que todavía no sé exactamente por qué el hecho de llamar a esta función rompe solo este pequeño aspecto de las páginas secundarias de CPT, ¡y sin embargo, nunca manifestó ningún otro problema! Pero estaba claro que al usarlo dentro de un filtro, la devolución de llamada modificó el $query devuelto de alguna manera. Al eliminar esta llamada, mis errores 404 desaparecieron.

Gracias por todos los consejos: me gustaría poder dividir la recompensa, ya que obtuve una idea de cada respuesta, incluso si la solución definitiva no estaba relacionada. Esta ha sido una lección educativa para no confiar ciegamente en su código, incluso si ha estado funcionando de manera confiable durante mucho tiempo, o si no está produciendo ningún error obvio.

A veces, como la gráfica de Kaiser se encarna tan bien, solo tienes que empezar a lanzar los interruptores hasta que las luces vuelvan a encenderse. En mi caso, tuve que tomar la misma estrategia de solución de problemas hasta las líneas individuales en una función antes de poder ver el problema.

    
respondido por el somatic 12.01.2013 - 04:36
14

Esta es la primera vez que participo aquí en Stack Exchange, pero lo intentaré y veré si puedo ayudarte a orientarte en la dirección correcta.

De forma predeterminada, los CPT jerárquicos se comportan exactamente de la manera que se describe. El único prefijo de slug, "boletín" en este caso, es permitir que el motor de reescritura sepa cómo diferenciar las solicitudes de los diferentes tipos de publicaciones.

Esos argumentos de registro de CPT se ven bien, pero cuando se solicita un CPT, el pagename query var no debería tener un valor y el name query var debería ser el mismo que newsletter aquí, por lo que parece que hay un conflicto en algún lugar de tu configuración.

Para ayudar a depurar, instale y active el complemento del Inspector de reglas de reescritura , luego visite la pantalla en " Herramientas - > Reglas de reescritura ."

  1. Mientras mira la lista, todas sus reglas para el boletín CPT deben aparecer antes de cualquier reglas de reescritura de páginas. Verifique que este sea el caso escaneando la columna " Fuente ".
  2. Si esto se comprueba, ingrese la URL de su CPT de "primer artículo" en el campo " Coincidir URL " y haga clic en el botón "Filtrar" para ver qué regla coincide. Debe coincidir con una regla de boletín y una regla de página, pero la regla de boletín debe ser la primera.

Si eso no revela ningún problema, busque en la columna post_name en wp_posts para encontrar otras publicaciones con la barra del "primer artículo" para ver si puede haber una colisión. Haga también una búsqueda de "boletín", solo para estar seguro.

Agregue el siguiente fragmento de código para inspeccionar las variables de consulta al inicio de la solicitud para verificar y determinar cuáles se establecen mediante la coincidencia de la regla de reescritura (visite el CPT secundario en el extremo frontal). Si el pagename var no aparece aquí, entonces se establecerá algo más adelante en la solicitud:

add_filter( 'request', 'se77513_display_query_vars', 1 );

function se77513_display_query_vars( $query_vars ) {
    echo '<pre>' . print_r( $query_vars, true ) . '</pre>';

    return $query_vars;
}

Cualquier complemento / función que modifique las variables de consulta podría estar causando un conflicto, así que desactívelos si aún observa problemas. También elimine las reglas de reescritura después de cada paso, especialmente si la solicitud coincidía con una regla incorrecta en el segundo paso anterior (mantenga la pantalla "Permalinks" abierta en una pestaña separada y simplemente actualícela).

    
respondido por el Brady Vercher 07.01.2013 - 08:15
5

El parent/Child permalink Funciona fuera de la caja siempre y cuando lo establezca

'hierarchical'=> true,
'supports' => array('page-attributes' ....

Actualizar:

Acabo de probarlo de nuevo y funciona como se esperaba, con este caso de prueba:

add_action('init','test_post_type_wpa77513');
function test_post_type_wpa77513(){
    $args = array(
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true, 
        'show_in_menu' => true, 
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'post',
        'has_archive' => true, 
        'hierarchical' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' )
    ); 

    register_post_type( 'newsletter', $args );
}

y permalink establecido en /%postname%/ Me sale bien el boletín / padre / hijo.

    
respondido por el Bainternet 07.01.2013 - 13:45
3

Además de preguntar »¿Has intentado apagarlo y volver a encenderlo?« , También tengo que preguntar "¿Tiene algún complemento activo y su tema está haciendo algo con los enlaces permanentes (por ejemplo, para registrar taxonomía, publicar tipos, agregar reglas de reescritura, etc.)?

Si es así: ¿Sigue sucediendo esto, después de que deshabilitaste todos los complementos y cambiaste a TwentyEleven?

Paradepuraraúnmás,dirígeteaGitHubytomael Complemento "Rewrite" de Toschos . Luego cambie al repositorio oficial de complementos en wp.org y seleccione el complemento MonkeyManRewriteAnalyzer . Incluso escribí una pequeña extensión para pegar ambos un poco juntos. Esto le dará muchos detalles sobre su configuración.

    
respondido por el kaiser 07.01.2013 - 19:42
-2

¿Está ejecutando la versión más actual de WP? Supongo que esa es la primera pregunta (¡como cuando llamas a soporte técnico y te preguntan si tu computadora está conectada!), Ya que he leído que este problema se solucionó en la versión más reciente.

Hay una publicación en digwp.com que trata este problema (http://digwp.com/2011/06/dont-use-postname/). Al parecer, WP no puede distinguir la diferencia entre las publicaciones y las páginas, y si inicia sus URL con una opción basada en texto, WP activa una marca que crea una regla para cada página / publicación que tenga. Si tiene una gran cantidad de contenido en su sitio, esto puede generar una gran cantidad de solicitudes y es probable que su servidor se desactive, lo que resultará en un montón de 404, incluso si las páginas están allí.

Entonces. Si usa primero una estructura basada en números, luego su estructura basada en texto, apostaría a que su problema 404 se resolvería. Ahora, considerando los problemas de SEO, no usaría una estructura de fecha, pero tomar esa decisión será lo suficientemente lógico para ti.

    
respondido por el Melanie Sumner 07.01.2013 - 21:58

Lea otras preguntas en las etiquetas