添加字段并传递值
本文档描述了开发者如何将一个输入字段插入到结账块中,并将该字段的值传递给 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- 您的数据的价值。
工作原理
setExtensionData通过 props 传递给内部块。- 它更新
wc/store/checkout数据存储中的extensionData键。 - 当向结账端点发送 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 之前和之后的的数据存储:
| 之前 | 之后 |
|---|---|
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():保存订单。
使用方法:
- 确保已安装并激活相应的扩展。
- 在
checkout页面,用户可以输入替代配送说明。 - 当用户完成结账时,替代配送说明将被保存到订单的元数据中。
注意事项:
- 请确保您的扩展与 WooCommerce API 兼容。
- 在更新订单元数据之前,请务必进行数据验证。
其他信息:
- 您可以在
Store的Order详情页面查看保存的配送说明。 Data存储在订单的元数据中。- 如果需要修改保存的
Value,请使用API或Hooks。 - 请定期
check您的API和Extensions,以确保其正常运行。 - 如果遇到问题,请联系
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/)。