web-dev-qa-db-fra.com

Comment ajouter plusieurs taxonomies à l'URL?

Plusieurs taxonomies dans l'URL

Comment ajouter plusieurs taxonomies à l'URL ayant les caractéristiques suivantes:

  • Type de poste: produits
  • Taxonomie: produit_type
  • Taxonomie: product_brand


Ajouter un nouveau produit et sélectionner le type et la marque pour ce produit:

Lors de l'ajout d'un nouveauproduit, il existe deux zones de taxonomie (type_produit et marque_produit). Appelons cette nouvelle publicationTest Product 1. La première chose que nous souhaitons faire est de cocher le type de produit avec lequel je traite, par exempletéléphones portables. Ensuite, je veux cocher la marque à laquelle appartient le produit, disonssamsung.

Maintenant, "Produit test 1} _ " est associé au type"téléphones portables"et à la marque" samsung ".

Le résultat final souhaité est:

/produits
"Voir tous les messages personnalisés

/produits/téléphones portables
"Voir tous les messages personnalisés avec le taxonomie

/produit/téléphones portables/samsung/
"Voir tous les messages personnalisés où la taxonomie est téléphones portablesETsamsung

/produits/téléphones cellulaires/samsung/test-product-1
"Voir le produit (publication personnalisée unique)


La question

Comment pourrait-on rendre cela possible? Ma pensée initiale consistait à utiliser une seule taxonomie, ayant"téléphones portables"} _ comme terme parent de"samsung". En réalité, l’application 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 cela, car il génère 404 problèmes et WP ne permet pas certaines choses.
WP.org "taxonomy-archive-template

Cela m’a amené à repenser la structure, à quitter les taxonomies et ses termes et je me suis dit; pourquoi ne pas créer une 2ème taxonomie, associer le type de message à celui-ci et l'ajouter à l'URL?

Bonne question en effet, mais comment?

8
DRSK

Ceci est certainement possible en utilisant certaines règles de réécriture de vos propres dans une certaine mesure. Le WP_Rewrite API expose des fonctions qui vous permettent d’ajouter des règles de réécriture (ou des "mappes") pour convertir une requête en requête.

Il est indispensable de rédiger de bonnes règles de réécriture, dont le plus important est la compréhension de base des expressions régulières. Le moteur WordPress Rewrite utilise des expressions régulières pour traduire des parties d'une URL en requêtes afin d'obtenir des publications.

This est un tutoriel court et utile 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 telles que:

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

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

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

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

Vous devrez flush_rewrite_rules() dès que vous aurez ajouté la règle de réécriture pour l’enregistrer dans la base de données. Ceci n’est fait qu’une 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 procédant comme suit:

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

Le résultat final

C'est ce que j'ai proposé en partie en utilisant 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:

Ça marche. Bien que vous soyez 'obligatoire' pour affecter les deux taxonomies à chaque publication, sinon l'URL aura un '/' "'/products/taxonomy//postname' suivant. Puisque je vais assigner les deux taxonomies à tous mes produits, 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 à y répondre!

3
DRSK

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

/produits
"Voir tous les messages personnalisés

/produits/type/téléphones cellulaires
"Voir tous les messages personnalisés avec le taxonomie

/produits/type/téléphones portables/marque/samsung
"Voir tous les messages personnalisés où la taxonomie est téléphones portablesETsamsung

/marque/samsung
"Voir tous les messages personnalisés où la taxonomie est samsung

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

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

Cependant, vous devez enregistrer vos taxonomies et vos types de publication personnalisés dans un ordre particulier. L'astuce consiste à enregistrer toute taxonomie où le slug commence par le slug de votre post-type avant d'enregistrer ce type de post personnalisé. Par exemple, supposons les slugs suivants:

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 semblable à ceci:

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

UPDATEhttps://stackoverflow.com/questions/3861291/multiple-custom-permalink-structures-in-wordpress

Voici comment redéfinir correctement l'URL d'une publication unique.

Définissez re-write sur false pour le type de publication personnalisé. (Laissez les archives telles quelles), puis après avoir enregistré les taxonomies et les messages, 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 l'article lié, 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 la taxonomie de la marque sans la balise de marque principale, et je devrais correspondre exactement à l'URL de votre choix.

1
marfarma

Vérifiez de cette façon, il y a encore des bugs avec les archives de la 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');
1
Luis Abarca