web-dev-qa-db-de.com

Behandeln Sie das Umschreiben der URL des Kategorienamens, bevor Sie einen anderen Beitragstyp verwenden

Ich habe hier mehr als hundert ähnliche Themen behandelt, die genau dem entsprachen, was ich brauche, aber leider konnte ich dies nicht genau einstellen. Ich entschuldige mich, wenn es sich um ein Duplikat handelt.

Ich habe mehrere Beitragstypen (wie Events, Venues, Places) und ich verwende auch Posts, wobei die vier Beitragstypen mit der Standard-Taxonomie von WordPress Categories verbunden sind.

Ich habe versucht, einen Permalink zu erstellen, der so aussieht:

http: // sitename/venues/61312/california-venue

Wobei venues der Name der Kategorie ist; 61312 ist die post_id und california-venue ist der postname.

Alle Beitragstypen sollten dieselbe Struktur aufweisen:

%category%/%post_id%/%postname%/

Diese Permalink-Struktur scheint für Posts in Einstellungen -> Permalinks gut zu funktionieren, nicht jedoch für die anderen Post-Typen.

Die mit with_front => false geben 404 zurück, die anderen funktionieren einwandfrei, leiten aber zu post_type/postname weiter.

Ich habe eine benutzerdefinierte Umschreiberegel, die so aussieht:

array( 
  'regex'     => '^([^/]+)/([0-9]+)/([^/]+)?',  
  'query'       => 'category_name=$matches[1]&post_id=$matches[2]&pagename=$matches[3]', 
 )

Ich habe versucht, den post_type_link zu filtern und zu prüfen, ob die Umleitung beendet wird. Außerdem habe ich das folgende Snippet versucht, indem ich disable_redirect=1 zu meinen Abfrageregeln hinzugefügt habe:

add_filter('query_vars', 'my_public_query_vars');
function my_public_query_vars($qv)
{
    $qv[] = 'disable_redirect';
    return $qv;
}
add_filter('wp_redirect', 'my_disable_redirect');
function my_disable_redirect($location)
{
    $disable_redirect = get_query_var('disable_redirect');
    if(!empty($disable_redirect)) return false;
    return $location;
}

Das hat einfach einen WSOD ausgelöst.

Wie kann ich die Weiterleitung zu meinen Einzelansichten für jeden Beitragstyp verhindern (Einzelbeitragsansicht scheint einwandfrei zu funktionieren) und die %category%/%post_id%/%postname%-URL-Struktur beibehalten?

4
Mario Peshev

Nach einigem Brainstorming und viel Versuch und Irrtum mit T5 Rewrite und HM Rewrite habe ich mich für die einfachste Lösung entschieden.

Der Permalink wurde tatsächlich von WordPress abgefangen, so dass ich die zusätzliche Regel zum Umschreiben nicht brauchte (obwohl es nicht weh tat, abgesehen von der Leistung). Ich habe %category%/%post_id%/%postname% als benutzerdefinierten Standard-Permalink gelassen und es scheint für alle Post-Typen zu funktionieren.

Der ursprüngliche Slug wird ebenfalls ordnungsgemäß behandelt (wenn übrig gebliebene Links gefunden werden), aber der neue ist der Standard.

Ich habe mit template_redirect, request, redirect_canonical, query_vars, wp_redirect und anderen Hooks gespielt, um das Problem zu finden.

add_filter( 'request', 'sm_permalink_request_handler' );
function sm_permalink_request_handler( $request ) {
    if ( ! isset( $request['p'] ) ) {
        return $request;
    }

    // Get the post type, it's required to prevent the redirect
    $post_id = $request['p'];
    $post = get_post( $post_id );
    $request['post_type'] = $post->post_type;

    return $request;
} 


/**
 * Override get_permalink and prevent redirects
 */
function sm_fix_permalinks_for_post_types( $url, $post ) {
        $taxonomies = get_post_taxonomies();
        // See if categories are assigned to our CPT entry
        if ( ! empty( $taxonomies ) && in_array( 'category', $taxonomies ) ) {

            // Fetch all categories
            $categories = wp_get_post_categories( $post->ID, array() );

            if ( ! empty( $categories ) ) {
                // Get the main category in case there are more assigned
                // Somewhat arbitrary since it pops the last one.
                $main_category_id = array_pop( $categories );

                $main_category = get_category( $main_category_id );

                if( ! empty( $main_category ) ) {
                    $category_slug = $main_category->slug;
                    $post_id = $post->ID;
                    $post_name = $post->post_name;

                    $url = home_url( "$category_slug/$post_id/$post_name" );
                }
            }
        }

        return $url;
}

add_filter( 'post_type_link', 'sm_fix_permalinks_for_post_types', 10, 2 );

Das erste Problem betraf den Mangel an post_type, der mit der Anforderung übergeben wurde. Mein Permalink filterte nach Kategorienamen und Beitrags-ID, war jedoch posttypunabhängig und beeinträchtigte WordPress. Indem der Beitrag anhand seiner ID abgerufen und der post_type festgelegt wurde, wurde der normale Zustand wiederhergestellt.

Das zweite Problem betraf die Permalinks für neue Beiträge im Admin-Bereich und in den Frontend-Vorlagen. Ein anderer Teil der Filterung hat es geschafft und es funktioniert auf der gesamten Website.

1
Mario Peshev