Hierarchische benutzerdefinierte Post-Typ-Permalinks funktionieren wie Seiten

16

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-Listen, 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 konstruiert 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 meinen benutzerdefinierten Post - Typ Kindern und normaler Seite Kindern, ist , dass mein CPT die Schnecke zu Beginn der Permalink - Struktur hat, dann von den Eltern / Kind - Schnecken gefolgt (wo Seiten nur mit den Eltern / Kind - Schnecken 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 verwundert, ist, wenn ich die query_vars für diese 404-Seite untersuche - sie scheinen die richtigen Werte zu enthalten, damit WP meine untergeordneten Seiten "findet", 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 dies mit verschiedenen Themen versucht, darunter auch mit zwölf, nur um sicherzugehen, dass es nicht irgendeine fehlende Vorlage meinerseits ist.

Mit dem Rewrite Rules Inspector wird Folgendes für die URL angezeigt: http://meinesite.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
)
somatisch
quelle

Antworten:

14

Ich nehme 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 Beitragstypen voneinander unterschieden werden.

Diese CPT-Registrierungsargumente sehen gut aus, aber wenn ein CPT angefordert wird, sollte die pagenameAbfragevariable keinen Wert haben und die nameAbfragevariable sollte derselbe sein wie newsletterhier, sodass es den Anschein hat, dass 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 dann den Bildschirm unter " Extras -> Rewrite Rules " auf.

  1. Wenn Sie sich die Liste ansehen, sollten alle Ihre Regeln für das CPT für Newsletter aufgeführt sein, bevor Sie Regeln zum Umschreiben von Seiten festlegen. Überprüfen Sie, ob dies der Fall ist, indem Sie die Spalte " Quelle " scannen .
  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 festzustellen, 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 post_nameSpalte wp_postsnach 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 pagenameVariable hier nicht angezeigt wird, wird sie zu einem späteren Zeitpunkt in der Anforderung 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).

Brady Vercher
quelle
Ich habe die Frage bearbeitet, um die Ausgabe des Inspektors für das Umschreiben von Regeln anzuzeigen, da diese Kommentare nicht genügend Formatierung zulassen. Die Regeln für das CPT werden vor allem oben in der Liste angezeigt. Sie sind sich jedoch nicht sicher, welche der folgenden Regeln "Seiten" -Regeln sind (nicht klar). Auch keine Kollisionen in der post_nameSpalte.
somatische
Hast du irgendwelche Gedanken zur richtigen Permalink-Struktur? Ich bin /%postname%/seither zurückgegangen, /%category%/was die Dinge im Rewrite Inspector nur noch weiter zu verwirren scheint. Ich habe sogar Leute gesehen, die behaupteten, dass /%category%/CPTs auf magische Weise "Eltern" bedeuten, obwohl ich dies nicht für wahr halte.
Somatic
Diese Ausgabe scheint für ein anderes Plugin zu kommen, weshalb die "Quelle" der Regel nicht angezeigt wird. Wie auch immer, Ihre Regel scheint in Ordnung zu sein. Ich habe meine Antwort so bearbeitet, dass sie ein Snippet enthält, mit dem die Abfragevariablen zu einem früheren Zeitpunkt in der Anforderung überprüft werden, um sicherzustellen, dass sie korrekt eingestellt sind.
Brady Vercher
Was die Permalink-Struktur angeht, bin ich kein Fan davon, die Kategorie einzuschließen. Es ist nur ein weiterer beweglicher Teil, der nichts hilft, und Beiträge können mehreren Kategorien angehören. Wenn es überhaupt eine Chance gibt, dass Sie die Permalink-Struktur in Zukunft ändern oder einen anderen CPT ohne ein Slug-Präfix laden möchten, würde ich empfehlen, Ihre Struktur mit einem festen und eindeutigen Namensraum wie "Namespacing" zu versehen /blog/%postname%/.
Brady Vercher
Es ist das richtige Plugin, aber es gibt zwei Seiten: "Rewrite Analyzer" und "Rewrite Rules", beide mit einer Test-URL. Ich habe die andere Seite ausprobiert und sie zeigte die Quelle als "Programm" für die erste eingerückte Gruppe und "Seite" für die zweite.
somatic
5

Der parent/ChildPermalink funktioniert sofort, solange Sie ihn einstellen

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

Aktualisieren:

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

Bainternet
quelle
Mein Code oben zeigte es nicht, aber ich habe page-attributes in den Unterstützungen (was eigentlich nur darum geht, die Metabox für die Zuweisung der Abstammung zu zeigen, sollte sich nicht auf Permalinks auswirken) - aber 404 bekommen. Welche Permalink-Struktur muss eingestellt werden? oder spielt es eine rolle
somatic
@somatic Ich habe es gerade noch einmal getestet und es funktioniert einwandfrei. Was den Permalink angeht, bin ich mir nicht sicher, ob es wichtig sein sollte, aber auf irgendeine Weise habe ich meine Antwort aktualisiert.
Bainternet
Ich kann bestätigen, dass mit dem Hinzufügen eines Argumentarrays für 'labels' (ohne das CPT nicht in admin angezeigt wird) dieses grundlegende Beispiel für eine Vanilla-Installation von WP3.5 mit Twentytwelve funktioniert. Aber ich bemerke ein paar wichtige Unterschiede in Ihren register_post_typeArgumenten: Ich habe verwendet 'rewrite' => array( 'slug' => 'newsletter', 'with_front' => false ), wo Sie gerade verwendet haben true. Sie auch einfach übergeben truefür has_archive, wo ich die Schnecke geleitet. Als ich jedoch Ihren Argumenten entsprach, bekam ich immer noch 404 ... Ich versuche immer noch, herauszufinden, wo ich falsch liege.
Somatic
3

Abgesehen von der Frage »Haben Sie versucht, es aus- und wieder einzuschalten?« , Muss ich Sie auch fragen: »Haben Sie Plugins aktiviert und tut Ihr Theme irgendetwas mit den Permalinks (zum Beispiel: Taxonomie registrieren, Beitragstypen, Regeln zum Umschreiben hinzufügen , etc.)?

Wenn ja: Geschieht dies immer noch, nachdem Sie alle Plugins deaktiviert und auf TwentyEleven umgestellt haben? Bildbeschreibung hier eingeben

Um weiter zu debuggen, gehen Sie zu GitHub und holen Sie sich das 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.

Kaiser
quelle
Nun, wenn ich alles deaktiviere , werde ich nicht den benutzerdefinierten Post-Typ haben, auf den sich diese Frage bezieht ... aber ja, ich habe es sogar mit dem Thema "Twentytwelve" versucht. Ich stöbere immer noch in den wenigen notwendigen Steckern, um zu sehen, was die Abfrage verstümmelt. Wie ich sehe, sind die Permalinks selbst wohlgeformt.
somatic
@ somatic Natürlich nicht deaktivieren Sie :)
Kaiser
@somatic Siehe Update.
Kaiser
1

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) , etc). 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.

Da habe ich festgestellt, dass die Verwendung eine Konsequenz hat $query->get_queried_object(). Es scheint, als würde die Verwendung dieser Wrapper-Funktion tatsächlich $ query selbst modifizieren. Ich dachte, ich würde am Ende meiner Funktion unverändert zurückkehren. Drei Filter über zwei Klassen waren daran beteiligt , dass die Abfrage geändert: parse_query, posts_orderby, posts_join- und alle der Callback - Funktionen wurden Aufruf $query->get_queried_object()an dem bestandenen $queryARG dann einige bedingten Tests ausgeführt und manchmal ändern die Abfrage Vars (wie für spezielle Sortierreihe Fälle). Seltsamerweise funktionierten diese Funktionen trotz allem einwandfrei meiner Verwendung der . Ich habe noch nie etwas falsches an der zurückgegebenen $ -Anfrage bemerkt!

Irgendwie hatte ich nach mehr als einem Jahr Entwicklung und Einsatz an Dutzenden von Produktionsstandorten noch nie negative Auswirkungen durch diesen 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 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 die zurückgegebenen $queryWerte irgendwie verstümmelte . Durch das Entfernen dieses Aufrufs sind meine 404-Fehler verschwunden.

Vielen Dank für alle Tipps - ich wünschte, ich könnte das Kopfgeld aufteilen, da ich aus jeder Antwort einen Einblick gewinnen könnte, selbst wenn die endgültige Lösung in keiner Beziehung zueinander steht. 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.

somatisch
quelle
Sie können die Wrapper-Funktion auch verwenden, get_queried_object()ohne das $wpdbObjekt abzufangen .
Kaiser
aber was $querypackt das? Ich benutze dies in einem Filter für parse_queryund muss speziell das abgefragte Objekt eines bestimmten abrufen $query, das vom Filter übergeben wird ...
somatic
Ich habe gerade versucht, den Wrapper in meinem Filter für zu verwenden parse_query. Es verursachte wieder die gleichen 404-Fehler. Ich muss einen Weg finden, um zu replizieren, was get_queried_object()funktioniert, ohne diese Filter zu verschmutzen ...
somatisch
-2

Laufen Sie die aktuellste Version von WP? Ich denke, das ist die erste Frage (wie wenn Sie den technischen Support anrufen und gefragt werden, ob Ihr Computer angeschlossen ist!), Da ich gelesen habe, dass dieses Problem im aktuellsten Versionsupdate behoben wurde.

Auf digwp.com gibt es einen Beitrag, 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. Wenn Sie Ihre URLs mit einer textbasierten Option beginnen, löst WP ein Flag aus, das eine Regel für jede Seite / jeden Beitrag erstellt, die bzw. der Sie haben. Wenn Sie viel Inhalt auf Ihrer Website haben, kann dies zu einer großen Anzahl von Anfragen führen, und auf Ihrem Server tritt wahrscheinlich eine Zeitüberschreitung auf, die zu einer Reihe von 404 führt, selbst wenn die Seiten vorhanden sind.

So. Wenn Sie zuerst eine zahlenbasierte Struktur verwenden, dann Ihre textbasierte Struktur, würde ich wetten, dass Ihr 404-Problem behoben ist. In Anbetracht von SEO-Problemen würde ich keine Datumsstruktur verwenden, aber diese Entscheidung wird für Sie logisch genug sein.

Melanie Sumner
quelle
2
Ich bin am 3.5. Ab WP3.3.1 ist dieses Problem bei Digiwp behoben.
Somatic