You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Divi自定义模块中获取WooCommerce产品及自定义属性数据?

在自定义Divi模块中获取WooCommerce产品自定义属性数据

问题

我是自定义Divi模块开发新手,正遵循官方教程创建新的Divi模块。我们项目需使用WooCommerce,但现有WooCommerce模块无法完全满足需求,想知道如何获取产品数据并插入到我创建的模块中?

目标产品包含自定义属性,部分现有模块可用,但我需要创建专属模块,且希望直接访问数据库中的数据,无需在Divi模块后台选择动态数据。

当前我的PHP代码如下:

<?php

class wsdm_Stars extends ET_Builder_Module
{

    public $slug       = 'wsdm_woo_stars';
    public $vb_support = 'on';

    public function init()
    {
        $this->name = esc_html__('Woocommerce Stars', 'wsdm-woo-stars');
    }

    public function get_fields()
    {
        return array(
            'heading'     => array(
                'label'           => et_builder_i18n('Heading'),
                'type'            => 'text',
                'option_category' => 'basic_option',
                'description'     => esc_html__('Input your desired heading here.', 'wsdm-woo-stars'),
                'toggle_slug'     => 'main_content',
                'dynamic_content' => 'text',
            ),
        );
    }

    private function renderStars(int $stars)
    {
        return str_repeat('<div className="wsdm-star-rating"></div>', (int)$stars);
    }

    public function render($attrs, $content = null, $render_slug)
    {
        return sprintf(
            '<div className="wsdm-product">
                <div className="wsdm-product-rating">
                    <span>Estrellas: </span>
                    %2$s
                </div>
            </div>',
            esc_html($this->props['heading']),
            $this->renderStars($this->props['heading']),
        );
    }
}

new wsdm_Stars;

我仅需获取estrellas属性,但理想情况下希望直接在PHP或JS中获取所有属性并格式化。

测试时我尝试获取产品标题(标准字段),但渲染结果不符合预期:
测试渲染结果异常

用于打印动态数据的JSX代码:

<h1 className="wsdm_stars">{this.props.heading}</h1>

目标自定义属性estrellas如下:
目标自定义属性estrellas


解决方案

1. 在PHP中直接获取WooCommerce产品数据(推荐)

Divi模块的render方法中,可通过WooCommerce的内置函数直接获取产品对象及属性:

方法一:获取当前产品页的产品数据

如果模块仅在产品详情页使用,直接调用wc_get_product()获取当前产品:

public function render($attrs, $content = null, $render_slug) {
    // 获取当前产品对象
    $product = wc_get_product();
    if (!$product) {
        return '<div class="wsdm-product">无可用产品数据</div>';
    }

    // 获取指定自定义属性
    $estrellas = $product->get_attribute('estrellas');
    // 获取所有产品属性(返回关联数组)
    $all_attributes = $product->get_attributes();

    // 修复原代码的sprintf参数顺序错误
    return sprintf(
        '<div class="wsdm-product">
            <div class="wsdm-product-rating">
                <span>Estrellas: </span>
                %s
            </div>
        </div>',
        $this->renderStars($estrellas)
    );
}
方法二:添加产品选择字段,支持任意页面使用

如果模块需要在非产品页使用,可在字段配置中添加产品选择器,让用户手动指定目标产品:

public function get_fields() {
    return array(
        'product_id' => array(
            'label'           => esc_html__('选择产品', 'wsdm-woo-stars'),
            'type'            => 'select',
            'option_category' => 'basic_option',
            'options'         => $this->get_woo_product_options(),
            'toggle_slug'     => 'main_content',
        ),
    );
}

// 生成产品下拉选项列表
private function get_woo_product_options() {
    $options = array('' => esc_html__('选择产品', 'wsdm-woo-stars'));
    $products = wc_get_products(array('limit' => -1));
    foreach ($products as $product) {
        $options[$product->get_id()] = $product->get_name();
    }
    return $options;
}

public function render($attrs, $content = null, $render_slug) {
    $product_id = $this->props['product_id'];
    if (!$product_id) {
        return '<div class="wsdm-product">请选择产品</div>';
    }

    $product = wc_get_product($product_id);
    if (!$product) {
        return '<div class="wsdm-product">产品不存在</div>';
    }

    $estrellas = $product->get_attribute('estrellas');
    return sprintf(
        '<div class="wsdm-product">
            <div class="wsdm-product-rating">
                <span>Estrellas: </span>
                %s
            </div>
        </div>',
        $this->renderStars($estrellas)
    );
}

2. 在JSX(可视化编辑器)中获取预览数据

如果需要在Divi可视化编辑器中实时预览数据,需在PHP中传递数据到前端JS:

// 在模块类中添加方法,允许JS渲染
public function get_advanced_fields_config() {
    return array(
        'js' => array(
            'render' => true,
        ),
    );
}

public function render($attrs, $content = null, $render_slug) {
    $product = wc_get_product();
    $estrellas = $product ? $product->get_attribute('estrellas') : 0;

    // 将产品数据传递到前端JS
    wp_localize_script('et-builder-modules-global', 'wsdm_product_data', array(
        'estrellas' => $estrellas,
    ));

    // 渲染PHP内容...
}

对应的JSX代码:

export default class WsdmStars extends ETBuilderModule {
    constructor(props) {
        super(props);
    }

    render() {
        const estrellas = window.wsdm_product_data?.estrellas || 0;
        return (
            <div className="wsdm-product">
                <div className="wsdm-product-rating">
                    <span>Estrellas: </span>
                    {Array.from({length: estrellas}, () => (
                        <div className="wsdm-star-rating"></div>
                    ))}
                </div>
            </div>
        );
    }
}

WsdmStars.moduleName = 'wsdm_woo_stars';

3. 修复原代码的核心问题

原代码存在两个明显错误:

  • sprintf参数顺序错误:使用了%2$s但未对应正确的参数位置
  • 错误将heading字段值传递给renderStars方法,应替换为实际的星级属性值

内容的提问来源于stack exchange,提问作者DevWizard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:57:06