Entfernen des Basis-Slugs aus dem hierarchischen benutzerdefinierten Post-Typ

Ich habe einen hierarchischen benutzerdefinierten Post-Typ namens “state”. Mein Ziel ist es, eine Permalink-Struktur wie folgt zu haben:

http://website.com/idaho/ http://website.com/idaho/sub-page

Ich bin nah dran , habe es aber noch nicht herausgefunden. Hier ist der Code, den ich verwende:

Zuerst entferne ich die Schnecke

public function remove_slugs( $permalink, $post, $leavename ) { $url_components = parse_url( $permalink ); $post_path = $url_components['path']; $post_name = end( explode( '/', trim( $post_path, '/' ) ) ); if( !empty( $post_name )) { switch($post->post_type) { case 'state': if( $post->post_parent ) { $parent = get_post( $post->post_parent ); $parent = $parent->post_name; $permalink = str_replace( $post_path, '/' . $parent . '/' . $post_name . '/', $permalink ); } else { $permalink = str_replace( $post_path, '/' . $post_name . '/', $permalink ); } break; } } return $permalink; } 

Dies ist in post_type_link .

Als nächstes setze ich die Abfragevariablen zurück, so dass WordPress weiß, dass es sich um einen CPT handelt

  public function parse_custom_post_type( $query ) { if ( ! $query->is_main_query() ) return; if ( count( $query->query ) != 2 || ! isset( $query->query['page'] ) ) return; // Are we dealing with a page? if ( ! empty( $query->query['pagename'] ) && ! is_home() ) { // If the page doesn't exist, we must be dealing with a state if ( ! is_page( $query->query['pagename'] ) ) { $query->set( 'name', $query->query['pagename'] ); $query->set( 'state', $query->query['pagename'] ); $query->set( 'post_type', 'state' ); $query->is_page = 0; $query->is_single = 1; unset( $query->query_vars['page'] ); unset( $query->query_vars['pagename'] ); unset( $query->query['page'] ); unset( $query->query['pagename'] ); } } } 

Dies wird in pre_get_posts .

Also funktionieren die Level- One- Seiten, aber nicht die Unterseiten. Die URLs werden aufgetriggers und dann auf 404 geklickt.

Was muss ich tun, damit das funktioniert?

Solutions Collecting From Web of "Entfernen des Basis-Slugs aus dem hierarchischen benutzerdefinierten Post-Typ"

Vorwort

Zwei Dinge bevor ich beginne:

  1. Du solltest das wirklich nicht tun. Statische Anker zum Umschreiben von Regeln haben ihre Effizienz. Ihre beste Wette ist es, eine Schnecke zu finden, mit der Sie zufrieden sind – vielleicht statt “Staat” verwenden Sie “Aktivitäten” (oder was auch immer Ihre Unterseiten sind).
  2. Höchstwahrscheinlich sind Ihre Unterseiten nicht wirklich Zustände (da Sie / idaho / vermont / nicht haben würden), daher scheint diese Datenstruktur nicht viel Sinn zu ergeben. Sie könnten in Betracht ziehen, dass “state” eine Datenstruktur und “sub-page” eine andere sein soll. Wenn der Status eine Klassifizierung ist, können Sie eine Taxonomie erstellen. Wenn state mehr ist, könnte es ein Post-Typ sein. Hier finden Sie statementen zum Einrichten von Umschreibungen für den ersten von einem WordCamp-Vortrag, den ich in Portland gegeben habe, und hier sind statementen für Letzteres aus einer anderen Frage auf dieser Website.

Der Code

Wenn Sie sich entscheiden, mit dieser Struktur fortzufahren, ist hier eine Singleton-class, die für Sie funktionieren sollte, wenn Ihr Post-Typ “hierarchisch” auf “true” und “rewrite” auf “false” gesetzt hat. Achten Sie darauf, Ihre Umschreibungen zu löschen, nachdem Sie diese der functions.php-Datei Ihres Themes oder Ihrem Plugin hinzugefügt haben (gehen Sie zu Einstellungen → Permalinks und klicken Sie auf “Änderungen speichern”).

 /** * Strip the slug out of a hierarchical custom post type */ if ( !class_exists( 'State_Rewrites' ) ) : class State_Rewrites { private static $instance; public $rules; private function __construct() { /* Don't do anything, needs to be initialized via instance() method */ } public static function instance() { if ( ! isset( self::$instance ) ) { self::$instance = new State_Rewrites; self::$instance->setup(); } return self::$instance; } public function setup() { add_action( 'init', array( $this, 'add_rewrites' ), 20 ); add_filter( 'request', array( $this, 'check_rewrite_conflicts' ) ); add_filter( 'state_rewrite_rules', array( $this, 'strip_state_rules' ) ); add_filter( 'rewrite_rules_array', array( $this, 'inject_state_rules' ) ); } public function add_rewrites() { add_rewrite_tag( "%state%", '(.+?)', "state=" ); add_permastruct( 'state', "%state%", array( 'ep_mask' => EP_PERMALINK ) ); } public function check_rewrite_conflicts( $qv ) { if ( isset( $qv['state'] ) ) { if ( get_page_by_path( $qv['state'] ) ) { $qv = array( 'pagename' => $qv['state'] ); } } return $qv; } public function strip_state_rules( $rules ) { $this->rules = $rules; # We no longer need the attachment rules, so strip them out foreach ( $this->rules as $regex => $value ) { if ( strpos( $value, 'attachment' ) ) unset( $this->rules[ $regex ] ); } return array(); } public function inject_state_rules( $rules ) { # This is the first 'page' rule $offset = array_search( '(.?.+?)/trackback/?$', array_keys( $rules ) ); $page_rules = array_slice( $rules, $offset, null, true ); $other_rules = array_slice( $rules, 0, $offset, true ); return array_merge( $other_rules, $this->rules, $page_rules ); } } State_Rewrites::instance(); endif; 

Ich fand das Thema interessant und habe auf meinem Blog eine ausführliche Erklärung dazu geschrieben. Dort habe ich etwas komplexeren Code eingefügt, der für Ihre spezifische Frage nicht relevant war.