it-swarm.com.de

Entfernen Sie Slugs aus benutzerdefinierten Beitragstyp-Beitrags-URLs

Es scheint, dass alle Web-Ressourcen, die auf dem Thema des Entfernens eines benutzerdefinierten Beitragstyps basieren, z

yourdomain.com/CPT-SLUG/post-name 

inzwischen sind Lösungen sehr veraltet, die häufig auf Installationen vor WP Version 3.5 verweisen. Eine übliche ist:

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

innerhalb Ihrer register_post_type Funktion. Das funktioniert nicht mehr und ist irreführend. Also frage ich die Community im 3. Quartal 2018 am Rande von WordPress 5 ...

Welche modernen und effizienten Methoden stehen zur Verfügung, um den Post Type Slug aus der URL eines benutzerdefinierten Post Type-Posts innerhalb des Rewrite-Arguments oder an einer anderen Stelle zu entfernen?

UPDATE: Es scheint verschiedene Möglichkeiten zu geben, dies zu erzwingen, um mit regulären Ausdrücken zu arbeiten. Insbesondere die Antwort von Jan Beck, falls Sie beständig bereit sein sollten, die Erstellung von Inhalten zu überwachen, um sicherzustellen, dass keine widersprüchlichen Seiten-/Post-Namen erstellt werden. Ich bin jedoch überzeugt, dass dies eine große Schwachstelle im Kern von WP ist, wo dies sein sollte für uns gehandhabt werden. Beides als Option/Hook beim Erstellen eines CPT oder eines erweiterten Optionssatzes für Permalinks. Bitte unterstützen Sie das Track-Ticket.

Fußnote: Bitte unterstützen Sie dieses Trac-Ticket, indem Sie es ansehen/bewerben: https://core.trac.wordpress.org/ticket/34136#ticket

43
Ben Racicot

Der folgende Code wird funktionieren, aber Sie müssen nur bedenken, dass Konflikte leicht auftreten können, wenn der Slug für Ihren benutzerdefinierten Post-Typ dem einer Seite oder des Slugs eines Posts entspricht ...

Zuerst werden wir den Slug aus dem Permalink entfernen:

function na_remove_slug( $post_link, $post, $leavename ) {

    if ( 'events' != $post->post_type || 'publish' != $post->post_status ) {
        return $post_link;
    }

    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

    return $post_link;
}
add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );

Nur die Schnecke zu entfernen ist nicht genug. Im Moment erhalten Sie eine 404-Seite, da WordPress nur erwartet, dass sich Posts und Seiten so verhalten. Sie müssen außerdem Folgendes hinzufügen:

function na_parse_request( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'events', 'page' ) );
    }
}
add_action( 'pre_get_posts', 'na_parse_request' );

Ändern Sie einfach "Ereignisse" in Ihren benutzerdefinierten Beitragstyp und schon kann es losgehen. Möglicherweise müssen Sie Ihre Permalinks aktualisieren.

57
Nate Allen

Schreiben Sie den folgenden Code in die Taxonomie-Registrierung.

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

Das Wichtigste, was Sie nach einer Codeänderung tun müssen

Nachdem Sie Ihr benutzerdefiniertes Taxonomiedokument für den Beitragstyp geändert haben, wechseln Sie zu Einstellungen> Permalinks und Speichern Sie Ihre Einstellungen erneut . Andernfalls werden 404-Seiten nicht gefunden.

Überprüfen Sie hier die beste Lösung: http://www.krazzycodes.com/de/wie-zum-entfernen-von-url-in-wordpress/

19
Mayank Dudakiya

Ich habe vor nicht allzu langer Zeit versucht, das herauszufinden, und die kurze Antwort von dem, was ich weiß, ist nein . Zumindest nicht innerhalb des Rewrite-Arguments.

Die lange Erklärung wird deutlich, wenn Sie sich den tatsächlichen Code von register_post_type in wp-includes/post.php Zeile 1454 ansehen:

add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );

Sie können sehen, dass dem $args->rewrite['slug'] umschreibenden Tag %$post_type% vorangestellt wird. Man könnte denken, "setzen wir den Slug einfach auf null then", bis Sie ein paar Zeilen nachschlagen:

if ( empty( $args->rewrite['slug'] ) )
    $args->rewrite['slug'] = $post_type;

Sie können sehen, dass die Funktion immer einen Slug-Wert erwartet, der nicht leer ist und ansonsten den Post-Typ verwendet.

12
Jan Beck

Als Antwort auf meine vorherige Antwort : Sie können natürlich den Parameter rewrite auf false setzen, wenn Sie einen neuen Beitragstyp registrieren, und die Umschreiberegeln selbst so handhaben

<?php
function wpsx203951_custom_init() {

    $post_type = 'event';
    $args = (object) array(
        'public'      => true,
        'label'       => 'Events',
        'rewrite'     => false, // always set this to false
        'has_archive' => true
    );
    register_post_type( $post_type, $args );

    // these are your actual rewrite arguments
    $args->rewrite = array(
        'slug' => 'calendar'
    );

    // everything what follows is from the register_post_type function
    if ( is_admin() || '' != get_option( 'permalink_structure' ) ) {

        if ( ! is_array( $args->rewrite ) )
            $args->rewrite = array();
        if ( empty( $args->rewrite['slug'] ) )
            $args->rewrite['slug'] = $post_type;
        if ( ! isset( $args->rewrite['with_front'] ) )
            $args->rewrite['with_front'] = true;
        if ( ! isset( $args->rewrite['pages'] ) )
            $args->rewrite['pages'] = true;
        if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive )
            $args->rewrite['feeds'] = (bool) $args->has_archive;
        if ( ! isset( $args->rewrite['ep_mask'] ) ) {
            if ( isset( $args->permalink_epmask ) )
                $args->rewrite['ep_mask'] = $args->permalink_epmask;
            else
                $args->rewrite['ep_mask'] = EP_PERMALINK;
        }

        if ( $args->hierarchical )
            add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" );
        else
            add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" );

        if ( $args->has_archive ) {
            $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;
            if ( $args->rewrite['with_front'] )
                $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug;
            else
                $archive_slug = $wp_rewrite->root . $archive_slug;

            add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );
            if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) {
                $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
                add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
                add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
            }
            if ( $args->rewrite['pages'] )
                add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );
        }

        $permastruct_args = $args->rewrite;
        $permastruct_args['feed'] = $permastruct_args['feeds'];
        add_permastruct( $post_type, "%$post_type%", $permastruct_args );
    }
}
add_action( 'init', 'wpsx203951_custom_init' );

Sie können sehen, dass der add_permastruct-Aufruf den Slug jetzt nicht mehr enthält. Ich habe zwei Szenarien getestet:

  1. Wenn ich eine Seite mit dem Slug "calendar" erstellt habe, wird diese Seite durch das Archiv des Post-Typs überschrieben, in dem auch der Slug "calendar" verwendet wird.

 enter image description here 

  1. Wenn ich eine Seite mit dem Slug "my-event" und einem Event (CPT) mit dem Slug "my-event" erstellt habe, wird der benutzerdefinierte Beitragstyp angezeigt.

 enter image description here 

  1. Alle anderen Seiten funktionieren auch nicht. Wenn Sie sich das Bild oben ansehen, wird klar, warum: Die benutzerdefinierte Post-Typ-Regel wird immer mit einem Seiten-Slug verglichen. Da WordPress nicht erkennen kann, ob es sich um eine Seite oder einen benutzerdefinierten Beitragstyp handelt, der nicht vorhanden ist, wird 404 zurückgegeben. Aus diesem Grund benötigen Sie einen Slug, um die Seite oder den CPT zu identifizieren. Eine mögliche Lösung wäre, den Fehler abzufangen und nach einer Seite zu suchen, die möglicherweise existiert ähnlich wie diese Antwort .
7
Jan Beck

Wenn ich mir die Antworten hier ansehe, gibt es meines Erachtens Raum für eine bessere Lösung, die einige der oben genannten Erkenntnisse kombiniert und die automatische Erkennung und Verhinderung von doppelten Post-Slugs hinzufügt.

HINWEIS: Stellen Sie sicher, dass Sie in meinem Beispiel unten "custom_post_type" für Ihren eigenen CPT-Namen ändern. Es gibt viele Vorkommen und ein Suchen/Ersetzen ist eine einfache Möglichkeit, sie alle zu finden. Der gesamte Code kann in Ihrer functions.php oder in einem Plugin gespeichert werden.

Schritt 1: Deaktiviere Umschreibungen für deinen benutzerdefinierten Beitragstyp, indem du die Umschreibungen auf 'false' setzt, wenn du den Beitrag registrierst:

register_post_type( 'custom_post_type',
    array(
        'rewrite' => false
    )
);

Schritt 2: Fügen Sie unsere benutzerdefinierten Umschreibungen manuell zum Ende der WordPress-Umschreibungen für unseren benutzerdefinierten_Postentyp hinzu

function custom_post_type_rewrites() {
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/embed/?$', 'index.php?custom_post_type=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/trackback/?$', 'index.php?custom_post_type=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '([^/]+)/page/?([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&paged=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)(?:/([0-9]+))?/?$', 'index.php?custom_post_type=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
}
add_action( 'init', 'custom_post_type_rewrites' );

HINWEIS: Je nach Ihren Anforderungen möchten Sie möglicherweise die obigen Änderungen vornehmen (Trackbacks deaktivieren, Feeds deaktivieren usw.). Diese stellen die 'Standard'-Arten von Umschreibungen dar, die generiert worden wären, wenn Sie die Umschreibungen in Schritt 1 nicht deaktiviert hätten.

Schritt 3: Erstelle wieder einen Permalink zu deinem benutzerdefinierten Post-Typ 'pretty'

function custom_post_type_permalinks( $post_link, $post, $leavename ) {
    if ( isset( $post->post_type ) && 'custom_post_type' == $post->post_type ) {
        $post_link = home_url( $post->post_name );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'custom_post_type_permalinks', 10, 3 );

HINWEIS: Sie können hier anhalten, wenn Sie nicht befürchten, dass Ihre Benutzer einen in Konflikt stehenden (doppelten) Beitrag in einem anderen Beitragstyp erstellen, wodurch eine Situation entsteht, in der nur einer von ihnen geladen werden kann, wenn die Seite angefordert wird.

Schritt 4: Verhindern Sie doppelte Pfostenbutzen

function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
    $check_post_types = array(
        'post',
        'page',
        'custom_post_type'
    );

    if ( ! in_array( $post_type, $check_post_types ) ) {
        return $slug;
    }

    if ( 'custom_post_type' == $post_type ) {
        // Saving a custom_post_type post, check for duplicates in POST or PAGE post types
        $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
        $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );

        if ( $post_match || $page_match ) {
            $slug .= '-duplicate';
        }
    } else {
        // Saving a POST or PAGE, check for duplicates in custom_post_type post type
        $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', 'custom_post_type' );

        if ( $custom_post_type_match ) {
            $slug .= '-duplicate';
        }
    }

    return $slug;
}
add_filter( 'wp_unique_post_slug', 'prevent_slug_duplicates', 10, 6 );

HINWEIS: Damit wird die Zeichenfolge '-duplicate' an das Ende aller doppelten Slugs angehängt. Dieser Code kann doppelte Bugs nicht verhindern, wenn diese bereits vor der Implementierung dieser Lösung vorhanden waren. Achten Sie darauf, zuerst nach Duplikaten zu suchen.

Ich würde gerne von allen anderen hören, die dies ausprobieren, um zu sehen, ob es auch für sie gut funktioniert.

5
Matt Keys

Sie brauchen nicht so viel Hardcode. Benutze einfach ein leichtes Plugin:

Es hat anpassbare Optionen.

1
T.Todua

Für alle, die dies lesen und Probleme mit untergeordneten Posts hatten, wie ich es tat, war es der beste Weg, Ihre eigenen Umschreiberegeln hinzuzufügen.

Das Hauptproblem, das ich hatte, war, dass WordPress die Weiterleitung von Seiten mit einer Tiefe von 2 Ebenen (untergeordnete Posts) ein wenig anders behandelt als 3 Ebenen (untergeordnete Posts).

Das bedeutet, wenn ich/post-type/post-name/post-child/habe, kann ich/post-name/post-child verwenden und es wird mich zu dem mit post-type vor umleiten, aber wenn ich post-type habe/post-name/post-child/post-grandchild dann kann ich post-name/post-child/post-grandchild nicht verwenden.

Wenn Sie sich die Umschreiberegeln ansehen, sieht es so aus, als würde sie für andere Dinge als Seitennamen auf der ersten und zweiten Ebene passen (ich denke, die zweite Ebene entspricht dem Anhang), und dann wird dort etwas unternommen, um Sie zum richtigen Beitrag umzuleiten. Auf drei Ebenen funktioniert es nicht.

Als Erstes müssen Sie den Beitragstyp-Link auch von Kindern entfernen. Diese Logik sollte hier vorkommen, wenn Sie sich die Antwort von Nate Allen oben ansehen:

$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

Ich selbst habe eine Mischung verschiedener Bedingungen verwendet, um zu überprüfen, ob der Beitrag Kinder hat und was nicht, um zum richtigen Permalink zu gelangen. Dieser Teil ist nicht allzu schwierig und Sie werden Beispiele von Leuten finden, die es woanders machen.

Der nächste Schritt ist jedoch, wo sich die Dinge von der gegebenen Antwort ändern. Anstatt der Hauptabfrage Dinge hinzuzufügen (die für benutzerdefinierte Posts und ihre Kinder, aber nicht für die weiteren Kinder funktionierten), habe ich ein Umschreiben hinzugefügt, das an die Basis der WordPress-Regeln ging, sodass, wenn der Seitenname nicht ausgecheckt wurde und es im Begriff war, Wenn Sie auf 404 klicken, wird ein letzter Test durchgeführt, um festzustellen, ob eine Seite innerhalb des benutzerdefinierten Beitragstyps den gleichen Namen hat. Andernfalls wird 404 verworfen.

Hier ist die Umschreiberegel, die ich verwendet habe, vorausgesetzt, 'event' ist der Name Ihres CPT

function rewrite_rules_for_removing_post_type_slug()
{
    add_rewrite_rule(
        '(.?.+?)?(:/([0-9]+))?/?$',
        'index.php?event=$matches[1]/$matches[2]&post_type=event',
        'bottom'
    );
}

add_action('init', 'rewrite_rules_for_removing_post_type_slug', 1, 1);

Hoffe, das hilft jemand anderem, ich konnte nichts anderes finden, was mit Child-of-Child-Posts und dem Entfernen der Schnecke von diesen zu tun hatte.

0
Moe Loubani

und wir können einige Änderungen an der oben genannten Funktion vornehmen:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {
    $query->set( 'post_type', array( 'post', 'events', 'page' ) );
}
}

zu:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {

    global $wpdb;
    $pt = $wpdb->get_var(
        "SELECT post_type FROM `{$wpdb->posts}` " .
        "WHERE post_name = '{$query->query['name']}'"
    );
    $query->set( 'post_type', $pt );
}
}

um den richtigen post_type Wert zu setzen.

0
Max Kondrachuk

Das hat bei mir funktioniert: 'rewrite' => array('slug' => '/')

0
Malki Mohamed