Wie hänge ich mehrere Taxonomien an die URL an?

8

Mehrere Taxonomien in der URL

Wie hängt man mehrere Taxonomien an die URL mit den folgenden Angaben an:

  • Beitragstyp: Produkte
  • Taxonomie: Produkttyp
  • Taxonomie: product_brand


Hinzufügen eines neuen Produkts und Auswahl von Typ und Marke für dieses Produkt:

Beim Hinzufügen eines neuen Produkts gibt es zwei Taxonomiefelder (product_type und product_brand). Nennen wir diesen neuen Beitrag Testprodukt 1 . Das erste, was wir tun möchten, ist anzukreuzen, mit welcher Art von Produkt ich es zu tun habe, sagen wir Handys . Als nächstes möchte ich ankreuzen , zu welcher Marke das Produkt gehört, sagen wir Samsung.

Jetzt ist "Testprodukt 1 " dem Typ "Handys" und der Marke "Samsung" zugeordnet .

Das gewünschte Endergebnis ist:

/ products
»Alle benutzerdefinierten Beiträge anzeigen

/ products / handys
»Alle benutzerdefinierten Beiträge mit den Taxonomie-Handys anzeigen

/ product / handys / samsung /
»Alle benutzerdefinierten Beiträge anzeigen, in denen die Taxonomie Handys UND Samsung lautet

/ products / handys / samsung / test-product-1
»Produkt anzeigen (einzelner benutzerdefinierter Beitrag)


Die Frage

Wie würde man das möglich machen? Mein erster Gedanke war, eine Taxonomie zu verwenden, bei der "Handys" der übergeordnete Begriff von "Samsung" war . Das Anhängen der Taxonomie und ihrer Begriffe war nicht so schwierig. Aber es führte zu vielen anderen Problemen, einige bekannt, andere weniger. Auf jeden Fall funktioniert es nicht so, da es 404 Probleme gibt und WP bestimmte Dinge nicht zulässt.
WP.org »Taxonomie-Archiv-Vorlage

Dies führte mich dazu, die Struktur zu überdenken, Taxonomien und ihre Bedingungen zu verlassen, und ich dachte; Warum nicht eine zweite Taxonomie erstellen und den Beitragstyp damit verknüpfen und an die URL anhängen?

Gute Frage, aber wie?

DRSK
quelle
Können
Sanjay Nakate

Antworten:

7

Dies ist sicherlich möglich, indem Sie in gewissem Umfang eigene Umschreiberegeln verwenden. Die WP_Rewrite- API stellt Funktionen bereit , mit denen Sie Umschreiberegeln (oder 'Maps') hinzufügen können, um eine Anforderung in eine Abfrage zu konvertieren.

Es gibt Voraussetzungen, um gute Umschreiberegeln zu schreiben, und die wichtigste ist das grundlegende Verständnis regulärer Ausdrücke. Die WordPress Rewrite-Engine verwendet reguläre Ausdrücke, um Teile einer URL in Abfragen zu übersetzen, mit denen Beiträge abgerufen werden sollen.

Dies ist ein kurzes und gutes Tutorial zu PHP PCRE (Perl-kompatible reguläre Ausdrücke).

Sie haben also zwei Taxonomien hinzugefügt. Nehmen wir an, ihre Namen sind:

  • Produktart
  • Produktmarke

Wir können diese in Abfragen wie folgt verwenden:

get_posts( array(
    'product_type' => 'cell-phones',
    'product_brand' => 'samsung'
) );

Die Abfrage wäre ?product_type=cell-phones&product_brand=samsung. Wenn Sie dies als Ihre Abfrage eingeben, erhalten Sie eine Liste der Samsung-Telefone. Um /cell-phones/samsungin diese Abfrage umzuschreiben, muss eine Umschreiberegel hinzugefügt werden.

add_rewrite_rule()werde das für dich tun. Hier ist ein Beispiel dafür, wie Ihre Umschreiberegel für den obigen Fall aussehen könnte:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]',
    'top' );

Sie werden müssen flush_rewrite_rules(), sobald Sie die Rewrite - Regel hinzugefügt haben es in die Datenbank zu speichern. Dies geschieht nur einmal, es ist nicht erforderlich, dies bei jeder Anforderung zu tun, sobald eine Regel dort gelöscht ist. Um es zu entfernen, spülen Sie es einfach ohne die hinzugefügte Umschreiberegel.

Wenn Sie eine Paginierung hinzufügen möchten, können Sie dies tun, indem Sie Folgendes tun:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
    'top' );
Soulseekah
quelle
1
Der einfachste Artikel, den ich je gesehen habe, in Bezug auf WordPress-Regeln zum Umschreiben. Ich habe viel gelesen, aber nachdem ich das gelesen habe, hat es endlich funktioniert. Vielen Dank! +1
evu
3

Das Endergebnis

Dies ist, was ich mir ausgedacht habe, indem ich teilweise Teile aus allen Antworten verwendet habe, die ich habe:

/**
 * Changes the permalink setting <:> post_type_link
 * Functions by looking for %product-type% and %product-brands% in the URL
 * 
  * products_type_link(): returns the converted url after inserting tags
  *
  * products_add_rewrite_rules(): creates the post type, taxonomies and applies the rewrites rules to the url
 *
 *
 * Setting:         [ produkter / %product-type%  / %product-brand% / %postname% ]
 * Is actually:     [ post-type / taxonomy        /  taxonomy       / postname   ]
 *                   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 * Desired result:  [ products  / cellphones      / apple           / iphone-4   ]
 */

    // Add the actual filter    
    add_filter('post_type_link', 'products_type_link', 1, 3);

    function products_type_link($url, $post = null, $leavename = false)
    {
        // products only
        if ($post->post_type != 'products') {
            return $url;
        }

        // Post ID
        $post_id = $post->ID;

        /**
         * URL tag <:> %product-type%
         */
            $taxonomy = 'product-type';
            $taxonomy_tag = '%' . $taxonomy . '%';

            // Check if taxonomy exists in the url
            if (strpos($taxonomy_tag, $url) <= 0) {

                // Get the terms
                $terms = wp_get_post_terms($post_id, $taxonomy);

                if (is_array($terms) && sizeof($terms) > 0) {
                    $category = $terms[0];
                }

                // replace taxonomy tag with the term slug » /products/%product-type%/productname
                $url = str_replace($taxonomy_tag, $category->slug, $url);
            }

        /** 
         * URL tag <:> %product-brand%
         */
        $brand = 'product-brand';
        $brand_tag = '%' . $brand . '%';

        // Check if taxonomy exists in the url
        if (strpos($brand_tag, $url) < 0) {
            return $url;
        } else { $brand_terms = wp_get_post_terms($post_id, $brand); }

        if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
            $brand_category = $brand_terms[0];
        }

        // replace brand tag with the term slug and return complete url » /products/%product-type%/%product-brand%/productname
        return str_replace($brand_tag, $brand_category->slug, $url);

    }

    function products_add_rewrite_rules() 
    {
        global $wp_rewrite;
        global $wp_query;

        /**
         * Post Type <:> products
         */

            // Product labels
            $product_labels = array (
                'name'                  => 'Products',
                'singular_name'         => 'product',
                'menu_name'             => 'Products',
                'add_new'               => 'Add product',
                'add_new_item'          => 'Add New product',
                'edit'                  => 'Edit',
                'edit_item'             => 'Edit product',
                'new_item'              => 'New product',
                'view'                  => 'View product',
                'view_item'             => 'View product',
                'search_items'          => 'Search Products',
                'not_found'             => 'No Products Found',
                'not_found_in_trash'    => 'No Products Found in Trash',
                'parent'                => 'Parent product'
            );

            // Register the post type
            register_post_type('products', array(
                'label'                 => 'Products',
                'labels'                => $product_labels,
                'description'           => '',
                'public'                => true,
                'show_ui'               => true,
                'show_in_menu'          => true,
                'capability_type'       => 'post',
                'hierarchical'          => true,
                'rewrite'               => array('slug' => 'products'),
                'query_var'             => true,
                'has_archive'           => true,
                'menu_position'         => 5,
                'supports'              => array(
                                            'title',
                                            'editor',
                                            'excerpt',
                                            'trackbacks',
                                            'revisions',
                                            'thumbnail',
                                            'author'
                                        )
                )
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-type', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Types', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'products/types'),
                'singular_label' => 'Product Types') 
            );

        /**
         * Taxonomy <:> product-type
         */
            register_taxonomy('product-brand', 'products', array(
                'hierarchical' => true, 
                'label' => 'Product Brands', 
                'show_ui' => true, 
                'query_var' => true, 
                'rewrite' => array('slug' => 'product/brands'),
                'singular_label' => 'Product Brands') 
            );

            $wp_rewrite->extra_permastructs['products'][0] = "/products/%product-type%/%product-brand%/%products%";

            // flush the rules
            flush_rewrite_rules();
    }

    // rewrite at init
    add_action('init', 'products_add_rewrite_rules');


Einige Gedanken:

Das funktioniert. Obwohl Sie ‚erforderlich‘ beide Taxonomien jedem Beitrag zuweisen oder die URL ein nachstehendes haben '/'» '/products/taxonomy//postname'. Da ich allen meinen Procuts beide Taxonomien zuweisen werde, die einen Typ und eine Marke haben, scheint dieser Code für meine Bedürfnisse zu funktionieren. Wenn jemand Vorschläge oder Verbesserungen hat, kann er gerne antworten!

DRSK
quelle
Ausgezeichnet. Vielen Dank, dass Sie Ihre Lösung veröffentlicht haben. Bitte wählen Sie es als Antwort aus, sobald genügend Zeit vergangen ist. Es wird außerdem empfohlen, hilfreiche Antworten zu verbessern.
Marfarma
Es fällt mir schwer, das zum Laufen zu bringen, ich weiß nicht warum. Selbst das Kopieren / Einfügen in meine Funktionen, anstatt zu versuchen, Ihre Änderungen zu portieren, führt zu unzähligen Fehlern. Ich denke, etwas im Kern von WordPress muss sich zwischen dem Zeitpunkt, als dies geschrieben wurde (vor über 3 Jahren) und heute, geändert haben. Ich versuche das Gleiche herauszufinden: wordpress.stackexchange.com/questions/180994/…
JacobTheDev
flush_rewrite_rules()auf init? nicht dazu. Grundsätzlich setzen Sie Ihre Umschreiberegeln bei jedem Laden der Seite zurück.
Honk31
1

Überprüfen Sie auf diese Weise, es gibt immer noch einige Fehler im Markenarchiv

http://pastebin.com/t8SxbDJy

add_filter('post_type_link', 'products_type_link', 1, 3);

function products_type_link($url, $post = null, $leavename = false)
{
// products only
    if ($post->post_type != self::CUSTOM_TYPE_NAME) {
        return $url;
    }

    $post_id = $post->ID;

    $taxonomy = 'product_type';
    $taxonomy_tag = '%' . $taxonomy . '%';

    // Check if exists the product type tag
    if (strpos($taxonomy_tag, $url) < 0) {
        // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
        $url = str_replace($taxonomy_tag, '', $url);
    } else {
        // Get the terms
        $terms = wp_get_post_terms($post_id, $taxonomy);

        if (is_array($terms) && sizeof($terms) > 0) {
            $category = $terms[0];
            // replace taxonomy tag with the term slug: /products/%product_type%/samsumng/productname
            $url = str_replace($taxonomy_tag, $category->slug, $url);
        }
        }

    /* 
     * Brand tags 
     */
    $brand = 'product_brand';
    $brand_tag = '%' . $brand . '%';

    // Check if exists the brand tag 
    if (strpos($brand_tag, $url) < 0) {
        return str_replace($brand_tag, '', $url);
    }

    $brand_terms = wp_get_post_terms($post_id, $brand);

    if (is_array($brand_terms) && sizeof($brand_terms) > 0) {
        $brand_category = $brand_terms[0];
    }

    // replace brand tag with the term slug: /products/cell-phone/%product_brand%/productname 
    return str_replace($brand_tag, $brand_category->slug, $url);
}

function products_add_rewrite_rules() 
{
global $wp_rewrite;
global $wp_query;

register_post_type('products', array(
    'label' => 'Products',
    'description' => 'GVS products and services.',
    'public' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'capability_type' => 'post',
    'hierarchical' => true,
    'rewrite' => array('slug' => 'products'),
    'query_var' => true,
    'has_archive' => true,
    'menu_position' => 6,
    'supports' => array(
        'title',
        'editor',
        'excerpt',
        'trackbacks',
        'revisions',
        'thumbnail',
        'author'),
    'labels' => array (
        'name' => 'Products',
        'singular_name' => 'product',
        'menu_name' => 'Products',
        'add_new' => 'Add product',
        'add_new_item' => 'Add New product',
        'edit' => 'Edit',
        'edit_item' => 'Edit product',
        'new_item' => 'New product',
        'view' => 'View product',
        'view_item' => 'View product',
        'search_items' => 'Search Products',
        'not_found' => 'No Products Found',
        'not_found_in_trash' => 'No Products Found in Trash',
        'parent' => 'Parent product'),
    ) 
);

register_taxonomy('product-categories', 'products', array(
    'hierarchical' => true, 
    'label' => 'Product Categories', 
    'show_ui' => true, 
    'query_var' => true, 
    'rewrite' => array('slug' => 'products'),
    'singular_label' => 'Product Category') 
);

$wp_rewrite->extra_permastructs['products'][0] = "/products/%product_type%/%product_brand%/%products%";

    // product archive
    add_rewrite_rule("products/?$", 'index.php?post_type=products', 'top');

    /* 
     * Product brands
     */
    add_rewrite_rule("products/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_brand=$matches[2]', 'top');
    add_rewrite_rule("products/([^/]+)/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_brand=$matches[2]&paged=$matches[3]', 'top');

    /*
     * Product type archive
     */
    add_rewrite_rule("products/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]', 'top');    
    add_rewrite_rule("products/([^/]+)/page/([0-9]{1,})/?$", 'index.php?post_type=products&product_type=$matches[1]&paged=$matches[1]', 'bottom'); // product type pagination

    // single product
    add_rewrite_rule("products/([^/]+)/([^/]+)/([^/]+)/?$", 'index.php?post_type=products&product_type=$matches[1]&product_brand=$matches[2]&products=$matches[3]', 'top');



flush_rewrite_rules();

}}

add_action('init', 'products_add_rewrite_rules');
Luis Abarca
quelle
1

Obwohl dies nicht Ihre genau gewünschte URL-Struktur ist, können Sie Folgendes erhalten:

/ products
»Alle benutzerdefinierten Beiträge anzeigen

/ products / type / handys
»Alle benutzerdefinierten Beiträge mit den Taxonomie-Handys anzeigen

/ products / type / handys / brand / samsung
»Alle benutzerdefinierten Beiträge anzeigen , in denen die Taxonomie Handys UND Samsung lautet

/ brand / samsung
»Alle benutzerdefinierten Beiträge anzeigen, in denen die Taxonomie Samsung ist

/ product / test-product-1
»Produkt anzeigen (einzelner benutzerdefinierter Beitrag)

ohne benutzerdefinierte Regeln zum erneuten Schreiben angeben zu müssen.

Es ist jedoch erforderlich, dass Sie Ihre Taxonomien und benutzerdefinierten Beitragstypen in einer bestimmten Reihenfolge registrieren. Der Trick besteht darin, jede Taxonomie zu registrieren, bei der der Slug mit dem Slug Ihres Post-Typs beginnt, bevor Sie diesen benutzerdefinierten Post-Typ registrieren. Nehmen Sie zum Beispiel die folgenden Schnecken an:

product_type taxonomy slug               = products/type
product custom_post_type slug            = product
product custom_post_type archive slug    = products
product_brand taxonomy slug              = brand

Dann könnten Sie sie in dieser Reihenfolge registrieren:

register_taxonomy( 
    'products_type', 
    'products', 
        array( 
            'label' => 'Product Type', 
            'labels' => $product_type_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'products/type', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

register_post_type('products', array(
    'labels' =>$products_labels,
    'singular_label' => __('Product'),
    'public' => true,
    'show_ui' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'rewrite' => array('slug' => 'product', 'with_front' => false ),
    'has_archive' => 'products',
    'supports' => array('title', 'editor', 'thumbnail', 'revisions','comments','excerpt'),
 ));

register_taxonomy( 
    'products_brand', 
    'products', 
        array( 
            'label' => 'Brand', 
            'labels' => $products_brand_labels,
            'public' => true, 
            'show_ui' => true, 
            'show_in_nav_menus' => true, 
            'args' => array( 'orderby' => 'term_order' ),
            'rewrite' => array( 'slug' => 'brand', 'with_front' => false  ),
            'has_archive' => true,
            'query_var' => true, 
        ) 
);

Wenn Sie unbedingt eine URL haben müssen wie:

/ products / type / handys / brand / samsung / test-product-1
»Produkt anzeigen (einzelner benutzerdefinierter Beitrag)

Dann würden Sie eine Umschreiberegel wie diese benötigen:

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

UPDATE /programming/3861291/multiple-custom-permalink-structures-in-wordpress

So definieren Sie die URL für einen einzelnen Beitrag korrekt neu.

Setzen Sie das erneute Schreiben für den benutzerdefinierten Beitragstyp auf false. (Lassen Sie das Archiv unverändert) und registrieren Sie nach dem Registrieren der Taxonomien und Beiträge auch die folgenden Umschreiberegeln.

  'rewrite' => false

   global $wp_rewrite;
   $product_structure = '/%product_type%/%brand%/%product%';
   $wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
   $wp_rewrite->add_permastruct('product', $product_structure, false);

Filtern Sie anschließend post_type_link, um die gewünschte URL-Struktur zu erstellen. Dabei werden nicht festgelegte Taxonomiewerte berücksichtigt. Wenn Sie den Code aus dem verlinkten Beitrag ändern, haben Sie:

function product_permalink($permalink, $post_id, $leavename){
    $post = get_post($post_id);

    if( 'product' != $post->post_type )
         return $permalink;

    $rewritecode = array(
    '%product_type%',
    '%brand%',
    $leavename? '' : '%postname%',
    $leavename? '' : '%pagename%',
    );

    if('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){

        if (strpos($permalink, '%product_type%') !== FALSE){

            $terms = wp_get_object_terms($post->ID, 'product_type'); 

            if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))  
               $product_type = $terms[0]->slug;
            else 
               $product_type = 'unassigned-artist';         
        }

        if (strpos($permalink, '%brand%') !== FALSE){
           $terms = wp_get_object_terms($post->ID, 'brand');  
           if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) 
               $brand = $terms[0]->slug;
           else 
               $brand = 'unassigned-brand';         
        }           

        $rewritereplace = array(
           $product_type,
           $brand,
           $post->post_name,
           $post->post_name,
        );

        $permalink = str_replace($rewritecode, $rewritereplace, $permalink);
    }
    return $permalink;
}

add_filter('post_type_link', 'product_permalink', 10, 3);

Jetzt muss ich nur noch herausfinden, wie die URL der Markentaxonomie ohne das führende Markentag neu geschrieben werden kann, und ich sollte genau mit Ihrer gewünschten URL übereinstimmen.

Marfarma
quelle