it-swarm.com.de

Permalinks für CPT unterbrechen Permalinks zu Seiten

Ich habe einen CPT, für den ich die 'root'-Permalinks haben möchte:

Also für die Seite: 'Foo Bar' hätte ich gerne die URL:

https://example.org/foo-bar

Ich habe herausgefunden, dass ich dies erreiche, indem ich das CPT mit der folgenden Zeile in der args für register_post_type( 'my_CPT', $args ); registriere:

'rewrite' => array('slug' => '/', 'with_front' => false)

Allerdings ... Wenn ich das hinzufüge, funktionieren meine Permalinks für meine Seiten nicht. Ich würde ihnen im Idealfall diese Permalinks geben:

https://example.org/page/some-page

Wie mache ich das?

2
Zeth

Seiten sind fest codiert, um die Standard-Parsing-Möglichkeit für jede URL zu sein (oder anders ausgedrückt, wenn nichts anderes zutrifft, versucht WordPress, dort eine Seite zu finden).

Aus diesem Grund ist es nicht ratsam, eine Permalink-Struktur ohne "Präfix" zu erstellen. Wenn Sie dies jedoch wirklich möchten, fügen Sie einfach eine Seite mit einem "Seiten" -Schnitt hinzu und machen Sie alle anderen Seiten zu ihren Söhnen. Dies funktioniert hervorragend, wenn Sie nicht viele Seiten haben und Sie keinen Code haben, der das Parsen und die Generierung von Permalinks gefährdet;)

2
Mark Kaplun

WordPress verwendet Rewrite Rules, um die Anfrage zu analysieren. Wenn die Anforderung mit einer der Regeln übereinstimmt, wird sie anhand dieser Regeln analysiert.

Die Regel für Seiten ist eine der letzten Regeln, mit denen die meisten Anfragen abgefangen werden, die nicht mit früheren Regeln übereinstimmen. Wenn Sie also Ihr CPT ohne Slug hinzufügen, wird die Seitenregel nicht ausgelöst ...

Eine Möglichkeit, dies zu beheben, besteht darin, CPT mit einem Slug zu registrieren und dann deren Links und WPs-Verhalten zu ändern. Hier ist der Code:

function register_mycpt() {
    $arguments = array(
        'label' => 'MyCPT',
        'public' => true,
        'hierarchical' => false,
        ...
        'has_archive' => false,
        'rewrite' => true
    );
    register_post_type('mycpt', $arguments);
}
add_action( 'init', 'register_mycpt' );

Jetzt sehen die URLs für diese Posts so aus:

http://example.com/mycpt/{post_name}/

Mit dem post_type_link-Filter können wir dies jedoch leicht ändern:

function change_mycpt_post_type_link( $url, $post, $leavename ) {
    if ( 'mycpt' == $post->post_type ) {
        $url = site_url('/') . $post->post_name . '/';
    }

    return $url;
}
add_filter( 'post_type_link', 'change_mycpt_post_type_link', 10, 3 );

Jetzt sind die URLs korrekt, aber ... Sie funktionieren nicht. Sie werden mithilfe der Umschreiberegel für Seiten analysiert und verursachen einen 404-Fehler (da keine Seite mit einer solchen URL vorhanden ist). Aber wir können das auch beheben:

function try_mycpt_before_page_in_parse_request( $wp ) {
    global $wpdb;

    if ( is_admin() ) return;

    if ( array_key_exists( 'name', $wp->query_vars ) ) {
        $post_name = $wp->query_vars['name'];

        $id = $wpdb->get_var( $wpdb->prepare(
            "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s ",
            'mycpt', $post_name
        ) );

        if ( $id ) {
            $wp->query_vars['mycpt'] = $post_name;
            $wp->query_vars['post_type'] = 'mycpt';
        }

    }
}
add_action( 'parse_request', 'try_mycpt_before_page_in_parse_request' );

PS. Ist es ratsam, diesen Code zu verwenden? Das ist eine andere Frage. Es ändert das Verhalten von WP in ziemlich schwerwiegender Weise, so dass es ein bisschen knifflig sein kann. Aber wenn es wirklich nötig ist, können Sie dies tun ...

Haftungsausschluss: Dieser Code funktioniert problemlos für nicht hierarchische CPTs, Sie können ihn jedoch auch an hierarchische CPTs anpassen.

1