好的,对于任何想了解这一点的人来说,这里有一个我想到的完整插件,它解决了这个问题:
<?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();