问题描述

我的网站中有以下几行代码,将在 WooCommerce 的单个产品页面的底部显示相关产品…

的 functions.php:

// display upsells and related products within dedicated div with different column and number of products
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20);
remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10);
add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);

function woocommerce_output_related_products() {
    $output = null;

    ob_start();
    woocommerce_related_products(4,4);
    $content = ob_get_clean();
    if($content) { $output .= $content; }

    echo '<div class="clear"></div>' . $output;
}

由于它显示了 4 个已经被分类为相同名称的产品,那么我如何修改上述内容呢?

例如,我有一个名为’Automotive’ 的产品类别,在这个类别中,是几个标签 – ‘Holden’,’Ford’,’Toyota’,’Nissan’ 等。

我希望在底部显示 4 个产品,与用户当前正在查看的产品标签相关。

最佳解决方案

首先,您无法立即通过您在问题中显示的代码实现您所描述的目标。要了解为什么没有直接的方法与该代码,你必须看看你正在使用的 – woocommerce_related_products() – 做你迄今为止做的。

其次,你必须明白,因为否则你不能问一个一个问题,这绝对是你的目标,以确保你得到一个答案。此外,您必须记住,WordPress Development 的主要范围设置在 wordpress 核心相关问题上 – 如果您有兴趣,则正在讨论 WordPress Development Meta,一个特定主题是 Our wooes and future of platform plugins at WPSE 。所以,如果您提出有关插件的问题,例如 woocommerce,您应该将其分解为使其与核心功能尽可能相关 – 请参阅下一点 – 因为您不能指望人们了解每个插件的每个细节使用。

第三,现在让我深入了解发生了什么。正如你所说,你现在使用 woocommerce_related_products()。如果你看看源码,你会发现这个功能使用 woocommerce_get_template()获取 related.php 模板。 woocommerce_get_template()再次使用 woocommerce_locate_template()来定位模板,后者通过使用 wordpress 核心函数 locate_template()来实现。现在有一个连接回到核心,导致认识到上述 – 并且有希望的检查 – woocommerce 功能本质上是包装以扩展核心功能。通过分析功能依赖关系变得清晰的另一件事情是,我之前说过,需要一种不同的方法来实现您的目标,因为 woocommerce_related_products() – 现在是不可否认的 – 显而易见的 – 不是正确的。如果您跟随我的解释,并且到目前为止已经彻底阅读,您意识到 related.php 包含您要查找的内容。我特别在谈论 get_related()功能,其中包括 woocommerce_product_related_posts 钩子,并使用 wp_get_post_terms()get_posts()的核心功能 – get_related()用于获取一组 ids 。另外还有 woocommerce_related_products_args 挂钩,可用于修改 related.php 内相关产品查询的参数,WP_Query 用于此。该查询使用 get_related()调用中生成的 ID 。我想你现在有一切可以解决你的问题。实际上,这样做比较简单,给出了如何定制相关产品的几乎完整的概述。我没有提到检查的源代码的每个功能 – 功能和/或钩子,但绝对是所有重要的。现在应该更清楚的是,如何将 woocommerce 的相关产品功能追溯到 wordpress 核心功能。

第四,我来,你应该在哪里应用你的定制和你应该提出什么。例如:

Woocommerce 拥有 woocommerce_product_related_posts 挂钩来定制 get_posts()调用来确定相关产品。

码:

        // Get the posts
        $related_posts = get_posts( apply_filters('woocommerce_product_related_posts', array(
                'orderby' => 'rand',
                'posts_per_page' => $limit,
                'post_type' => 'product',
                'fields' => 'ids',
                'meta_query' => $meta_query,
                'tax_query' => array(
                        'relation' => 'OR',
                        array(
                                'taxonomy' => 'product_cat',
                                'field' => 'id',
                                'terms' => $cats_array
                        ),
                        array(
                                'taxonomy' => 'product_tag',
                                'field' => 'id',
                                'terms' => $tags_array
                        )
                )
        ) ) );

我如何定制这个来实现我的目标?哪个是显示相同产品类别的相关产品–product_cat – 并且具有相同的标签 – product_tag – 作为显示的单个产品。

没有给你一个结论 – 至少如果你有希望获得完整的准备好的代码 – 答案,你可能应该做的第一件事是将 tax_query 参数关系从 OR 更改为 AND 。


笔记:

  • 我把这个更长的描述性答案与上面连接的正在进行的讨论相结合

  • 我希望你不介意,这不仅是你的问题的答案,而且还追求实现一般的教育目的

  • 这是未经测试的,因为没有实际的准备好的代码

  • 最后但并非最不重要的是,可以预见,随着发行版 2.1 的发布,将会实现一些重要的代码更改,但是考虑到现在的 2.0.19 以上代码是有效的


编辑:

你真的不应该直接编辑 (插件) 核心类。这是有问题的,因为您必须再次维护对更新的更改,因为核心文件如果执行一个更新并覆盖。特别是如果在这种情况下很容易避免,下面的代码将会执行您打算做的任何操作,也就是通过 functions.php 实现此更改。

码:

    add_filter( 'woocommerce_product_related_posts',
                'wpse_123436_change_wc_related_products_relation_to_and' );
    function wpse_123436_change_wc_related_products_relation_to_and() {
            $get_related_products_args = array(
                'orderby' => 'rand',
                'posts_per_page' => $limit,
                'post_type' => 'product',
                'fields' => 'ids',
                'meta_query' => $meta_query,
                'tax_query' => array(
                    'relation' => 'AND',
                    array(
                        'taxonomy' => 'product_cat',
                        'field' => 'id',
                        'terms' => $cats_array
                    ),
                    array(
                        'taxonomy' => 'product_tag',
                        'field' => 'id',
                        'terms' => $tags_array
                    )
                )
            );
            return $get_related_products_args;
    }


对于 WooCommerce 版本 2.1.0 及更高版本,上述钩子将不起作用,因为它不再存在,所以答案可用到版本 2.0.20 之前。但是 @NathanPowell 在 StackOverflow 上发现了一个关于可用的 v2.1.0 和 customization of the related products usable set of hooks 的一个很好的答案。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。