web-dev-qa-db-fra.com

URL personnalisée pour chaque variante de produit - règles de réécriture

J'aimerais avoir une URL distincte pour chacune de mes variantes de produits. Pour cela, il me faudrait créer une règle de réécriture, qui fonctionnera sur les URL du produit.

Par exemple, l'URL de mon produit est https://example.com/product/tshirt/

Le produit a deux variations - taille et couleur. Je voudrais pouvoir accéder au produit sur une URL telle que https://example.com/product/tshirt/size-s-color-black

Cela a clairement quelque chose à voir avec la fonction add_rewrite_rule. Je ne sais pas comment construire la structure d'URL pour pouvoir accéder à la partie variations de l'URL

function custom_rewrite_basic() {
  add_rewrite_rule('^product/([0-9]+)/([0-9]+)?', 'index.php?page_id=$matches[1]&variations=$matches[2]', 'top');
}
add_action('init', 'custom_rewrite_basic');

N'importe qui?

2
user1049961

Ok, pour ceux qui recherchent ceci, voici un plugin complet que j'ai proposé, qui résout le problème:

<?php
/*
Plugin Name: WooCommerce Variations URL
Description: Adds support for variation-specific URL's for WooCommerce product variations
Author: Václav Greif
Version: 1.0
Author URI: https://wp-programator.cz
*/

namespace WCVariationsUrl;

final class Init
{
    /**
     * Call this method to get singleton
     *
     * @return Init
     */
    public static function Instance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new Init();
        }
        return $inst;
    }

    /**
     * Private ctor so nobody else can instance it
     *
     */
    private function __construct()
    {
        $this->add_actions();
    }

    /**
     * Add actions
     */
    function add_actions() {
        add_filter('woocommerce_dropdown_variation_attribute_options_args',array($this,'variation_dropdown_args'));
        add_action('init', array($this,'add_rewrite_rules'));
        add_action('wp_head', array($this,'add_js_to_head'));

    }

    function variation_dropdown_args($args) {
        // Get the WooCommerce atts
        $attributes =  wc_get_attribute_taxonomies();
        $atts = [];
        foreach ($attributes as $attribute) {
            $atts[] = $attribute->attribute_name;
        }

        // Get the variations part of URL
        $url_string = get_query_var('variation');

        if ($url_string) {
            $array = [];
            preg_replace_callback(
                "/(\w++)(?>-(\w+-?(?(?!" . implode("|", $atts) . ")(?-1))*))/",
                function($matches) use (&$array) {
                    $array[$matches[1]] = rtrim($matches[2], '-');
                },
                $url_string
            );

            if (!empty($array)) {
                $attribute_key = str_replace('pa_','',$args['attribute']);

                if (array_key_exists($attribute_key,$array)) {
                    $args['selected'] = $array[$attribute_key];
                }
            }
        }

        return $args;

    }

    function add_rewrite_rules() {
        add_rewrite_rule('^product/([^/]*)/([^/]*)/?','index.php?product=$matches[1]&variation=$matches[2]','top');
        add_rewrite_tag('%variation%', '([^&]+)');
    }

    function add_js_to_head() {
        if (!function_exists('is_product') || !is_product())
            return;

        global $post;
        ?>

        <script type="text/javascript">
            var url = '<?php echo get_permalink($post->ID);?>';
            jQuery( document ).ready(function($) {
                setTimeout(
                    function() {
                        $('table.variations select').on('change',function() {
                            var attributes = [];
                            var allAttributesSet = true;
                            $('table.variations select').each(function() {
                                var value = $(this).val();
                                if (value) {
                                    attributes.Push({
                                        id: $(this).attr('name'),
                                        value: value
                                    });
                                } else {
                                    allAttributesSet = false;
                                }
                            });

                            if (allAttributesSet) {
                                $.each(attributes,function(key, val) {
                                    var attributeSlug = val.id.replace('attribute_pa_','');
                                    url = url + attributeSlug + '-' + val.value
                                    if($(this)[0] !== $(attributes).last()[0]) {
                                        url = url + '-';
                                    }
                                });
                                window.location.replace(url);
                            }
                        });

                    }, 1000
                )
            });
        </script>
    <?php }
}

Init::Instance();
3
user1049961