Come posso aggiungere più tassonomie all'URL?


8

Tassonomie multiple nell'URL

In che modo è possibile aggiungere più tassonomie all'URL con quanto segue:

  • Tipo di posta: prodotti
  • Tassonomia: tipo_prodotto
  • Tassonomia: product_brand


Aggiunta di un nuovo prodotto e selezione del tipo e della marca per questo prodotto:

Quando si aggiunge un nuovo prodotto , ci sono due caselle di tassonomia (product_type e product_brand). Chiamiamo questo nuovo post Test prodotto 1 . La prima cosa che vogliamo fare è spuntare con che tipo di prodotto ho a che fare, diciamo telefoni cellulari . Quindi, desidero selezionare la marca a cui appartiene il prodotto, diciamo Samsung.

Ora " Test prodotto 1 " è associato al tipo "telefoni cellulari" e al marchio "samsung" .

Il risultato finale desiderato è:

/ prodotti
»Visualizza tutti i post personalizzati

/ products / cell -phones
»Visualizza tutti i post personalizzati con i telefoni cellulari di tassonomia

/ product / cell -phones / samsung /
»Visualizza tutti i post personalizzati in cui la tassonomia è telefoni cellulari E Samsung

/ products / cell -phones / samsung / test-product-1
»Visualizza il prodotto (singolo post personalizzato)


La domanda

Come si potrebbe renderlo possibile? Il mio pensiero iniziale era usare una tassonomia, avendo "telefoni cellulari" come termine principale di "Samsung" . In realtà aggiungere la tassonomia e i suoi termini non è stato così difficile. Ma ha portato a molte altre questioni, alcune ben note, altre non così tante. Ad ogni modo non funziona così dato che dà 404 problemi e WP non permetterà determinate cose.
WP.org »modello-archivio-tassonomia

Questo mi ha portato ad aver ripensato la struttura, a dover lasciare le tassonomie e i suoi termini e ho pensato; perché non creare una seconda tassonomia e associare il tipo di post con esso e aggiungerlo all'URL?

Bella domanda davvero, ma come?


si può controllare questo link ho problema con il stessa cosa stackoverflow.com/questions/34351477/...
Sanjay Nakate

Risposte:


7

Questo è certamente possibile utilizzando alcune regole di riscrittura in una certa misura. L' API WP_Rewrite espone funzioni che consentono di aggiungere regole di riscrittura (o "mappe") per convertire una richiesta in una query.

Ci sono prerequisiti per scrivere buone regole di riscrittura, e la più importante è la comprensione di base delle espressioni regolari. Il motore di riscrittura di WordPress utilizza espressioni regolari per tradurre parti di un URL in query con cui ottenere post.

Questo è un breve e valido tutorial su PHP PCRE (espressioni regolari compatibili Perl).

Quindi, hai aggiunto due tassonomie, supponiamo che i loro nomi siano:

  • Tipologia di prodotto
  • product_brand

Possiamo usarli nelle query in questo modo:

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

La query sarebbe ?product_type=cell-phones&product_brand=samsung. Se lo digiti come query otterrai un elenco di telefoni Samsung. Per riscrivere /cell-phones/samsungin quella query è necessario aggiungere una regola di riscrittura.

add_rewrite_rule()lo farà per te. Ecco un esempio di come potrebbe apparire la tua regola di riscrittura per il caso precedente:

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

Sarà necessario flush_rewrite_rules()non appena avrai aggiunto la regola di riscrittura per salvarla nel database. Questo viene fatto solo una volta, non è necessario farlo con ogni richiesta, una volta che una regola viene scaricata lì. Per rimuoverlo è sufficiente scaricare senza la regola di riscrittura aggiunta.

Se vuoi aggiungere l'impaginazione puoi farlo facendo qualcosa del tipo:

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

1
Singolo articolo più semplice che ho visto riguardo alle regole di riscrittura di wordpress. Ho letto molto ma dopo aver letto questo, finalmente le cose hanno funzionato. Grazie! +1
evu,

3

Il risultato finale

Questo è quello che mi è venuto in mente usando in parte frammenti di tutte le risposte che ho:

/**
 * 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');


Alcuni pensieri:

Questo funziona. Anche se ti viene richiesto di assegnare entrambe le tassonomie a ciascun post o l'URL avrà un finale '/'» '/products/taxonomy//postname'. Dal momento che assegnerò entrambe le tassonomie a tutti i miei procut, avendo un tipo e un marchio, questo codice sembra funzionare per le mie esigenze. Se qualcuno ha qualche suggerimento o miglioramento sentiti libero di rispondere!


Eccellente. Grazie per aver postato la tua soluzione. Seleziona come risposta una volta che è trascorso abbastanza tempo. Inoltre, si consiglia di votare tutte le risposte utili.
marfarma,

Sto facendo fatica a farlo funzionare, non so perché. Anche copiare / incollare nelle mie funzioni piuttosto che cercare di trasferire le tue modifiche mi dà tonnellate di errori. Sto pensando che qualcosa nel nucleo di WordPress debba essere cambiato tra quando è stato scritto (oltre 3 anni fa) e oggi. Sto cercando di capire la stessa cosa: wordpress.stackexchange.com/questions/180994/…
JacobTheDev

flush_rewrite_rules()su init? non farlo. in pratica stai reimpostando le tue regole di riscrittura con ogni singolo caricamento della pagina.
honk31

1

Controlla in questo modo, ha ancora alcuni bug con l'archivio del marchio

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');

1

Pur non essendo l'esatta struttura dell'URL desiderata, puoi ottenere:

/ prodotti
»Visualizza tutti i post personalizzati

/ products / type / cell -phones
»Visualizza tutti i post personalizzati con i telefoni cellulari di tassonomia

/ prodotti / tipo / telefoni cellulari / marchio / samsung
»Visualizza tutti i messaggi personalizzati in cui la tassonomia è telefoni cellulari E Samsung

/ brand / samsung
»Visualizza tutti i post personalizzati in cui la tassonomia è Samsung

/ product / test-product-1
»Visualizza il prodotto (singolo post personalizzato)

senza dover specificare regole di riscrittura personalizzate.

Tuttavia, richiede la registrazione delle tassonomie e dei tipi di posta personalizzati in un ordine particolare. Il trucco è registrare qualsiasi tassonomia in cui la lumaca inizia con la lumaca del tuo tipo di post prima di registrare quel tipo di post personalizzato. Ad esempio, supponiamo che le seguenti lumache:

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

Quindi è possibile registrarli in questo ordine:

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, 
        ) 
);

Se devi assolutamente avere un URL come:

/ products / type / cell -phones / brand / samsung / test-product-1
»Visualizza il prodotto (singolo post personalizzato)

Quindi avresti bisogno di una regola di riscrittura simile a questa:

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

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

Ecco come ridefinire correttamente l'URL del singolo post.

Imposta la riscrittura su false per il tipo di post personalizzato. (Lascia l'archivio così com'è) e dopo aver registrato le tassonomie e i post, registra anche le seguenti regole di riscrittura.

  '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);

Quindi filtra post_type_link per creare la struttura URL desiderata, consentendo valori di tassonomia non impostati. Modificando il codice dal post collegato, avresti:

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);

Ora devo solo capire come riscrivere l'URL della tassonomia del marchio senza il tag del marchio principale e dovrei corrispondere esattamente all'URL desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.