每个产品变体的自定义URL-重写规则

时间:2017-09-15 作者:user1049961

我想为我的每个产品变体都有一个单独的url。为此,我需要创建一个重写规则,用于产品URL

Ie,我的产品URL是https://example.com/product/tshirt/

该产品有两种变体-尺寸和颜色。我希望能够访问url上的产品,如https://example.com/product/tshirt/size-s-color-black

这显然与add_rewrite_rule 作用我不知道如何构建url结构,以便能够访问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\');
有人吗?

2 个回复
最合适的回答,由SO网友:user1049961 整理而成

好的,对于任何想了解这一点的人来说,这里有一个我想到的完整插件,它解决了这个问题:

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

SO网友:David Salcer

我的意图:在change reload页面上,将ID作为URL传递?属性,以便我可以在下一页上以get的形式获取它。我有同样的意图。但我想将其作为更好的属性传递到URL中。这里的建议并不真正符合我的意图,因此我根据自己的目的对其进行了一些修改。我所需要的商店实际上是有意地专门使用单一变体,没有2-3个混合在一起。

<script>
        jQuery(function($){
            setTimeout( function(){
                $( ".single_variation_wrap" ).on( "show_variation", function ( event, variation ) {
                    //alert( variation.variation_id );
                    console.log( variation.variation_id );


                    var url = \'<?php echo get_permalink($post->ID);?>\';
                    //$(\'input.variation_id\').change( function(){


                    console.log(\'You just selected variation #\' + variation.variation_id);
                    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 +\'?variation_id=\'+ variation.variation_id +\'&\'+attributeSlug+\'=\' + val.value;
                        });
                        console.log(\'Relocating #\' + variation.variation_id);
                        //window.location.replace(url);
                        window.location.href = url;
                    }

                } );
            }, 400 );

        });
    </script>
不确定这是否是最好的好方法,但这对我来说是可行的,它甚至会在变量下拉列表中保留选定的值,因为它只是一个值。

我在此操作中调用上面的脚本:

添加操作(“woocommerce\\u before\\u add\\u to\\u cart\\u quantity”,“destone\\u variation\\u modification”);

结束

相关推荐