wake-up-neo.com

Hierarchische benutzerdefinierte Post-Typ-Permalinks funktionieren wie Seiten

Ich habe hier alle Fragen zu benutzerdefinierten Permalinks für Posts durchgearbeitet, aber die meisten scheinen entweder Probleme mit benutzerdefinierten Taxonomieumschreibungen oder das offensichtliche Fehlen von flush_rewrite_rules () zu sein. Aber in meinem Fall verwende ich nur einen benutzerdefinierten Beitragstyp (keine Taxonomie), der hierarchisch festgelegt ist (damit ich Eltern-Kind-Beziehungen zuweisen kann), mit der richtigen "Unterstützung" für die Attribute Metabox usw. usw. I hab über tausend verschiedene möglichkeiten rewrite regeln gespült. Ich habe verschiedene Permalink-Strukturen ausprobiert. Untergeordnete URLs führen jedoch immer zu 404!

Ich hatte ursprünglich unabhängige benutzerdefinierte Beitragstypen für die Elemente "parent" und "child" (mit p2p), und ich hätte wahrscheinlich keine Probleme gehabt, eine Taxonomie für die Gruppierung "parent" zu verwenden - ich weiß, dass diese semantisch genauer wären. Für den Kunden ist es jedoch am einfachsten, die Hierarchie zu visualisieren, wenn die "Posts" im Administrator angezeigt werden, genau wie die folgenden Seiten: Ein einfacher Baum, in dem unter dem übergeordneten Element Kinder mit dem Präfix "-" und in der richtige Reihenfolge. Es können auch verschiedene Methoden zum Zuweisen der Reihenfolge per Drag & Drop verwendet werden. Die Gruppierung über Taxonomie (oder p2p) führt zu einer flachen Liste von "Posts" in den Admin-Einträgen, was einfach nicht so offensichtlich ist.

Was ich also suche, ist im wahrsten Sinne des Wortes dasselbe Verhalten wie die "Kernseiten", jedoch mit meinem benutzerdefinierten Beitragstyp. Ich habe den Post-Typ wie erwartet registriert und im Admin funktioniert er einwandfrei. Ich kann jedem "Post" des Newsletters einen Parent und einen menu_order zuweisen. Diese werden in den Edit Listings korrekt angezeigt:

Spring 2012
— First Article
— Second Article

Und ihre Permalinks scheinen richtig aufgebaut zu sein. Wenn ich beim Registrieren des Post-Typs etwas an der Struktur ändere oder sogar den Überschreibungs-Slug ändere, werden diese automatisch korrekt aktualisiert, sodass ich weiß, dass etwas funktioniert:

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 */

Ich habe auch Standard-Core- "Seiten" mit hierarchischen Beziehungen erstellt und sie sehen im Administrator genauso aus, aber sie funktionieren auch im Front-End (sowohl übergeordnete als auch untergeordnete URLs funktionieren einwandfrei).

Meine Permalink-Struktur lautet:

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

Ich habe es auch versucht (nur weil so viele andere Antworten darauf hindeuteten, dass es nötig war, obwohl es in meinem Fall keinen Sinn ergab):

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

Meine registrierten CPT-Argumente umfassen:

$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 ),

Der einzige sichtbare Unterschied zwischen meinem benutzerdefinierten Beitragstyp children und normalem page children besteht darin, dass mein CPT den Slug am Anfang der Permalink-Struktur hat, gefolgt von den Parent/Child-Slugs (wo die Seiten nur mit den Parent/Child-Slugs beginnen, kein "Präfix"). Warum dies die Dinge beschmutzen würde, weiß ich nicht. Viele Artikel scheinen darauf hinzuweisen, dass sich solche hierarchischen CPT-Permalinks genau so verhalten sollten - aber meine funktionieren, obwohl sie gut ausgearbeitet sind, nicht.

Was mich auch verwirrt, ist, wenn ich die query_vars für diese 404-Seite untersuche - sie scheinen die richtigen Werte für WP zu enthalten, um meine untergeordneten Seiten zu "finden", aber etwas funktioniert nicht.

$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
[...]

Ich habe es mit verschiedenen Themen versucht, darunter auch mit zwölf, nur um sicherzugehen, dass mir keine Vorlage fehlt.

Mit dem Rewrite Rules Inspector wird dies für die URL angezeigt: http://mysite.com/newsletter/spring-2012/first-article/

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

wie es auf einer anderen Inspektorseite angezeigt wird:

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

Diese Neuschreibungsausgabe würde mich glauben lassen, dass der folgende "nicht-hübsche" Permalink funktionieren würde:

http://meinesite.com/?newsletter=spring-2012&page=first-article

Es wird nicht 404, sondern der übergeordnete CPT-Artikel "Newsletter" angezeigt, nicht das untergeordnete. Die Anfrage sieht so aus:

Array
(
    [page] => first-article
    [newsletter] => spring-2012
    [post_type] => newsletter
    [name] => spring-2012
)
15
somatic

Nachdem ich bestätigt hatte, dass ich mit einer vollständig sauberen Installation und nur einer einzigen CPT-Deklaration das erwartete hierarchische Seitenverhalten erzielen konnte, wusste ich, dass der Fehler irgendwo in meinem eigenen Plugin liegt, das ich für die CPT-Erstellung verwende (sehr komplex, behandelt benutzerdefinierte Metaboxen, Taxonomien) , usw). Das Problem war, dass ich trotz aller Ratschläge zum Überprüfen auf Überschreib- oder Abfrageprobleme nichts offensichtlich Falsches sehen konnte. Ich überprüfte jeden Filter und Haken, betrachtete die Abfrage an jedem Punkt und sah nichts, was den 404 verursachen würde.

Ich hatte also die Aufgabe, jede der 9 großen Klassen manuell zu deaktivieren/zu aktivieren, und dann herauszufinden, ob mindestens zwei von ihnen den Fehler 404 verursachen, jede Funktion einzeln durchzugehen und sie zu deaktivieren/zu aktivieren und dann die Linie zu verfolgen nach Zeilen innerhalb dieser Funktionen - ein Brute-Force-Versuch, genau zu sehen, was den 404 verursachte, auch wenn ich nicht wusste, warum.

In diesem Moment habe ich festgestellt, dass die Verwendung von $query->get_queried_object() eine Konsequenz hat. Es scheint, als würde die Verwendung dieser Wrapper-Funktion tatsächlich $ query selbst verändern, was ich am Ende meiner Funktion für unverändert gehalten habe. Es waren drei Filter in 2 Klassen beteiligt, die die Abfrage änderten: parse_query, posts_orderby, posts_join - und alle Rückruffunktionen riefen $query->get_queried_object() für das übergebene $query-Argument auf, um dann einige bedingte Tests auszuführen und manchmal die Abfragevariablen zu ändern (z. B. für eine spezielle Sortierreihenfolge) Fälle). Seltsamerweise funktionierten diese Funktionen tatsächlich einwandfrei für das, wofür sie entwickelt wurden, trotz meiner Verwendung der Funktion. Ich habe noch nie etwas falsches an der zurückgegebenen $ -Anfrage bemerkt!

Irgendwie hatte ich nach mehr als einem Jahr der Entwicklung und Nutzung an Dutzenden von Produktionsstandorten noch nie irgendwelche nachteiligen Auswirkungen von diesem Fehler erfahren. Erst als ich mich in hierarchische CPTs wagte, brach dieser kleine Unterschied plötzlich die Dinge. Das ist ein Teil dessen, was mich so sehr daran hinderte - so gut ich es beurteilen konnte, waren meine Abfragefilter vertrauenswürdig!

Ich muss zugeben, dass ich immer noch nicht genau weiß, warum der Aufruf dieser Funktion nur diesen einen kleinen Aspekt der CPT-Kinderseiten zerstört - und dennoch keine anderen Probleme aufwirft! Aber es war klar, dass die Verwendung innerhalb eines Filter-Callbacks den zurückgegebenen $query irgendwie verstümmelte. Durch das Entfernen dieses Aufrufs sind meine 404-Fehler verschwunden.

Vielen Dank für alle Tipps - wünschte, ich könnte das Kopfgeld aufteilen, da ich aus jeder Antwort Erkenntnisse gewinnen könnte, auch wenn die endgültige Lösung in keiner Beziehung stand. Dies war eine lehrreiche Lektion darin, Ihrem Code nicht blind zu vertrauen, auch wenn er lange Zeit zuverlässig für Sie gearbeitet hat oder keine offensichtlichen Fehler produziert.

Manchmal muss man, wie Kaisers Karte so gut verkörpert, einfach Schalter betätigen, bis die Lichter wieder angehen. In meinem Fall musste ich dieselbe Fehlerbehebungsstrategie bis hinunter zu den einzelnen Zeilen in einer Funktion anwenden, bevor ich das Problem erkennen konnte.

1
somatic

Ich nehme hier zum ersten Mal an Stack Exchange teil, aber ich werde es versuchen, um zu sehen, ob ich Ihnen dabei helfen kann, die richtige Richtung einzuschlagen.

Standardmäßig verhalten sich hierarchische CPTs genau so, wie Sie es beschrieben haben. Das eindeutige Slug-Präfix, in diesem Fall "Newsletter", soll der Rewrite-Engine mitteilen, wie Anforderungen für verschiedene Post-Typen voneinander unterschieden werden.

Diese CPT-Registrierungsargumente sehen gut aus, aber wenn ein CPT angefordert wird, sollte die Abfragevariable pagename keinen Wert haben, und die Abfragevariable name sollte hier mit newsletter identisch sein, sodass anscheinend irgendwo in Ihrem Setup ein Konflikt vorliegt.

Um das Debuggen zu unterstützen, installieren und aktivieren Sie das Rewrite Rules Inspector Plugin und rufen Sie den Bildschirm unter " Tools -> Rewrite Rules " auf.

  1. Wenn Sie sich die Liste ansehen, sollten alle Ihre Regeln für das CPT-Newsletter-Programm vor allen Regeln für das Umschreiben von Seiten aufgeführt sein. Überprüfen Sie, ob dies der Fall ist, indem Sie die Spalte " Source " durchsuchen.
  2. Wenn dies auscheckt, geben Sie die URL für Ihr CPT für den ersten Artikel in das Feld " URL abgleichen " ein und klicken Sie auf die Schaltfläche "Filter", um zu sehen, welche Regel abgeglichen wird. Es sollte mit einer Newsletter-Regel und einer Seitenregel übereinstimmen, aber die Newsletter-Regel sollte an erster Stelle stehen.

Wenn dies keine Probleme aufzeigt, durchsuchen Sie die Spalte post_name in wp_posts nach anderen Posts mit dem Slug "first-article", um festzustellen, ob möglicherweise eine Kollision vorliegt. Suchen Sie auch nach "Newsletter", nur um sicherzugehen.

Fügen Sie das folgende Snippet hinzu, um Ihre Abfragevariablen zu Beginn der Anforderung zu überprüfen und festzustellen, welche durch die Regelübereinstimmung zum Neuschreiben festgelegt werden (besuchen Sie das untergeordnete CPT im Front-End). Wenn die Variable pagename var hier nicht angezeigt wird, wird sie später in der Anforderung durch Folgendes festgelegt:

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;
}

Alle Plugins/Funktionen, die die Abfragevariablen ändern, können einen Konflikt verursachen. Deaktivieren Sie sie, wenn weiterhin Probleme auftreten. Leeren Sie auch Ihre Umschreiberegeln nach jedem Schritt, insbesondere wenn die Anforderung im zweiten Schritt oben mit einer falschen Regel übereinstimmte (lassen Sie den Bildschirm "Permalinks" in einem separaten Tab geöffnet und aktualisieren Sie ihn einfach).

14
Brady Vercher

Der parent/Child -Permalink funktioniert sofort, solange Sie ihn einstellen

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

Update:

Ich habe es gerade noch einmal getestet und es funktioniert wie erwartet, mit diesem Testfall:

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 );
}

und Permalink auf /%postname%/ gesetzt Ich bekomme Newsletter/Eltern/Kind gut funktioniert.

5
Bainternet

Abgesehen von der Frage "Haben Sie versucht, es aus- und wieder einzuschalten?" muss ich auch fragen: "Haben Sie Plugins aktiviert und tut Ihr Theme etwas für die Permalinks (z. B. : Taxonomie registrieren, Beitragstypen hinzufügen, Umschreiberegeln hinzufügen, etc.)?

Wenn ja: Tritt dies immer noch auf, nachdem Sie alle Plugins deaktiviert und auf TwentyEleven umgestellt haben? enter image description here

Um weiter zu debuggen, gehe zu GitHub und nimm Toschos "Rewrite" Plugin . Wechseln Sie dann zum offiziellen Plugin-Repo auf wp.org und greifen Sie auf das MonkeyManRewriteAnalyzer-Plugin zu. Ich habe sogar eine kleine Erweiterung geschrieben, um beide ein bisschen zusammenzukleben. Dadurch erhalten Sie viele Details zu Ihrem Setup.

3
kaiser