WordPress智库

添加自定义字段和选项卡到WooCommerce产品数据Metabox

在开发WooCommerce电子商务网站时,产品默认提供的元数据字段不够我们使用,我们需要添加自定义产品字段来实现我们特殊的需求,比如我们可以添加产品的产地、品牌等自定义数据。

我们可以通过自定义字段插件来添加字段,但是这种方法会在产品编辑页面新建一个 Metabox,增加了UI的复杂度。其实我们可以把需要的自定义字段添加到WooCommerce默认的「产品数据」Metabox,只需要简单的几段代码就可以。

添加自定义字段表单项到现有选项卡

要添加自定义字段到现有的选项卡中,我们需要挂载两个钩子;一种用于输出字段,另一个用于保存字段的值。第一个钩子可以根据我们需要添加到的选项卡中下面的列表中选择一个

添加自定义字段表单

添加自定义表单字段的方法很简单,WooCommerce 为我们提供了一些显示常用表单的函数,我们直接在挂在到默认选项卡的钩子函数中使用这些函数添加表单字段即可,如下面代码中的 woocommerce_wp_text_input 函数,WooCommerce 支持的其他表单字段函数都可以在上面的链接中找到。

add_action('woocommerce_product_options_inventory_product_data', function ()
{
    woocommerce_wp_text_input([
        'id'            => '_number_in_package',
        'label'         => __('Number in package', 'txtdomain'),
        'wrapper_class' => 'show_if_simple',
    ]);
});

通过添加上面的代码,我们可以得到如下图中的成果,最下面的「Number in package」就是我们刚刚添加的字段。

保存自定义字段数据

需要注意的是,添加了自定义字段后,保存产品的时候,系统并不会自动保存我们这些自定义字段的值,我们需要通过下面的代码手动保存这些数据。

add_action('woocommerce_process_product_meta', function ($post_id)
{
    $product     = wc_get_product($post_id);
    $num_package = isset($_POST[ '_number_in_package' ]) ? $_POST[ '_number_in_package' ] : '';
    $product->update_meta_data('_number_in_package', sanitize_text_field($num_package));
    $product->save();
});

在前端输出我们添加的自定义数据

在后台添加了数据之后,我们就可以在模版代码中获取使用这些数据了,直接使用$product->get_meta() 方法获取我们添加的自定义字段值即可。

add_action('woocommerce_product_meta_start', function ()
{
    global $post;
    $product     = wc_get_product($post->ID);
    $num_package = $product->get_meta('_number_in_package');
    if ( ! empty($num_package)) {
        printf('<div class="custom-sku">%s: %s</div>', __('Number in package', 'txtdomain'), $num_package);
    }
});

面向对象方式

为了方法使用,我们可以把上面的代码写成一个类,在需要的地方示例化这个类就可以了。

class ProductMeta
{

    public function __construct()
    {
        if (is_admin()) {
            add_action('woocommerce_product_options_shipping', [$this, 'add_fields']);
            add_action('woocommerce_process_product_meta', [$this, 'save_fields']);
        }

        add_action('woocommerce_product_meta_start', [$this, 'show_fields']);
    }

    public function add_fields()
    {
        woocommerce_wp_text_input([
            'id'    => '_hs_code',
            'label' => __('HS Code', 'wc-javing-api'),
        ]);
    }


    public function save_fields($post_id)
    {
        $product     = wc_get_product($post_id);
        $num_package = isset($_POST[ '_hs_code' ]) ? $_POST[ '_hs_code' ] : '';
        $product->update_meta_data('_hs_code', sanitize_text_field($num_package));
        $product->save();
    }

    public function show_fields()
    {
        global $post;
        $product     = wc_get_product($post->ID);
        $num_package = $product->get_meta('_hs_code');

        if ( ! empty($num_package)) {
            printf('<div class="custom-sku">%s: %s</div>', __('Number in package', 'wc-javing-api'), $num_package);
        }
    }
}

添加表单项到自定义产品数据选项卡

如果我们需要添加的元数据比较多,并且这些元数据放到现有的产品数据选项卡中不合适,我们可以新建一个自定义产品数据选项卡,然后把自定义字段表单项添加到新建的产品数据选项卡中。

比如,我们需要添加一个「其他信息」的选项卡,然后添加几个自定义产品字段到这个选项卡中。

添加产品数据选项卡标题

首先,我们通过 woocommerce_product_data_tabs Filter 添加自定义选项卡标题到产品数据Metabox 选项卡中。

add_filter('woocommerce_product_data_tabs', function ($tabs)
{
    $tabs[ 'additional_info' ] = [
        'label'    => __('Additional info', 'txtdomain'),
        'target'   => 'additional_product_data',
        'class'    => ['hide_if_external'],
        'priority' => 25,
    ];

    return $tabs;
});

添加产品数据选项卡内容

和添加到默认的选项卡一样,我们可以使用WooCommerce为我们提供的表单字段函数来快速添加表单字段。当然,如果需要,我们也可以通过HTML或PHP代码自行添加表单字段,注意下面代码中的 「id」需要上面代码中的「target」的值。

add_action('woocommerce_product_data_panels', function ()
{
    ?>
    <div id="additional_product_data" class="panel woocommerce_options_panel hidden"><?php

    woocommerce_wp_text_input([
        'id'            => '_dummy_text_input',
        'label'         => __('Dummy text input', 'txtdomain'),
        'wrapper_class' => 'show_if_simple',
    ]);
    woocommerce_wp_checkbox([
        'id'            => '_dummy_checkbox',
        'label'         => __('Dummy checkbox', 'txtdomain'),
        'wrapper_class' => 'hide_if_grouped',
    ]);
    woocommerce_wp_text_input([
        'id'                => '_dummy_number_input',
        'label'             => __('Dummy number input', 'txtdomain'),
        'type'              => 'number',
        'custom_attributes' => [
            'step' => '1',
            'min'  => '0',
        ],
    ]);

    ?></div><?php
});

添加了上面的代码后,我们可以在产品数据选项卡中看到如下的界面,又一个「Addition info」的自定义选项卡被添加到了 inventory 选项卡下面,该选项卡中有我们需要添加的 3 个自定义字段。

保存自定义选项卡数据

和添加到默认的选项卡一样,我们需要收到保存我们添加的自定义字段数据。

add_action('woocommerce_process_product_meta', function ($post_id)
{
    $product = wc_get_product($post_id);

    $product->update_meta_data('_dummy_text_input', sanitize_text_field($_POST[ '_dummy_text_input' ]));

    $dummy_checkbox = isset($_POST[ '_dummy_checkbox' ]) ? 'yes' : '';
    $product->update_meta_data('_dummy_checkbox', $dummy_checkbox);

    $product->update_meta_data('_dummy_number_input', sanitize_text_field($_POST[ '_dummy_number_input' ]));

    $product->save();
});

通过插件实现本文中的功能

除了通过本文中的代码添加自定义字段,我们还可以使用 WC Fields Factory 插件实现本文中的功能,有需要的朋友可以根据自己的需求和喜好选择。

退出移动版