如何在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如下:
解决方案
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
相关产品推荐
相关产品推荐

