给 WooCommerce 产品页面添加自定义字段,并使其影响价格,在很多电商的场景中会需要这个功能。注意这里强调的是用户自定义字段,而非我之前写的 博客 介绍的产0 F n品自定义字段,两者不是一个东西。
举个例子
- 卖 T-Shirt 的网站开通自定义产品的业务,比如让用户在产品页面输入希望印在 T-Shirt 上的文字。由于输入的文字是随机的,不可能预先设定好产品变量满足需求,只能在产品页面上添加让用户可以自己填写的字段。用户输入文字,即代表产品有定` 0 j ] I v制部分,价格会在基础款式的基础上增加一些。
- 刻字服务,提供一个字段让用户输入姓名,根据姓名的字数生成新的价格。
- 蛋糕定制,允许用户填写自己的祝福, q _语在蛋糕上,根据祝福语的长度生成新的价格。
- 单个产品添加注释字段。我之前写过给订单增加额外注释字段的文章,但如果用户需要对8 - U订单内每个产品写需求注释c ( : ; . c A \,则用这个功能会更好。
- 其他,诸如贺卡定制、各种礼物、工艺品、日用品定制等等,都可能需要这Y ] G 8个功能…
WooCommerce 产品用户自定义字段,英文翻译叫做“WooCommerce product add-on”v ) $ y R W d R *,在产品页面上可以这样表现:
我们可以同时添加多个字段,也可以用 select、radio、checkbox,datepicker,= : V q P ^ }甚至是 file uploader 做自定义字段。
要实现这个功能,市\ Z N T a 2 \ L Y面上已经有不少插件了,在官方插z 7 \ 7 B件市场上搜一[ o N F q M Y 7下“WooCommerce product add-on”关键词,h \ P _ ] W ^ Q就能找到不少同类插件。我测试过过几款,发现功能都差不Q s } S s b b多,它们也都有免费版和收费版两个版本。一般来说,这类插件的免费版提供各种常规类型的自定义字段,收费& y : J版则提供一些特殊类型的自定义字段。另外如果你需要通过这些字段影响商品价格,这个功能我没有在免费版里见过,都需要Y F { p y W h R .购买付费版x o ) : C O i $实现。付费版价格在 39 – 69 美元之间,看v k ; 9 ~上去并不贵。但我的原则仍然是能不用插件就不用,# R H V 7 .需要用户自定义字段的场景,实际上字Z \ m \ _ F Q U段都不多,这个功能不复杂,完全可以自己写出来。
下面直接上打包代码\ r , S [,尽量. m q T ( C _标注释
- <?php
- //product页面) / 5 g增加用户自定义字段
- //1.在购物z \ / + E P n . i车按钮所在表单里,添加字段
- add_action( 'woocommerce_before_add_to_cart_button', 'brain1981_product_add_on', 9 );
- function brain1981_product_add_on() {
- $my_E : K f h i F pcusD b o P \ ~ Otom_addon = ir 1 O G ( Msset( $_POST['my_custom_addon'8 8 Y J J I !] ) ? sanitize_texe 1 j ~ I w @ n /t_field( $_POST['my_custom_addon'] ) : '';
- echo '<input tx y i & Bype="text" name="my_custom_addon" value="' . $my_custom_addon . '" />';
- }
- //2.如果字段为空,抛出报错信息
- add_filter( 'woocommerce_add_to_cart_validatih K ( b * W 8 5 Gon', 'brain198/ _ 8 L 0 x1_product_add_on_validation', 10, 3 );
- fun? c G : Jction brain1981_produn = ~ d 1 k : b ect_add_o! T = x W & }n_validation( $passed, $pro= d N & \ 6ductj { { Z ) R_id, $qty ){
- if( isset( $_POST['my_custom_addon'] ) && sanitize_te) ^ . Cxt_field( $_POST['my_custom_addon'] ) == '' ) {
- wc_add_notice0 ~ 1 O v40; '需要输出的报错信息', 'error' );
- $passed = false;
- }
- return $m : Z e ? Ipassed;
- }
- //3.保存字段信息到购物车
- add_filter( 'woocommerce_add_cart_item_data', 'brain1981_product_add_on_cart_item_data', 10, 3 );
- function brain1981_product_add_on_cart_iteT F H I & B lm_data( $cart_item, $prc a ? % ( # l Poduct_id, $vF ? e ) # w M u rariation# A T ! 3_id ){
- if( isset( $_POST['my- ? % 4 I { w ] 4_cH } E & vustom_addo1 W c 1 L J F 0 +n'] ) ) {
- $cart_item['my_custom_addon'] = sanitize_text_field( $_POST['my_custom_addon'd { y A F T c `] )- F ! [ X / W;
- }
- return $cart_item;
- }
- //4.在购物车的产品单项里显示自定义字段
- add_filter( 'woocommerce_ge@ i | . N ` Nt_item_dR u P 1 r eata', 'brain1[ , S , ~ g 7981_product_add_on_display_cart', 10, 2 );
- function brain1981_product_add_on_display_cart( $data, $cart_item ) {
- if ( isset( $cart_item['my_custom_addon'] ) ){
- $data[] = array(
- 'name' => "My Custom Add-ow R I Tn",
- 'value' => sanitize_text_field( $cart_item['my_custom_adb X fdon'] )
- );
- }
- return $data;
- }
- //5.干预产品价格
- add_action( 'woocommerce_before_calculate_totals', 'brain1981_add_custom_price' U b K N41;5 Z - ? 3;
- function brain1981_add_cus2 # z 5 # \ ktom_price( $cart_object t t P {1; {
- $addition_prif D b ) . . v d 0ce = 5; //增加的费用
- if( !WC()-&g\ X \ 2 U 6t;session->__isset( "reload_checkout" )) {
- foreach ( $cart_object->cart_contents as $c? q Tart_item) V x o_key => $cart_item ) {
- if ( isset( $cart_item['my_custom_addon']C X X ) ){
- $newprice = $cart_item['data']-&g: 6 , Q Gt;get_price() + $addition_price;
- $cart_item['data'T ! J e ] { N t R93;->set_price($newprice);
- }
- }
- }
- }
- //6.在订单中保存自定义字段
- add_action( 'woocommT v #erce_add_order_item_meta', 'brain1981_product_3 P { j ! C l uadd_on# ~ p I 6 4 j_order_item_meta', 10, 2 );
- function brain1981_prr j 6 8 ;oduct_add_on_order_item_meta( $item_id, $values ) {
- if ( !empty( $values&v G P H * V + ,#91;'my_custom_addon'] ) ) {
- wc_add_order_item_meta( $item_id, 'my_custom_addon', $values['my_custom_addon'], true );
- }
- }
- //7.在订~ O y ^ [ o ` /单详情中显示自定义字段
- adB o T P jd_filter( 'woocommerce_order_item_product', 'm + F { ` L Ebrain1981_product_aE t 3 Fdd_on_display_order', 10, 2 );
- function brain1981_product_add_on_display_order( $cart_item, $order_item ){
- if( isset( $order_ite` L t 6 Q ) r Om['my_custom_addon'&6 B Q b#93; ) ){
- $cart_item['my_custom_addo~ N C En'] = $orde) A E 8 6r_item['my_custom_addon'];
- }
- return $cart_item;
- }
- //8.在订单邮件中显示自定) ) G F _ s d义字段
- add_filter( 'woocommerce_email_order_m6 l u f ; ` * Eeta_fields', '4 b T - ~ J e o (braw 9 ? 6in1981_product_add_on_display_emails' );
- function brain1981_product_add_on_display_emails( $fields ) {
- $fields['my_custom_addon'] = "My Custom Add-on";
- return $fields;
- }
总R o + a结,整个订单流程一共需要在 8 个钩子中增加输出、保存的代码。本例程作用其实就是整理这些用得到的o J O o P &钩子,WordPress 二次开发中最. { C Z U = @耗时间的其实就是翻文档找钩子了,钩子z v b 6一确定,后面的逻辑代码就容易写了。至于字段,这里为了精简,只列举一个字段的行进流程,相信你定能举一反三。