Regeln für den benutzerdefinierten Post-Typ, der an einen anderen benutzerdefinierten Post-Typ “angefügt” wurde, umschreiben

Ich habe zwei benutzerdefinierte Post-Typen: nennen wir sie location und topic . Der benutzerdefinierte Post-Typ des Standorts ist hierarchisch. Alle Artikel werden mit einem Post-Meta an einen einzigen Ort “angefügt”. Wenn es darauf ankommt, enthält der topic Beitragstyp ein benutzerdefiniertes Metabox, das ein Dropdown-Feld der locations , die die Verwendung von:

 update_post_meta( $post->ID, 'my-prefix-location', $the_location ); 

Ich möchte den Standort so umschreiben, dass die URLs https://my.domain.tld/location/sub-location/sub-sub-location/topic/ .

Für den Speicherort habe ich beim Registrieren des Post-Typs versucht, das folgende Umschreibungsargument zu verwenden:

 'rewrite' => [ 'slug' => '/', 'with_front' => false, ], 

Das funktioniert für die Standorte gut, aber ich kann auf keine der Themen zugreifen, auch nicht nach dem manuellen Löschen der Umschreibregeln. Wenn ich sie mit /?id=100 , werden sie nach /topic/slug/ umgeleitet (was nicht die gewünschte URL-Struktur ist), aber es ergibt sich ein 404.

Aber selbst wenn ich dieses Problem löse, habe ich keine Ahnung, wie ich die URLs für die Themen neu schreiben soll, damit sie die Struktur des angefügten Standorts haben.

Ich denke, ich muss add_rewrite_rule() und / oder add_rewrite_endpoint() . Ich habe noch nie zuvor eine dieser functionen benutzt. Alle Hinweise würden geschätzt werden. Gehe ich in die falsche Richtung?


[Hinzugefügt]

Ich glaube also nicht, dass ich in der Lage sein werde, das zu tun, was ich will (oder überhaupt). Was ich jetzt versucht habe ist, meine Permalinks zu haben:

 /topic/directory/to/my/location/page_name/ 

Es ist einfach genug, eine Rewrite-Regel hinzuzufügen, um alles außer dem letzten Parameter zu ignorieren und darauf zu antworten:

 add_rewrite_rule( 'topic/(.*)/([^/]+)/?$', 'index.php?topic=$matches[2]', 'top' ); 

Und das würde gut funktionieren, außer dass ich möchte, dass die kanonische URL die (*.) Hierarchische URL-Struktur der Kategorie hat, an die das Thema angehängt ist und alle anderen topic/*/leaf/ URLs auf diese verweisen.

Mir fällt es schwer, herauszufinden, wie das geht oder ob es möglich ist.

Solutions Collecting From Web of "Regeln für den benutzerdefinierten Post-Typ, der an einen anderen benutzerdefinierten Post-Typ “angefügt” wurde, umschreiben"

Die functionsweise der WordPress-Umschreibungsregeln (mit einigen speziellen Ausnahmen), verschiedene Inhaltstypen haben eine Art von einzigartigem Element für ihre URLs, die WP in die Lage versetzt, den gesuchten Inhalt in der database zu identifizieren und danach zu suchen. Zum Beispiel, angesichts der URL:

 /topic/one/two/three/ 

Sie können nicht mit Sicherheit sagen, ob three ein Standort oder ein Thema ist, wenn beide Standorte und Themen denselben topic Stamm haben.

Der komplizierte Teil besteht darin, dass Sie diese Zweideutigkeit manuell auflösen müssen. Das hat einen Nachteil – jede Anfrage nach etwas, das möglicherweise ein Thema sein könnte, erfordert eine zusätzliche Abfrage der database, was kein großes Problem ist, aber etwas, das beachtet werden muss.

In Ihrer ursprünglichen Frage haben Sie den Wunsch geäußert, die benutzerdefinierte Post-Typ-Basis zu entfernen. Die Antwort, die ich hier geben werde, verwendet das topic als Basis. Wenn Sie das entfernen, wird der page in die gesamte Mischung geworfen. Sie können es vielleicht mit dieser Lösung ausarbeiten, aber um Ihnen nur die einfachste Form zu zeigen, wie das funktioniert, werde ich das nicht tun.

Schritt 1

Fügen Sie ein neues %parent_location% rewrite -Tag hinzu, das den Platzhalter für den Speicherort eines Themas darstellt. Dies geschieht bei der init Aktion zusammen mit Ihren Regeln:

 add_rewrite_tag( '%parent_location%', '(.+)' ); 

Schritt 2

Registrieren Sie Ihre Post-Typen. Ich werde die grundlegenden Sachen weglassen und mich auf die spezifischen Teile konzentrieren, die das funktionieren lassen. Dies alles geschieht auch auf der init Aktion. Vergessen Sie nicht, die Umschreibregeln zu löschen, nachdem Sie diese hinzugefügt haben.

Für Standorte ist der Root-Slug topic , und der Post-Typ ist hierarchisch.

 $args = array( 'rewrite' => array( 'slug' => 'topic' ), 'hierarchical' => true, // ... your other args ); register_post_type( 'location', $args ); 

Für Themen haben wir das neue %parent_location% rewrite -Tag in den Slug %parent_location% . Wir verwenden dies, um den Ort in der URL zu ersetzen. Die Rewrite-Regeln, die dabei generiert werden, werden nie wirklich übereinstimmen, aber es erleichtert die nächsten Schritte.

 $args = array( 'rewrite' => array( 'slug' => 'topic/%parent_location%' ), // ... your other args ); register_post_type( 'topic', $args ); 

Schritt 3

Fügen Sie post_type_link einen Filter post_type_link , um den Standortpfad für unser %parent_location% -Tag zu vertauschen, wenn ein Permalink für dieses Thema angefordert wird. Sehen Sie sich die Kommentare an, um zu sehen, was passiert.

 function wpd_topic_link( $link, $post ) { // if this is a topic post if ( $post->post_type === 'topic' ) { // if there is location ID meta saved for this post under parent_location key if( $location_id = get_post_meta( $post->ID, 'parent_location', true ) ){ // query for that post to make sure it exists $location_post = get_posts( array( 'post_type' => 'location', 'p' => $location_id ) ); if( !empty( $location_post ) ){ // get the location permalink // strip out everything except the location parts of the URL // substitute that value for our %parent_location% placeholder $location_link = get_permalink( $location_post[0] ); $location_path = untrailingslashit( str_replace( home_url( '/topic/' ), '', $location_link ) ); $link = str_replace( '%parent_location%', $location_path, $link ); } } } return $link; } add_filter( 'post_type_link', 'wpd_topic_link', 20, 2 ); 

Wenn Sie nun einen Themenbeitrag hinzufügen und eine gültige Standort-ID in Post-Meta speichern, wird dieser Pfad beim Bearbeiten dieses Themenbeitrags in der URL angezeigt.

Schritt 4

Filtern Sie die request , um nach Anforderungen für einen Standort zu suchen, der möglicherweise ein Thema ist. Lesen Sie die Kommentare durch, um zu verstehen, was passiert. Ein weiterer Nebeneffekt, den Sie hier notieren sollten – Sie können nie einen Standort-Slug haben, der auch ein Thema ist.

 function wpd_locations_may_be_topics( $request ){ // if the location query var is set if( isset( $request['location'] ) ){ // location will be a parent / child hierarchy // make it an array of URL segments $parts = explode( '/', $request['location'] ); // it might be a topic only if there's more than a single segment if( count( $parts ) > 1 ){ $topic_slug = end( $parts ); $maybe_topic = get_posts( array( 'post_type' => 'topic', 'name' => $topic_slug ) ); // if a topic was returned if( !empty( $maybe_topic ) ){ // change request from location to topic unset( $request['location'] ); $request['post_type'] = 'topic'; $request['topic'] = $topic_slug; } } } return $request; } add_filter( 'request', 'wpd_locations_may_be_topics' );