跳到主要内容

添加字段并传递值

本文档描述了开发者如何将一个输入字段插入到结账块中,并将该字段的值传递给 Store API,以便在处理结账时可用。

概述

开发者可以通过添加新的内部块并处理额外的数据,来扩展结账块,从而通过结账 POST 请求进行处理。 这涉及到利用古腾堡和 WooCommerce Blocks 提供的可扩展性接口。 我们的教程中对这一点进行了更详细的说明:教程:扩展 WooCommerce 结账块以添加自定义配送选项

前置条件

  • 了解 React 和古腾堡块编辑器。
  • 熟悉 WooCommerce Blocks 的可扩展性接口和 Store API。

逐步指南

1. 设置您的开发环境

确保您的项目中包含以下文件:

  • index.js: Webpack 的入口点,用于导入和注册块类型。
  • edit.js: 处理在编辑器界面中渲染块。
  • block.json: 提供块的元数据和配置。
  • block.js: 管理块的状态和用户交互。
  • frontend.js: 注册结账块组件以在前端使用。

请参考此教程,了解向结账块添加自定义配送选项的示例。

2. 将新的字段块添加到结账块中

要将字段块添加到结账块中,您需要在块的 block.json 文件中添加以下条目:

"parent": [ "woocommerce/checkout-shipping-methods-block" ],
"attributes": {
"lock": {
"type": "object",
"default": {
"remove": true,
"move": true
}
}
}
  • lock 属性 是一个对象,用于控制是否可以删除或移动该块。 默认情况下,lock 属性设置为允许删除和移动块。 但是,通过修改 lock 属性,您可以“强制”块不可删除。 例如,您可以将 remove 和 move 属性都设置为 false,以防止删除或移动该块。
  • parent 属性 指定此块应嵌套在哪个父块中。 它确定块将在哪里渲染。 在我们的示例中,该块是 woocommerce/checkout-shipping-methods-block 的子块。 这意味着您的块将在 woocommerce/checkout-shipping-methods-block 中渲染。 如果不需要配送方法块,则您的块将不会渲染。

3. 设置自定义结账数据

我们可以将添加的字段数据设置为 setExtensionData 函数,以便在处理订单时将其发送到 wc/store/checkout 端点:

setExtensionData(
'namespace-of-your-block',
'key-of-your-data',
value
);

参数

  • namespace string - 您的块的命名空间。
  • key string - 您的数据的键。
  • value any - 您的数据的价值。

工作原理

  1. setExtensionData 通过 props 传递给内部块。
  2. 它更新 wc/store/checkout 数据存储中的 extensionData 键。
  3. 当向结账端点发送 POST 请求时,此键作为请求体的一部分传递。

代码示例

// block.js
export const Block = ( { checkoutExtensionData, extensions } ) => {
/**
* `setExtensionData` 会使用提供的值更新 `wc/store/checkout` 数据存储。
* 它可以用于在提交结账表单时,将客户端数据传递到服务器。
*/
const { setExtensionData } = checkoutExtensionData;
}

// ... 一些代码

useEffect( () => {
/**
* 此代码应使用 `setExtensionData` 来更新结账数据存储中 `namespace-of-your-block` 命名空间下的 `key-of-your-data` 键。
*/
setExtensionData(
'namespace-of-your-block',
'key-of-your-data',
value
);
}, [ setExtensionData, value ] );

截图

Redux Dev tool 的截图,显示在调用 setExtensionData 之前和之后的的数据存储:

之前之后
Redux Dev tool before setExtensionData callRedux Dev tool after setExtensionData call

4. 处理结账 POST 请求

为了处理添加的字段数据,我们需要扩展 Store API,以便告知它期望接收额外的数据。更多详情请参阅 在 Store API 中暴露您的数据

代码示例

我们将使用以下 PHP 文件作为示例:

  • custom-inner-block-blocks-integration.php 文件:当使用结账 blocks 时,在前端注册脚本、样式和数据。 更多详情请参考 IntegrationInterface 文档。
use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;

/**
* 用于与 WooCommerce Blocks 集成的类
*/
class Custom_Inner_Block_Blocks_Integration implements IntegrationInterface {

/**
* 集成的名称。
*
* @return string
*/
public function get_name() {
return 'new-field-block';
}

/**
* 调用时,会执行任何与集成相关的初始化/设置。
*/
public function initialize() {
// ... 这里有一些代码:(例如,初始化函数,用于注册脚本和样式,以及其他指令)
}

// ... 其他函数
}
  • custom-inner-block-extend-store-endpoint.php 文件:扩展 Store API,并添加钩子以保存和显示您的新字段块的说明。 默认情况下,此功能不会将自定义块中的数据保存到任何地方,但您可以添加自己的逻辑将数据保存到数据库。
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CartSchema;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;

/**
* 您的新字段块扩展 Store API。
*/
class Custom_Inner_Block_Extend_Store_Endpoint {
/**
* 存储 Rest 扩展实例。
*
* @var ExtendRestApi
*/
private static $extend;

/**
* 插件标识符,每个插件独一无二。
*
* @var string
*/
const IDENTIFIER = 'new-field-block';

/**
* 启动类和所需的钩子。
*
*/
public static function init() {
self::$extend = Automattic\WooCommerce\StoreApi\StoreApi::container()->get( Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema::class );
self::extend_store();
}

/**
* 将实际数据注册到每个端点。
*/
public static function extend_store() {
if ( is_callable( [ self::$extend, 'register_endpoint_data' ] ) ) {
self::$extend->register_endpoint_data(
[
'endpoint' => CheckoutSchema::IDENTIFIER,
'namespace' => self::IDENTIFIER,
'schema_callback' => [ 'Custom_Inner_Block_Extend_Store_Endpoint', 'extend_checkout_schema' ],
'schema_type' => ARRAY_A,
]
);
}
}

新字段块

/** * 将新的字段块结构化数据注册到结账端点。 * * @return array 注册的结构化数据。 * */ public static function extend_checkout_schema() { return [ 'Value_1' => [ 'description' => '字段的描述', 'type' => 'string', // ... 字段的类型,应该是一个字符串 'context' => [ 'view', 'edit' ], // ... 字段的上下文,应该是一个包含 'view' 和 'edit' 的数组 'readonly' => true, // ... 字段是否为只读,应该是一个布尔值 'optional' => true, // ... 字段是否为可选,应该是一个布尔值 ], // ... 其他值 ]; } }


- `new-field-block.php` 文件:主插件文件,加载 `custom-inner-block-blocks-integration.php` 和 `custom-inner-block-extend-store-endpoint.php` 文件。

```php
<?php
/**
* 插件名称: New Field Block
* 版本: 1.0
* 作者: Your Name Here
* 许可证: GPL-2.0-or-later
* 许可证 URI: https://www.gnu.org/licenses/gpl-2.0.html
* 文本域: new-field-block
*
* @package create-block
*/

// ... 一些代码

/**
* 包含实例化块所需的依赖项。
*/
add_action(
'woocommerce_blocks_loaded',
function() {
require_once __DIR__ . '/custom-inner-block-blocks-integration.php';

// 当 WC Blocks 加载时,初始化我们的商店端点扩展。
Custom_Inner_Block_Extend_Store_Endpoint::init();

add_action(
'woocommerce_blocks_checkout_block_registration',
function( $integration_registry ) {
$integration_registry->register( new Custom_Inner_Block_Blocks_Integration() );
}
);
}
);

// ... 一些代码

以下是一个示例,来自我们的 教程,说明如何在处理结账时获取此自定义字段的数据。 此示例来自 shipping-workshop-blocks-integration.php 文件。 完整的代码可以在此 GitHub 仓库 中找到。

# 配送说明保存

本节介绍如何保存配送说明。

我们使用一个钩子,即 `woocommerce_store_api_checkout_update_order_from_request` 操作,该操作会将配送工作坊的替代配送说明更新到订单元数据中。

该钩子的文档位于:https://github.com/woocommerce/woocommerce-blocks/blob/b73fbcacb68cabfafd7c3e7557cf962483451dc1/docs/third-party-developers/extensibility/hooks/actions.md#woocommerce_store_api_checkout_update_order_from_request

```php
private function save_shipping_instructions() {
/**
* We write a hook, using the `woocommerce_store_api_checkout_update_order_from_request` action
* that will update the order metadata with the shipping-workshop alternate shipping instruction.
*
* The documentation for this hook is at: https://github.com/woocommerce/woocommerce-blocks/blob/b73fbcacb68cabfafd7c3e7557cf962483451dc1/docs/third-party-developers/extensibility/hooks/actions.md#woocommerce_store_api_checkout_update_order_from_request
*/
add_action(
'woocommerce_store_api_checkout_update_order_from_request',
function( \WC_Order $order, \WP_REST_Request $request ) {
$shipping_workshop_request_data = $request['extensions'][$this->get_name()];
$alternate_shipping_instruction = $shipping_workshop_request_data['alternateShippingInstruction'];
$other_shipping_value = $shipping_workshop_request_data['otherShippingValue'];
$order->update_meta_data( 'shipping_workshop_alternate_shipping_instruction', $alternate_shipping_instruction );
$order->save();
},
10,
2
);
}

说明:

  • woocommerce_store_api_checkout_update_order_from_request:这是一个操作钩子,用于在结账更新订单时执行自定义操作。
  • \WC_Order $order:表示订单对象。
  • \WP_REST_Request $request:表示请求对象。
  • $request['extensions'][$this->get_name()]:从请求中获取扩展数据。
  • $order->update_meta_data():更新订单的元数据。
  • $order->save():保存订单。

使用方法:

  1. 确保已安装并激活相应的扩展。
  2. checkout 页面,用户可以输入替代配送说明。
  3. 当用户完成结账时,替代配送说明将被保存到订单的元数据中。

注意事项:

  • 请确保您的扩展与 WooCommerce API 兼容。
  • 在更新订单元数据之前,请务必进行数据验证。

其他信息:

  • 您可以在 StoreOrder 详情页面查看保存的配送说明。
  • Data 存储在订单的元数据中。
  • 如果需要修改保存的 Value,请使用 APIHooks
  • 请定期 check 您的 APIExtensions,以确保其正常运行。
  • 如果遇到问题,请联系 Developers 寻求帮助。
  • Shipping 信息将影响 Shipping 费用。
  • Actions 决定了订单的处理流程。
  • Request 包含了用户提交的数据。
  • Date 记录了订单的创建和更新时间。
  • Save 操作会将数据持久化到数据库。
  • Lock 功能可以防止多个用户同时修改订单。
  • Shop 平台提供各种 购物 体验。
  • Document 提供了详细的使用说明。
  • API 提供了编程接口。
  • Hooks 允许您自定义 WooCommerce 的行为。

## 结论

通过遵循以上步骤,您可以新增和处理新的字段区块,从而在 WooCommerce 结账区块中添加自定义的配送选项。有关完整实现和更多例子,请参考提供的 [教程](https://developer.woocommerce.com/2023/08/07/extending-the-woocommerce-checkout-block-to-add-custom-shipping-options/) 和相应的 [GitHub 仓库](https://github.com/woocommerce/wceu23-shipping-workshop-final/)。