您的购物车目前是空的!
小狮网AI学习
通过修改核心文件实现(仅供学习和理解)
以下步骤将直接修改 WooCommerce 的模板文件。请务必在操作前备份你的网站和数据库。
第一步:定位并复制模板文件
WooCommerce 的结账页面字段是通过模板文件生成的。你需要找到并修改这个文件。
- 登录你的网站服务器(通过 FTP 或主机面板的文件管理器)。
- 导航到以下目录:
wp-content/plugins/woocommerce/templates/checkout/ - 找到名为
form-billing.php的文件。这个文件负责生成账单地址区域的所有字段,包括姓名。 - 将
form-billing.php文件复制到你的电脑上,作为备份和编辑用。
第二步:编辑 form-billing.php 文件
用代码编辑器(如 VS Code, Sublime Text 等)打开你复制的 form-billing.php 文件。
- 找到姓氏和名字的代码块:
在文件中搜索 $fields['billing']['billing_first_name'] 和 $fields['billing']['billing_last_name']。你会找到类似下面这样的代码块:
php
<p class="form-row form-row-first validate-required" id="billing_first_name_field">
<label for="billing_first_name" class="">
<?php esc_html_e( 'First name', 'woocommerce' ); ?> <span class="required">*</span>
</label>
<input type="text" class="input-text" name="billing_first_name" id="billing_first_name" autocomplete="given-name" value="<?php echo esc_attr( $checkout->get_value( 'billing_first_name' ) ); ?>" placeholder="<?php esc_attr_e( 'First name', 'woocommerce' ); ?>">
</p>
<p class="form-row form-row-last validate-required" id="billing_last_name_field">
<label for="billing_last_name" class="">
<?php esc_html_e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span>
</label>
<input type="text" class="input-text" name="billing_last_name" id="billing_last_name" autocomplete="family-name" value="<?php echo esc_attr( $checkout->get_value( 'billing_last_name' ) ); ?>" placeholder="<?php esc_attr_e( 'Last name', 'woocommerce' ); ?>">
</p>
删除原有代码并替换为新代码:
将上面找到的两个 <p>...</p> 代码块完全删除,然后将其替换为下面的代码:
php
<?php // 获取已保存的姓名值,如果存在则合并显示 $full_name = ''; $first_name = $checkout->get_value( 'billing_first_name' ); $last_name = $checkout->get_value( 'billing_last_name' ); if ( ! empty( $first_name ) && ! empty( $last_name ) ) { $full_name = $first_name . ' ' . $last_name; } elseif ( ! empty( $first_name ) ) { $full_name = $first_name; } elseif ( ! empty( $last_name ) ) { $full_name = $last_name; } ?> <p class="form-row form-row-wide validate-required" id="billing_full_name_field"> <label for="billing_full_name" class=""> <?php esc_html_e( 'Full Name', 'woocommerce' ); ?> <span class="required">*</span> </label> <input type="text" class="input-text" name="billing_full_name" id="billing_full_name" value="<?php echo esc_attr( $full_name ); ?>" placeholder="<?php esc_attr_e( 'Enter your full name', 'woocommerce' ); ?>"> </p>代码解释:- 我们先用 PHP 逻辑获取了
billing_first_name和billing_last_name的值,并将它们合并成一个$full_name变量。这样,如果用户之前填写过信息,表单会自动显示他们的全名。 - 然后,我们创建了一个新的、宽度为
form-row-wide(整行)的输入框。 - 这个新输入框的
name属性是billing_full_name,我们将在下一步用它来处理数据。
- 我们先用 PHP 逻辑获取了
第三步:处理表单提交的数据
现在,前端的输入框合并好了,但当用户提交表单时,WooCommerce 仍然期望收到 billing_first_name 和 billing_last_name 两个字段。我们需要一个机制,将用户在 billing_full_name 输入框中填写的内容,分割成名和姓,并分别存入对应的数据库字段。
这需要修改另一个核心文件。
- 回到服务器上的 WooCommerce 插件目录:
wp-content/plugins/woocommerce/
导航到 includes/class-wc-checkout.php 文件。这个文件是处理结账流程的核心类。
备份此文件! 这个文件非常重要。
打开 class-wc-checkout.php 并找到 process_checkout() 方法。这个方法非常长。
在 process_checkout() 方法内部,找到处理 $_POST 数据的地方。通常在方法的开头部分,你会看到类似 $posted_data = $this->get_posted_data(); 的代码。
在 $posted_data = $this->get_posted_data();之后,添加以下代码:
php
// Custom code to split full name into first and last name if ( isset( $_POST['billing_full_name'] ) && ! empty( $_POST['billing_full_name'] ) ) { $full_name = sanitize_text_field( $_POST['billing_full_name'] ); // Split the name into parts. This will split on the last space. $name_parts = preg_split( '/\s+(?=\S*+$)/', $full_name ); if ( ! empty( $name_parts ) ) { $first_name = $name_parts[0]; $last_name = isset( $name_parts[1] ) ? $name_parts[1] : ''; // Update the posted data so WooCommerce uses our split values $_POST['billing_first_name'] = $first_name; $_POST['billing_last_name'] = $last_name; // Also update the $posted_data array in case it's used later $posted_data['billing_first_name'] = $first_name; $posted_data['billing_last_name'] = $last_name; } }代码解释:- 我们首先检查
billing_full_name是否存在于提交的数据中。 - 使用正则表达式
preg_split( '/\s+(?=\S*+$)/', $full_name )来分割字符串。这个正则表达式会在最后一个空格处分割,这样可以正确处理中间有空格的名字(例如 “Van der Sar” 会被当作姓)。 - 然后,我们将分割后的第一部分作为
billing_first_name,剩余部分(如果有)作为billing_last_name。 - 最后,我们手动更新了
$_POST全局变量和$posted_data数组,将分割好的名和姓放回去。这样,后续的 WooCommerce 处理流程就会无缝地接收到它所期望的数据格式。
- 我们首先检查
第四步:上传修改后的文件
- 将你修改过的
form-billing.php文件上传回服务器的wp-content/plugins/woocommerce/templates/checkout/目录,覆盖原始文件。 - 将你修改过的
class-wc-checkout.php文件上传回服务器的wp-content/plugins/woocommerce/includes/目录,覆盖原始文件。
完成以上步骤后,刷新你的结账页面,你应该就能看到合并后的 “姓名” 输入框了。提交订单后,你可以在 WordPress 后台的订单详情中检查,姓名是否被正确地分割并保存。
✅ 安全、推荐的实现方法(自定义插件)
为了让你的修改永久生效,我们应该使用 WooCommerce 提供的钩子(Hooks)系统。下面是创建一个简单自定义插件的完整代码。
- 在
wp-content/plugins/目录下,创建一个新文件夹,命名为wc-merge-name-fields。 - 在该文件夹内,创建一个新文件,命名为
wc-merge-name-fields.php。 - 将以下代码完整地复制并粘贴到
wc-merge-name-fields.php文件中:
php
<?php
/*
Plugin Name: WooCommerce Merge Name Fields
Plugin URI: https://yourwebsite.com/
Description: Merges the first and last name fields into a single full name field on the WooCommerce checkout page.
Version: 1.0
Author: Your Name
Author URI: https://yourwebsite.com/
License: GPL2
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Check if WooCommerce is active
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
/**
* Step 1: Remove the default first and last name fields
*/
function wc_remove_default_name_fields( $fields ) {
unset( $fields['billing']['billing_first_name'] );
unset( $fields['billing']['billing_last_name'] );
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'wc_remove_default_name_fields' );
/**
* Step 2: Add the custom full name field
*/
function wc_add_custom_full_name_field( $fields ) {
$fields['billing']['billing_full_name'] = array(
'label' => __( 'Full Name', 'woocommerce' ),
'placeholder' => _x( 'Enter your full name', 'placeholder', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-wide' ),
'clear' => true,
'priority' => 20, // Position it where the original name fields were
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'wc_add_custom_full_name_field' );
/**
* Step 3: Process the custom field data
*/
function wc_process_custom_name_field_data( $order_id, $posted_data, $order ) {
if ( isset( $_POST['billing_full_name'] ) && ! empty( $_POST['billing_full_name'] ) ) {
$full_name = sanitize_text_field( $_POST['billing_full_name'] );
// Split the name into parts (split on the last space)
$name_parts = preg_split( '/\s+(?=\S*+$)/', $full_name );
if ( ! empty( $name_parts ) ) {
$first_name = $name_parts[0];
$last_name = isset( $name_parts[1] ) ? $name_parts[1] : '';
// Update the order meta data
update_post_meta( $order_id, '_billing_first_name', $first_name );
update_post_meta( $order_id, '_billing_last_name', $last_name );
// Also update the user meta if the user is logged in
if ( get_current_user_id() ) {
update_user_meta( get_current_user_id(), 'billing_first_name', $first_name );
update_user_meta( get_current_user_id(), 'billing_last_name', $last_name );
}
}
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'wc_process_custom_name_field_data', 10, 3 );
/**
* Step 4: Display the full name correctly in admin order details
*/
function wc_admin_order_display_full_name( $order ) {
$first_name = get_post_meta( $order->get_id(), '_billing_first_name', true );
$last_name = get_post_meta( $order->get_id(), '_billing_last_name', true );
if ( $first_name || $last_name ) {
echo '<p><strong>' . __( 'Billing Name:', 'woocommerce' ) . '</strong> ' . esc_html( $first_name . ' ' . $last_name ) . '</p>';
}
}
// Remove the default billing name display
remove_action( 'woocommerce_admin_order_data_after_billing_address', 'woocommerce_admin_order_display_billing_address', 10 );
// Add our custom billing name display
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wc_admin_order_display_full_name', 10 );
}
- 保存文件后,登录到你的 WordPress 后台,导航到 “插件” > “已安装插件”,你会看到 “WooCommerce Merge Name Fields” 这个新插件。点击 “启用” 即可。
现在,你的结账页面姓名输入框已经安全地合并了,并且这个修改不会因为 WooCommerce 的升级而丢失。这才是在 WordPress 生态中进行开发的正确方式。
回复 一位 WordPress 评论者 取消回复