Definieren Sie Permalinks für benutzerdefinierte Beitragstypen nach Taxonomie

Lesezeit: 7 Minuten

Ich möchte kanonische Permalinks für Produkte und Produkttypen erstellen. Ich habe die benutzerdefinierten Beitragstypen und die benutzerdefinierte Taxonomie herausgefunden, aber ich weiß nicht, ob es möglich ist, Permalinks mit Taxonomien zu definieren. Also mein Workflow wäre zum Beispiel so…

  1. Ich erstelle einen benutzerdefinierten Beitragstyp namens Produkte.
  2. Dann erstelle ich eine benutzerdefinierte Taxonomie für Produktarten.
  3. Dann füge ich einen Produkttyp namens hinzu ‘Stühle’ und fügen Sie ein Produkt namens hinzu
    ‘Roter Stuhl’ zu dieser Kategorie.

Sobald ich dieses Produkt erstellt habe, wird die gewünschte Permalink-Struktur um dieses Produkt anzuzeigen, wäre so formatiert ->

http://shop.com/products/chairs/red-chair

Ist dies in WordPress 3.4 möglich? Die Meta-Boxen in meinem benutzerdefinierten Beitragstyp ermöglichen die Auswahl der für meine benutzerdefinierte Taxonomie definierten Produkttypen, und es wird immer nur einen Typ pro Produkt geben.

Wenn möglich möchte ich auch eventuelle Eltern der ausgewählten Produktkategorie mit einbeziehen (z.B. wenn die ‘Stühle’ Kategorie war ein Kind der ‘Salon’ Kategorie wäre die Permalink-Struktur wie folgt ->

http://shop.com/products/lounge/chairs/red-chair

So erstelle ich den benutzerdefinierten Beitragstyp und die benutzerdefinierte Taxonomie. Ich brauche nur Hilfe bei der Definition von Rewrite-/Slug-Regeln, um den Produkttyp in den Permalink aufzunehmen.

/* Custom Post Type - Products ------- */
function products_init() {
    $args = array(
        'public' => true,
        'label' => 'Products'
    );
    register_post_type( 'products', $args );
}
add_action( 'init', 'products_init' );

/* Custom Taxonomy - Product Type ------- */
add_action( 'init', 'create_prodtype' );
function create_prodtype() {
    $labels = array(
        'name' => _x( 'Product Type', 'products' ),
        'singular_name' => _x( 'Product Category', 'product' ),
        'search_items' =>  __( 'Search Product Types' ),
        'all_items' => __( 'All Product Types' ),
        'parent_item' => __( 'Products' ),
        'parent_item_colon' => __( 'Products:' ),
        'edit_item' => __( 'Edit Product Type' ),
        'update_item' => __( 'Update Product Type' ),
        'add_new_item' => __( 'Add New Product Type' ),
        'new_item_name' => __( 'New Product Type' ),
    );
    register_taxonomy(
        'products',
        array('products'),
        array(
            'rewrite' => array(
                'slug' => 'products',
                'hierarchical' => true
            ), 
            'with_front' => false,
            'labels' => $labels
    ));
}

  • Kannst du bitte lesen Dies Artikel, den ich vor einiger Zeit geschrieben habe. Es erfüllt fast das, was Sie brauchen, außer dass es nur zweistufige Taxonomie-Permalinks unterstützt. Das bedeutet, dass http://shop.com/products/lounge/chairs/red/fancy-chair wird höchstwahrscheinlich nicht funktionieren.

    – Nikola Iwanow Nikolow

    25. November 2012 um 19:52 Uhr

  • Hmm, habe versucht, es in meinen Code und auch alleine zu integrieren. Es nimmt das URL-Präfix “FAQ” überhaupt nicht auf …

    – rgdigi

    25. November 2012 um 20:44 Uhr

Benutzeravatar von rgdigi
rgdigi

Lösung

Ich habe es mit Hilfe dieser Beiträge von Jan Fabry herausgefunden ->

https://wordpress.stackexchange.com/a/5478/10350
https://wordpress.stackexchange.com/a/22490/10350

Ich habe den benutzerdefinierten Beitragstyp wie folgt eingerichtet ->

  • Benutzerdefinierter Beitragstyp (register_post_type) -> “Produkt”
  • Taxonomie (register_taxonomy) -> “Produktart”

Backend-Funktion

Ich schreibe die im Backend gespeicherte Permalink-Struktur neu, sodass der Permalink so gespeichert wird, dass er den benutzerdefinierten Taxonomietyp enthält – „Produkttyp“.

add_filter('post_type_link', 'product_type_permalink', 10, 4);
function product_type_permalink($post_link, $post, $leavename, $sample) {
    //If is custom post type "product"
    if ($post->post_type == 'product') {
        // Get current post object
        global $post;
        // Get current value from custom taxonomy "product-type"
        $terms = get_the_terms($post->id, 'product-type');
        // Define category from "slug" of taxonomy object
        $term = $terms[0]->slug;
        // Re-structure permalink with string replace to include taxonomy value and post name
        $permalink = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $post_link);
    }
    return $permalink;
}

Stellen Sie die ein Permalink-Einstellung zu ‘Name posten’ und speichern. Wenn Sie ein Produkt zu einer Kategorie hinzufügen und speichern, sollte es den Permalink neu schreiben, um die benutzerdefinierte Taxonomie-Definition einzuschließen, in diesem Fall „Produkttyp“. Wenn Sie also hinzufügen “Roter Stuhl” zum “Stühle” Kategorie wird die URL wie folgt formatiert ->

http://website.com/product/chairs/red-chair/

Aber wenn Sie versuchen, auf diese Seite zu gehen, erhalten Sie einen 404-Fehler. Das liegt daran, dass WordPress noch nicht weiß, wie die Datenbank mit dieser URL abgefragt werden soll, also müssen Sie sie schreiben.

Frontend-Funktion

Wir müssen Rewrite-Regeln hinzufügen, damit WordPress unsere URL nehmen und die Datenbank abfragen kann. Wir verwenden die WordPress-Funktion add_rewrite_rule um den angegebenen Permalink in eine Abfragezeichenfolge zu übersetzen.

add_rewrite_rule(
    // The regex to match the incoming URL
    'product/([^/]+)/([^/]+)/?',
    // The resulting internal URL: `index.php` because we still use WordPress
    // `pagename` because we use this WordPress page
    // `designer_slug` because we assign the first captured regex part to this variable
    'index.php?product-type=$matches[1]&product=$matches[2]',
    // This is a rather specific URL, so we add it to the top of the list
    // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
    'top'
);

In dieser Funktion wird das Übereinstimmungs-Array von WordPress definiert, indem die angegebene Zeichenfolge bei jedem Schrägstrich aufgelöst wird. In diesem Beispiel also der reguläre Ausdruck ([^/]+) wird verwendet, um alles zwischen jedem Schrägstrich zu finden. In diesem Beispiel gibt es 2 Ebenen, also vergleicht es den Produkttyp, dann das Produkt und fügt sie dem Match-Array hinzu, wobei product-type = $matches1und Produkt = $matches[2].

Diese Rewrite-Regel übersetzt dies ->

product/chairs/red-chair/

In diese hinein ->

index.php?product-type=chair&product=red-chair

Welche unsere Datenbank verwenden kann, um die Datenbank abzufragen und die richtige Produktseite mit dem formatierten Permalink zurückzugeben.

Dies wirft Produkttypseiten ab, da es nur eine Ebene in der URL gibt, Produkttyp. Dies bedeutet, dass die Rewrite-Regel derzeit immer versucht, den Produktnamen so zu identifizieren, wie er in der Abfragezeichenfolge definiert ist. Dafür schreiben wir auch eine einstufige Umschreibungsregel:

add_rewrite_rule('^product/([^/]*)?$','index.php?product-type=$matches[1]','top');

Dadurch werden jetzt auch Produkttypseiten abgefragt, sodass wir die Taxonomie einfach wie gewohnt durchlaufen können, wenn wir die verschiedenen Produkttypen anzeigen möchten, ohne 404-Fehler auszulösen, wenn wir versuchen, sie zu verlinken.

Nachteil

Dies erfordert derzeit nur eine einzige Taxonomieebene, sodass die benutzerdefinierte Taxonomiestruktur nicht hierarchisch sein kann. Wenn Sie mehr als eine Taxonomie angeben, wird die meiste mit der ersten ID verwendet, um den Permalink zu definieren. Eine mögliche Problemumgehung besteht darin, das benutzerdefinierte Taxonomiemenü auszublenden, das in der Seitenleiste von benutzerdefinierten Beitragstypen angezeigt wird, und ein Metafeld für die Taxonomie hinzuzufügen, in dem nur ein Auswahlfeld verwendet werden kann. Ich verwende das Meta Box-Plugin dafür. (Achtung, dieses Plugin hat keine Admin-Menüs, es erlaubt Ihnen, Meta-Boxen für benutzerdefinierte Post-Typen in Ihre functions.php zu schreiben, indem Sie einfach Arrays erstellen – sehr zu empfehlen!)

  • Ich hoffe, Sie können helfen – Ihr Beispiel funktioniert großartig, abgesehen von der Regel zum Umschreiben auf einer Ebene – es scheint nicht zu funktionieren? Ich bekomme einfach eine Seite, die nicht gefunden werden kann. Wenn ich index.php?product-type=chair manuell eingebe, leitet es mich zu /{taxonomy-slug-name}/chair weiter, aber funktioniert es?

    – Sjwdavies

    23. Juli 2013 um 16:46 Uhr

  • Danke für die Lösung! Musste wechseln $term = $terms[0]->slug; zu $first_key = reset($terms); $term = $first_key->slug; um die Anker auf den Übersichtsseiten zum Laufen zu bringen!

    – Vadiem Janssens

    13. März 2015 um 9:28 Uhr


  • Dies funktioniert für das CPT, auf das Sie es anwenden, aber die Umleitungsregel schreibt alle auf der Seite angezeigten Permalinks neu, sogar von anderen CPT. Habe ich etwas verpasst?

    – bluantinoo

    7. Mai 2015 um 19:47 Uhr

@reekogi Dies funktioniert korrekt für den benutzerdefinierten Beitragstyp des Produkts, unterbricht jedoch alle anderen Beitragstypen.

add_filter('post_type_link', 'product_type_permalink', 10, 4);
function product_type_permalink($post_link, $post, $leavename, $sample) {
    //If is custom post type "product"
    if ($post->post_type == 'product') {
        // Get current post object
        global $post;
        // Get current value from custom taxonomy "product-type"
        $terms = get_the_terms($post->id, 'product-type');
        // Define category from "slug" of taxonomy object
        $term = $terms[0]->slug;
        // Re-structure permalink with string replace to include taxonomy value and post name
        $permalink = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $post_link);
    }
    return $permalink;
}

Eine Lösung wäre, die Variablen $post_link und $permalink in $url zu ändern

function product_type_permalink($url, $post, $leavename, $sample) {
    //If is custom post type "product"
    if ($post->post_type == 'product') {
        // Get current post object
        global $post;
        // Get current value from custom taxonomy "product-type"
        $terms = get_the_terms($post->id, 'product-type');
        // Define category from "slug" of taxonomy object
        $term = $terms[0]->slug;
        // Re-structure permalink with string replace to include taxonomy value and post name
        $url = str_replace('product/', 'product/' . $term . "https://stackoverflow.com/", $url);
    }
    return $url;
}
add_filter('post_type_link', 'product_type_permalink', 10, 4);

1394160cookie-checkDefinieren Sie Permalinks für benutzerdefinierte Beitragstypen nach Taxonomie

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy