Comment ajouter plusieurs taxonomies à l'URL?

8

Taxonomies multiples dans l'URL

Comment ajouter plusieurs taxonomies à l'URL présentant les éléments suivants:

  • Type de message: produits
  • Taxonomie: product_type
  • Taxonomie: product_brand


Ajout d'un nouveau produit et sélection du type et de la marque pour ce produit:

Lors de l'ajout d'un nouveau produit , il existe deux cases de taxonomie (product_type et product_brand). Appelons ce nouveau post test produit 1 . La première chose que nous voulons faire est de cocher le type de produit avec lequel je traite, disons les téléphones portables . Ensuite, je veux cocher la marque à laquelle le produit appartient, disons samsung.

Désormais, " Test Product 1 " est associé au type "cell-phones" et à la marque "samsung" .

Le résultat final souhaité est:

/ produits
»Voir tous les articles personnalisés

/ produits / téléphones portables
»Voir tous les articles personnalisés avec la taxonomie des téléphones portables

/ produit / téléphones portables / samsung /
»Voir tous les articles personnalisés où la taxonomie est téléphones portables ET samsung

/ produits / téléphones portables / samsung / test-product-1
»Voir le produit (poste personnalisé unique)


La question

Comment rendre cela possible? Ma pensée initiale utilisait une taxonomie, ayant "téléphones portables" comme terme parent de "samsung" . En fait, l'ajout de la taxonomie et de ses termes n'était pas si difficile. Mais cela a conduit à beaucoup d'autres problèmes, certains bien connus, d'autres moins. Quoi qu'il en soit, cela ne fonctionne pas comme ça car cela donne 404 problèmes et WP ne permettra pas certaines choses.
WP.org »taxonomie-archive-modèle

Cela m'a conduit à avoir repensé la structure, à devoir quitter les taxonomies et ses termes et j'ai pensé; pourquoi ne pas créer une 2ème taxonomie, et y associer le type de poste et l'ajouter à l'url?

Bonne question en effet, mais comment?

DRSK
la source
pouvez-vous vérifier ce lien j'ai un problème avec la même chose stackoverflow.com/questions/34351477/…
Sanjay Nakate

Réponses:

7

Ceci est certainement possible en utilisant certaines de vos règles de réécriture dans une certaine mesure. L' API WP_Rewrite expose des fonctions qui vous permettent d'ajouter des règles de réécriture (ou «cartes») pour convertir une demande en requête.

Il existe des conditions préalables à l'écriture de bonnes règles de réécriture, et la plus importante est la compréhension de base des expressions régulières. Le moteur de réécriture WordPress utilise des expressions régulières pour traduire des parties d'une URL en requêtes pour obtenir des publications.

Ceci est un court et bon tutoriel sur PHP PCRE (expressions régulières compatibles Perl).

Donc, vous avez ajouté deux taxonomies, supposons que leurs noms sont:

  • type de produit
  • Marque de produit

Nous pouvons les utiliser dans des requêtes comme ceci:

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

La requête serait ?product_type=cell-phones&product_brand=samsung. Si vous saisissez cela comme votre requête, vous obtiendrez une liste de téléphones Samsung. Pour réécrire /cell-phones/samsungdans cette requête, une règle de réécriture doit être ajoutée.

add_rewrite_rule()fera cela pour vous. Voici un exemple de ce à quoi pourrait ressembler votre règle de réécriture dans le cas ci-dessus:

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

Vous devrez le faire flush_rewrite_rules()dès que vous aurez ajouté la règle de réécriture pour l'enregistrer dans la base de données. Cela n'est fait qu'une seule fois, il n'est pas nécessaire de le faire à chaque demande, une fois qu'une règle est supprimée. Pour le supprimer, rincez simplement sans la règle de réécriture ajoutée.

Si vous souhaitez ajouter une pagination, vous pouvez le faire en faisant quelque chose comme:

add_rewrite_rule( '^products/([^/]*)/([^/]*)/(\d*)?',
    'index.php?product_type=$matches[1]&product_brand=$matches[2]&p=$matches[3]',
    'top' );
soulseekah
la source
1
L'article le plus simple que j'ai vu concernant les règles de réécriture de wordpress. J'ai beaucoup lu, mais après avoir lu cela, j'ai finalement fait fonctionner les choses. Merci! +1
evu
3

Le résultat final

Voici ce que j'ai trouvé en utilisant partiellement des morceaux de toutes les réponses que j'ai:

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


Quelques idées:

Cela fonctionne. Bien que vous soyez «obligé» d'attribuer les deux taxonomies à chaque publication, l'URL aura une fin '/'» '/products/taxonomy//postname'. Puisque je vais affecter les deux taxonomies à tous mes procuts, ayant un type et une marque, ce code semble fonctionner pour mes besoins. Si quelqu'un a des suggestions ou des améliorations, n'hésitez pas à répondre!

DRSK
la source
Excellent. Merci d'avoir posté votre solution. Veuillez le sélectionner comme réponse une fois que suffisamment de temps s'est écoulé. En outre, il est recommandé de voter pour toutes les réponses utiles.
marfarma
J'ai du mal à faire fonctionner cela, je ne sais pas pourquoi. Même copier / coller dans mes fonctions plutôt que d'essayer de porter sur vos modifications me donne des tonnes d'erreurs. Je pense que quelque chose dans le cœur de WordPress doit avoir changé entre le moment où il a été écrit (il y a plus de 3 ans) et aujourd'hui. J'essaie de comprendre la même chose: wordpress.stackexchange.com/questions/180994/…
JacobTheDev
flush_rewrite_rules()sur init? ne le fais pas. Fondamentalement, vous réinitialisez vos règles de réécriture à chaque chargement de page.
honk31
1

Vérifiez de cette façon, il y a encore quelques bugs avec les archives de marque

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
la source
1

Bien que ce ne soit pas la structure d'URL souhaitée, vous pouvez obtenir:

/ produits
»Voir tous les articles personnalisés

/ produits / type / téléphones portables
»Voir tous les articles personnalisés avec la taxonomie des téléphones portables

/ produits / type / téléphones portables / marque / samsung
»Voir tous les articles personnalisés où la taxonomie est téléphones portables ET samsung

/ brand / samsung
»Voir tous les articles personnalisés où la taxonomie est samsung

/ product / test-product-1
»Voir le produit (publication personnalisée unique)

sans avoir à spécifier de règles de réécriture personnalisées.

Cela nécessite cependant que vous enregistriez vos taxonomies et types de publication personnalisés dans un ordre particulier. L'astuce consiste à enregistrer toute taxonomie où le slug commence par le slug de votre type de publication avant d'enregistrer ce type de publication personnalisé. Par exemple, supposons les limaces suivantes:

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

Ensuite, vous pouvez les enregistrer dans cet ordre:

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

Si vous devez absolument avoir une URL comme:

/ produits / type / téléphones portables / marque / samsung / test-product-1
»Voir le produit (publication personnalisée unique)

Ensuite, vous auriez besoin d'une règle de réécriture quelque chose comme ceci:

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

MISE À JOUR /programming/3861291/multiple-custom-permalink-structures-in-wordpress

Voici comment vous redéfinissez correctement l'URL de publication unique.

Définissez la réécriture sur false pour le type de publication personnalisé. (Laissez l'archive telle quelle), puis après avoir enregistré les taxonomies et les publications, enregistrez également les règles de réécriture suivantes.

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

Ensuite, filtrez post_type_link pour créer la structure d'URL souhaitée - en tenant compte des valeurs de taxonomie non définies. En modifiant le code de la publication liée, vous auriez:

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

Maintenant, je dois juste comprendre comment réécrire l'URL de taxonomie de la marque sans la balise de marque principale, et je dois correspondre exactement à l'URL souhaitée.

marfarma
la source