Das Erstellen von hierarchischen benutzerdefinierten Post-Typ-Permalinks funktioniert genau wie Seiten

Ich habe hier alle Fragen zu benutzerdefinierten Post-Typ-Permalinks geklärt, aber die meisten scheinen entweder Probleme mit benutzerdefinierten Taxonomie-Umschreibungen zu sein oder mit dem offensichtlichen Fehlen von flush_rewrite_rules (). Aber in meinem Fall verwende ich nur einen benutzerdefinierten Post-Typ (keine Taxonomie), der hierarchisch gesetzt ist (damit ich Eltern-Kind-Beziehungen zuweisen kann), mit der richtigen “Unterstützung” für die Attribute Metabox, usw., usw. I Ich habe viele verschiedene Regeln neu geschrieben. Ich habe verschiedene Permalink-Strukturen ausprobiert. Aber untergeordnete URLs führen immer zu 404!

Ich hatte ursprünglich unabhängige benutzerdefinierte Post-Typen für die “Eltern” und “Kind” -Elemente (mit p2p), und ich hätte wahrscheinlich keine Probleme mit einer Taxonomie für die “elterliche” Gruppierung – ich weiß, dass diese semantisch genauer wäre. Aber für den Kunden ist es am einfachsten für sie, die Hierarchie zu visualisieren, wenn die “Posts” im Admin angezeigt werden, genauso wie die Seiten: ein einfacher Baum, in dem Kinder unter dem Elternteil mit dem Präfix “-” und in der richtige Reihenfolge. Außerdem können verschiedene Verfahren zum Zuweisen einer Reihenfolge über Drag-and-Drop verwendet werden. Gruppierung über Taxonomie (oder P2P) führt zu einer flachen Liste von “Posts” in den Admin-Listings, was einfach nicht so offensichtlich ist.

Also, was ich bin, ist buchstäblich das gleiche Verhalten wie core “Seiten”, aber mit meinem benutzerdefinierten Beitragstyp. Ich habe den Post-Typ wie erwartet registriert, und im Admin funktioniert es perfekt – ich kann einen Eltern- und einen menu_order für jeden Newsletter “post” zuweisen, sie erscheinen korrekt in den Bearbeitungslisten:

Spring 2012 — First Article — Second Article 

Und ihre Permalinks scheinen richtig aufgebaut zu sein. In der Tat, wenn ich etwas an der Struktur ändere, oder sogar den Umschreibungs-Slug ändere, wenn ich den Post-Typ registriere, werden sie automatisch korrekt aktualisiert, also weiß ich, 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 genauso aus im Admin, aber sie arbeiten tatsächlich auch auf dem Front-End (Eltern und Kind URLs funktionieren gut).

Meine Permalink-Struktur ist festgelegt auf:

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

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

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

Meine Register-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 meinen benutzerdefinierten Post- Children und normalen Child-Seiten ist, dass mein CPT den Slug am Anfang der Permalink-Struktur hat, gefolgt von den Parent / Child-Slugs (wo die Seiten gerade mit den Parent / Child-Slugs beginnen, kein “Präfix”). Warum das alles verderben würde, weiß ich nicht. Viele Artikel scheinen zu zeigen, dass sich solche hierarchischen CPT-Permalinks genau so verhalten sollten – aber meine, obwohl schön geformt, funktionieren nicht.

Was mich auch verwirrt, ist, wenn ich die query_vars für diese 404-Seite untersuche – sie scheinen die korrekten 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 das mit verschiedenen Themen versucht, einschließlich Twenty Twelve, nur um sicher zu gehen, dass es keine fehlende Vorlage von meiner Seite ist.

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 Überarbeitung würde mich glauben lassen, dass der folgende “nicht-schöne” Permalink funktionieren würde:

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

Es ist nicht 404, aber es zeigt den übergeordneten CPT-Artikel “Newsletter”, nicht das Kind. Die Anfrage sieht folgendermaßen aus:

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

Solutions Collecting From Web of "Das Erstellen von hierarchischen benutzerdefinierten Post-Typ-Permalinks funktioniert genau wie Seiten"

Das ist das erste Mal, dass ich hier an Stack Exchange teilnehme, aber ich werde es versuchen und sehen, ob ich Ihnen helfen kann, Sie in die richtige Richtung zu lenken.

Standardmäßig verhalten sich hierarchische CPTs genau so, wie Sie es beschrieben haben. Das einzigartige Slug-Präfix, in diesem Fall “Newsletter”, soll der Rewrite-Engine die Möglichkeit geben, Anfragen für verschiedene Post-Typen zu unterscheiden.

Diese CPT-Registrierungsargumente sehen gut aus, aber wenn ein CPT angefordert wird, sollte der pagename query var keinen Wert haben und der name quer var sollte hier derselbe sein wie der newsletter , daher scheint es irgendwo in Ihrem Setup einen Konflikt zu geben.

Um das Debuggen, Installieren und Aktivieren des Rewrite Rules Inspector Plugins zu erleichtern , besuchen Sie den Bildschirm unter ” Extras -> Regeln neu schreiben “.

  1. Wenn Sie sich die Liste ansehen, sollten alle Ihre Regeln für den Newsletter CPT vor den Regeln zum Umschreiben der Seite aufgeführt sein. Überprüfen Sie dies, indem Sie die Spalte ” Quelle ” scannen.
  2. Wenn das auscheckt, geben Sie die URL für Ihren “First-article” CPT in das Feld ” Match URL ” ein und klicken Sie auf “Filter”, um zu sehen, welche Regel übereinstimmt. Es sollte mit einer Newsletter-Regel und einer Seitenregel übereinstimmen, aber die Newsletter-Regel sollte Vorrang haben.

Wenn dies keine Probleme post_name , durchsuchen Sie die Spalte post_name in wp_posts , um nach anderen Posts mit dem wp_posts “First-article” zu wp_posts , um wp_posts , ob eine Kollision wp_posts . Suchen Sie auch nach “Newsletter”, nur um sicher zu sein.

Fügen Sie das folgende Snippet hinzu, um Ihre Abfrage-Vars frühzeitig in der Anfrage zu prüfen und zu sehen, welche durch die Umschreibungsregel-Übereinstimmung gesetzt werden (besuchen Sie die untergeordnete CPT am Frontend). Wenn der pagename Var hier nicht pagename wird, wird er später in der Anforderung durch etwas festgelegt:

 add_filter( 'request', 'se77513_display_query_vars', 1 ); function se77513_display_query_vars( $query_vars ) { echo '
' . print_r( $query_vars, true ) . '

'; return $query_vars; }

Alle Plugins / functionen, die die Abfragevariablen ändern, können einen Konflikt verursachen. Deaktivieren Sie sie daher, wenn weiterhin Probleme auftreten. Leeren Sie auch die Umschreibregeln nach jedem Schritt, insbesondere wenn die Anfrage im zweiten Schritt zu einer falschen Regel passt (lassen Sie den “Permalinks” -Bildschirm in einem separaten Tab geöffnet und aktualisieren Sie ihn einfach).

Der parent/Child Permalink functioniert so lange wie Sie festgelegt haben

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

Aktualisieren:

Ich habe es gerade wieder 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%/ Ich bekomme Newsletter / Eltern / Kind funktioniert gut.

Abgesehen von der Frage »Hast du versucht, es aus- und wieder einzuschalten?« , Muss ich auch fragen: »Hast du irgendwelche Plugins aktiviert und ist dein Theme etwas mit den Permalinks zu tun (zB: Taxonomie registrieren, Post-Typen, Rewrite-Regeln hinzufügen , etc.)?

Falls ja: Tritt das immer noch auf, nachdem du alle Plugins deaktiviert und zu TwentyEleven gewechselt hast? Bildbeschreibung hier eingeben

Um weiter zu debuggen, gehen Sie zu GitHub und greifen Sie auf das Toschos “Rewrite” -Plugin zu . Dann wechsle zum offiziellen Plugin Repo auf wp.org und erstelle das MonkeyManRewriteAnalyzer Plugin . Ich habe sogar eine kleine Erweiterung geschrieben, um beide zusammen zu kleben. Dadurch erhalten Sie viele Details zu Ihrer Einrichtung.

Nachdem ich bestätigt hatte, dass ich das erwartete hierarchische Seitenverhalten mit einer komplett sauberen Installation und nur einer einzigen CPT-Deklaration bekommen konnte, wusste ich, dass der Fehler irgendwo in meinem eigenen Plugin liegt, das ich für die CPT-Erstellung verwende (sehr komplex, handhabt benutzerdefinierte Metaboxen, Taxonomien) , etc). Das Problem war, trotz aller Ratschläge, nach Neuschreib- oder Abfrageproblemen zu suchen, konnte ich nichts offensichtlich falsches sehen. Ich habe jeden Filter und jeden Haken überprüft, die Abfrage an jedem Punkt betrachtet und nichts gesehen, was den 404 verursacht hätte.

So blieb mir die Aufgabe, jede der 9 großen classn manuell zu deaktivieren / zu aktivieren und dann mindestens zwei von ihnen zu finden, die 404 verursachten, jede function nacheinander durchlaufen und sie deaktivieren und aktivieren und dann die Linie verfolgen nach Linie innerhalb dieser functionen – ein roher Gewaltversuch, um genau zu sehen, was den 404 verursachte, selbst wenn ich nicht warum wusste.

Das ist der Zeitpunkt, an dem ich festgestellt habe, dass $query->get_queried_object() . Es scheint, dass die Verwendung dieser Wrapper-function tatsächlich die $ query selbst modifiziert, die ich am Ende meiner function unverändert zurückgegeben habe. Es waren drei Filter über zwei classn beteiligt, die die Abfrage parse_query : parse_query , posts_orderby , posts_join – und alle Callback-functionen riefen $query->get_queried_object() für das übergebene $query arg auf, um dann bedingte Tests auszuführen und manchmal die Abfrage zu modifizieren vars (wie für spezielle Sortierreihenfolgen). Seltsamerweise funktionierten diese functionen trotz ihrer Verwendung der function tatsächlich in dem, was sie zu tun beabsichtigten. Ich habe vorher noch nie etwas falsch mit der zurückgegebenen $ Abfrage bemerkt!

Irgendwie hatte ich nach mehr als einem Jahr der Entwicklung und Nutzung auf Dutzenden von Live-Produktionsstandorten keinerlei negative Auswirkungen von diesem Fehler. 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 damit beschäftigt hat – so gut ich das beurteilen konnte, meine Abfragefilter waren vertrauenswürdig!

Ich gestehe, ich weiß immer noch nicht genau, warum der Aufruf dieser function nur diesen einen kleinen Aspekt der CPT-Kinderseiten unterbricht – und noch nie irgendwelche anderen Probleme gezeigt hat! Aber es war klar, dass die Rückgabe der $query irgendwie fehlte, wenn man sie innerhalb eines Filter-Callbacks verwendete. Durch das Entfernen dieses Anrufs verschwanden meine 404-Fehler.

Danke für all die Tipps – ich wünschte, ich könnte das Kopfgeld teilen, da ich aus jeder Antwort Einsichten gewinnen konnte, selbst wenn die ultimative Lösung nicht verwandt war. Dies war eine Lehrstunde, wenn Sie Ihrem Code nicht blind vertrauen, auch wenn er lange Zeit zuverlässig für Sie arbeitet oder keine offensichtlichen Fehler hervorruft.

Manchmal, wie die Karte von kaiser so gut verkörpert, müssen Sie nur Schalter casting, bis die Lichter wieder angehen. In meinem Fall musste ich die gleiche Fehlersuchstrategie bis zu den einzelnen Zeilen in einer function durchführen, bevor ich das Problem sehen konnte.

Führen Sie die aktuellste Version von WP aus? Ich denke, das ist die erste Frage (wie wenn du den technischen Support anrufst und sie dich fragen, ob dein Computer angeschlossen ist!), Da ich gelesen habe, dass dieses Problem im aktuellsten Versions-Update behoben wurde.

Es gibt einen Beitrag auf digwp.com, der dieses Problem behebt (http://digwp.com/2011/06/dont-use-postname/). Anscheinend kann WP den Unterschied zwischen Beiträgen und Seiten nicht leicht erkennen, und wenn Sie Ihre URLs mit einer textbasierten Option starten, triggers WP ein Flag aus, das für jede Seite / Post eine Regel erstellt. Wenn Sie viele Inhalte auf Ihrer Site haben, kann dies zu einer großen Anzahl von Anfragen führen und Ihr Server wird wahrscheinlich eine Zeitüberschreitung haben, was zu einer Menge von 404s führt, selbst wenn die Seiten da sind.

Damit. Wenn Sie zuerst eine auf Zahlen basierende Struktur und dann Ihre textbasierte Struktur verwenden, wette ich, dass Ihr 404-Problem getriggers wird. Nun, in Bezug auf SEO-Probleme, würde ich keine Datumsstruktur verwenden, aber diese Entscheidung zu treffen ist logisch genug für Sie.