-- 创造无限可能

wordpress分类页面自身返回默认文章,查询的文章需要使用setup_postdata($data)方法将查询结果设置成全局,这样使用文章的相关方法才会得到当前文章的属性.

wordpress分类页面自身返回默认文章,查询的文章需要使用setup_postdata($data)方法将查询结果设置成全局,这样使用文章的相关方法才会得到当前文章的属性.

$product_arr = get_posts([
'post_type' => 'product',
'meta_key' => 'name',
'meta_value' => '张三'
]);
get_field('字段名','post_id')//返回字段的值
the_field('字段名','post_id')//输入字段的值
get_field('字段名','post_id')//返回字段的值
the_field('字段名','post_id')//输入字段的值
the_permalink(); //产品链接
woocommerce_get_product_thumbnail() //产品缩略图
the_title() // 产品标题
$product->get_price_html() //产品价格
$product->get_sku() //产品sku
$product->get_type() // 产品类型
wc_get_product_category_list() // 获取产品分类
wc_get_product_tag_list() //获取产品标签

场景

wordpress默认只有一种文章类型,有时候需要添加自定义的文章类型:比如演员、电影、公告等

相关钩子

  • register_post_type

    代码演示

    1、添加以下代码到主体模板文件夹目录function.php中
    /**
    * @return void 公告
    */
    function my_custom_post_announcement()
    {
      $labels = array(
              'name' => _x('公告', '公告'),
              'singular_name' => _x('announcement', 'announcement'),
              'add_new' => _x('add', 'add'),
              'add_new_item' => __('add'),
              'edit_item' => __('edit'),
              'new_item' => __('add'),
              'all_items' => __('All items'),
              'view_item' => __('View'),
              'search_items' => __('Search'),
              'not_found' => __('not Found'),
              'not_found_in_trash' => __('not found in trash'),
              'parent_item_colon' => '',
              'menu_name' => '公告'
      );
      $args = array(
              'labels' => $labels,
              'description' => '',
              'public' => true,
              'menu_position' => 5,
              'supports' => array('title', 'editor', 'thumbnail'),
              'has_archive' => true
      );
      register_post_type('announcement', $args);
    }
    

场景

wordpress默认只有一种文章类型,有时候需要添加自定义的文章类型:比如演员、电影、公告等

相关钩子

  • register_post_type

    代码演示

    /**
    * @return void 公告
    */
    function my_custom_post_announcement()
    {
      $labels = array(
              'name' => _x('公告', '公告'),
              'singular_name' => _x('announcement', 'announcement'),
              'add_new' => _x('add', 'add'),
              'add_new_item' => __('add'),
              'edit_item' => __('edit'),
              'new_item' => __('add'),
              'all_items' => __('All items'),
              'view_item' => __('View'),
              'search_items' => __('Search'),
              'not_found' => __('not Found'),
              'not_found_in_trash' => __('not found in trash'),
              'parent_item_colon' => '',
              'menu_name' => '公告'
      );
      $args = array(
              'labels' => $labels,
              'description' => '',
              'public' => true,
              'menu_position' => 5,
              'supports' => array('title', 'editor', 'thumbnail'),
              'has_archive' => true
      );
      register_post_type('announcement', $args);
    }
    

谷歌地图提供了接口来计算两地的行驶距离

1.获取地址坐标


function get_coordinates($city, $street, $province)
{
    $address = urlencode($city.','.$street.','.$province);
    $url = "http://maps.google.com/maps/api/geocode/json?address=$address&sensor=false&region=Poland";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $response = curl_exec($ch);
    curl_close($ch);
    $response_a = json_decode($response);
    $return = array('lat' => $response_a->results[0]->geometry->location->lat, 'long' => $long = $response_a->results[0]->geometry->location->lng);

    return $return;
}

2.基于坐标获取两地的行驶距离

function GetDrivingDistance($lat1, $lat2, $long1, $long2)
{
    $url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$lat1.",".$long1."&destinations=".$lat2.",".$long2."&mode=driving&language=pl-PL";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $response = curl_exec($ch);
    curl_close($ch);
    $response_a = json_decode($response, true);
    $dist = $response_a['rows'][0]['elements'][0]['distance']['text'];
    $time = $response_a['rows'][0]['elements'][0]['duration']['text'];

    return array('distance' => $dist, 'time' => $time);
}

3.完整示例

$coordinates1 = get_coordinates('Tychy', 'Jana Pawła II', 'Śląskie');
$coordinates2 = get_coordinates('Lędziny', 'Lędzińska', 'Śląskie');
if ( !$coordinates1 || !$coordinates2 )
{
    echo 'Bad address.';
}
else
{
    $dist = GetDrivingDistance($coordinates1['lat'], $coordinates2['lat'], $coordinates1['long'], $coordinates2['long']);
    echo 'Distance: <b>'.$dist['distance'].'</b><br>Travel time duration: <b>'.$dist['time'].'</b>';
}

参考: https://developers.google.com/maps/documentation/distancematrix/#DistanceMatrixRequests

谷歌地图提供了接口来计算两地的行驶距离

1.获取地址坐标


function get_coordinates($city, $street, $province)
{
    $address = urlencode($city.','.$street.','.$province);
    $url = "http://maps.google.com/maps/api/geocode/json?address=$address&sensor=false&region=Poland";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $response = curl_exec($ch);
    curl_close($ch);
    $response_a = json_decode($response);
    $return = array('lat' => $response_a->results[0]->geometry->location->lat, 'long' => $long = $response_a->results[0]->geometry->location->lng);

    return $return;
}

2.基于坐标计算两地的直线距离

function getDistanceBetweenPoints($lat1, $lon1, $lat2, $lon2) {
    $theta = $lon1 - $lon2;
    $miles = (sin(deg2rad($lat1)) * sin(deg2rad($lat2))) + (cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)));
    $miles = acos($miles);
    $miles = rad2deg($miles);
    $miles = $miles * 60 * 1.1515;
    $kilometers = $miles * 1.609344;
    return $kilometers;
}

3.按公里打印距离:

function get_distance($lat1, $lat2, $long1, $long2)
{
    /* These are two points in New York City */
    $point1 = array('lat' => $lat1, 'long' => $long1);
    $point2 = array('lat' => $lat2, 'long' => $long2);

    $distance = getDistanceBetweenPoints($point1['lat'], $point1['long'], $point2['lat'], $point2['long']);
    return $distance;
}

4.完整示例

$coordinates1 = get_coordinates('Katowice', 'Korfantego', 'Katowicki');
$coordinates2 = get_coordinates('Tychy', 'Jana Pawła II', 'Tyski');

echo 'Distance: <b>'.round(get_distance($coordinates1['lat'], $coordinates2['lat'], $coordinates1['long'], $coordinates2['long']), 1).'</b> km';

用途

用于显示特定类别中的产品

语法

//显示顶级类别
[product_categories parent="0"]
//类别内的产品:
[product_category category="category-slug-here"]

用途

为WordPress后台 Settings(设置) 顶级栏目创建一个子栏目

语法

add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
//$page_title:显示名称
//$menu_title:菜单名称
//$capability:权限
//$menu_slug:标识
//$function 回调函数

例子

/** 第1步:定义添加菜单选项的函数 */
function my_plugin_menu() {
     add_options_page( 
        'My Plugin Options', 
        'My Plugin', 
        'manage_options', 
        'my-unique-identifier', 
        'my_plugin_options' );
}

/** 第2步:将函数注册到钩子中 */
add_action( 'admin_menu', 'my_plugin_menu' );

/** 第3步:定义选项被点击时打开的页面 */
//current_user_can()检测当前的用户是否有特定的权限
//wp_die()终断WordPress执行并显示错误HTML信息。
function my_plugin_options() {
     if ( !current_user_can( 'manage_options' ) )  {
          wp_die( 'You do not have sufficient permissions to access this page.' );
     }
     echo '<div class=wrap>Here is where the form would go if I actually had options.</div>';
}

其他顶级栏目创建子菜单的函数

//Dashboard
add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Posts
add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Media
add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Links
add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Pages
add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Comments
add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Appearance
add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Plugins
add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Users
add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Tools
add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function);

参考网址

https://www.xuxiaoke.com/wpfunc/73.html

用途

为WordPress后台 Settings(设置) 顶级栏目创建一个子栏目

语法

add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
//$page_title:显示名称
//$menu_title:菜单名称
//$capability:权限
//$menu_slug:标识
//$function 回调函数

例子

/** 第1步:定义添加菜单选项的函数 */
function my_plugin_menu() {
     add_options_page( 
        'My Plugin Options', 
        'My Plugin', 
        'manage_options', 
        'my-unique-identifier', 
        'my_plugin_options' );
}

/** 第2步:将函数注册到钩子中 */
add_action( 'admin_menu', 'my_plugin_menu' );

/** 第3步:定义选项被点击时打开的页面 */
//current_user_can()检测当前的用户是否有特定的权限
//wp_die()终断WordPress执行并显示错误HTML信息。
function my_plugin_options() {
     if ( !current_user_can( 'manage_options' ) )  {
          wp_die( 'You do not have sufficient permissions to access this page.' );
     }
     echo '<div class=wrap>Here is where the form would go if I actually had options.</div>';
}

其他顶级栏目创建子菜单的函数

//Dashboard
add_dashboard_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Posts
add_posts_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Media
add_media_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Links
add_links_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Pages
add_pages_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Comments
add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Appearance
add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Plugins
add_plugins_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Users
add_users_page( $page_title, $menu_title, $capability, $menu_slug, $function);

//Tools
add_management_page( $page_title, $menu_title, $capability, $menu_slug, $function);

不要相信用户的输入

输出用户的输入信息时候,需要对数据进行转义输入,已保证系统的安全

相关函数

  • esc_html()
  • esc_attr ()
  • esc_url()
  • esc_js()
  • esc_textarea()

用法

  • esc_attr
    删除不正确的utf8字符,
    将< (小于)、> (大于)、& (与)、” (双引号)和’(单引号)字符转换为HTML实体,
    永远不会对实体进行双重编码。

    请勿使用esc_attr()来转义src、href属性的数据– 而是使用esc_url(),
    也不要将其用于value属性,因为它可能导致HTML实体丢失和数据库中存储的值不正确,请改用esc_textarea()。这是因为esc_attr()不会对实体进行双重编码。

  • esc_html
    准备在HTML中使用的文本。与esc_attr()函数的唯一区别在于,它有一个连接到函数输出的过滤器钩子- esc_html而不是attribute_escape。

  • esc_url
    用%20替换空格,
    删除网址中不允许使用的符号,例如反斜杠,
    如果URL协议是mailto:,从使用私有函数_deep_replace()排除符号%0d、%0a、%0D、%0A等字符串,这意味着字符串%0%0%0AAA将被转换为空字符串,而不是str_replace()将返回的%0%0AA ,
    将替换;//为://,防止万一发生错误的情况,
    如果该网址不包含方案,除非该URL 是一个以/,#或?或php文件开头的相对链接,否则将添加前缀http://。
    如果第三个函数参数$_context等于display(默认情况下),则&符号将替换为&,并将单引号替换为英文的’,
    用%5B和%5D编码方括号。
    检查是否允许使用URL协议,如果不允许-返回空字符串,
    在最后,将clean_url滤镜挂钩应用于结果。

  • esc_js
    删除不正确的utf8字符,
    转义单引号’,
    将< (小于)、> (大于)、& (与)、” (双引号)字符转换为HTML实体< > & “ ,
    在行末添加\n。
    JavaScript中的文本字符串必须始终用单引号引起来!

  • esc_textarea()
    将< (小于)、> (大于)、& (与)、” (双引号)和’(单引号)字符转换为HTML实体

相关钩子

  • woocommerce_payment_gateways_setting_columns
  • woocommercepayment_gateways_setting_column{COLUMN ID}

用法

add_filter( 'woocommerce_payment_gateways_setting_columns', 'rudr_add_payment_method_column' );
function rudr_add_payment_method_column( $default_columns ) {
    $default_columns = array_slice( $default_columns, 0, 2 ) + array( 'id' => 'ID' ) + array_slice( $default_columns, 2, 3 );
    return $default_columns;
}
// woocommerce_payment_gateways_setting_column_{COLUMN ID}
add_action( 'woocommerce_payment_gateways_setting_column_id', 'rudr_populate_gateway_column' );
function rudr_populate_gateway_column( $gateway ) {
    echo '<td style="width:10%">' . $gateway->id . '</td>';
}

相关钩子

  • woocommerce_gateway_title
  • woocommerce_gateway_description

用法

add_filter( 'woocommerce_gateway_title', 'change_payment_gateway_title', 25, 2 );
function change_payment_gateway_title( $title, $gateway_id ){

    if( 'cod' === $gateway_id ) {
        $title = 'By Cash or Credit Card on delivery';
    }
    return $title;
}
add_filter( 'woocommerce_gateway_description', 'change_payment_gateway_description', 25, 2 );
function change_payment_gateway_description( $description, $gateway_id ) {
    if( 'cod' === $gateway_id ) {
        // you can use HTML tags here
        $description = 'Pay with cash upon delivery. Easy-breezy ;)';
    }
    return $description;
}

通常,每页显示的文章数量默认为仪表板设置 > 阅读 > 博客页面至多显示 的值,您可能希望常规的文章采用这个数量,但是自定义文章类型不要采用。要更改自定义文章类型的存档页面中显示的文章数量,您可以使用带有一些传入参数的pre_get_posts操作来实现。

add_action( 'pre_get_posts', 'tl_project_page' );
// 在项目存档页面显示所有项目
function tl_project_page( $query ) {
    if ( !is_admin() && $query->is_main_query() && is_post_type_archive( 'project' ) ) {
            $query->set( 'posts_per_page', '-1' ); // 要显示多少个,就修改 -1 为具体的数字即可
    }
}

get_terms:获取分类下的元素列表,可以获取文章分类,自定义分类,产品分类,文章标签等信息

场景:客户在购买商品时,有时候需要用户添加一些自定义信息,比如:备注、颜色等。

实现:我们以添加一个备注属性作为案例

  1. 添加产品属性
    产品->属性->添加属性(属性slug:remark)
  2. 在产品详情页面添加输入框

    function add_name_remark() {
         echo ' <input type="text" name="remark" value="" />';
    }
    add_action( 'woocommerce_before_add_to_cart_button', 'add_name_remark' );
    
  3. 保存自定义属性

    add_action( 'woocommerce_add_cart_item_data', 'save_in_cart_my_custom_product_field', 10, 2 );
    function save_in_cart_my_custom_product_field( $cart_item_data, $product_id ) {
     if( isset( $_POST['remark] ) ) {
     $cart_item_data[ 'remark' ] = $_POST['remark'];
     // When add to cart action make an unique line item
     $cart_item_data['unique_key'] = md5( microtime().rand() );
     WC()->session->set( 'custom_data', $_POST['remark'] );
     }
     return $cart_item_data;
    }
    
  4. 在购物车和结账页面显示自定义属性

    // 显示自定义数据
    add_filter( 'woocommerce_get_item_data', 'render_custom_field_meta_on_cart_and_checkout', 10, 2 );
    function render_custom_field_meta_on_cart_and_checkout( $cart_data, $cart_item ) {
     $custom_items = array();
     if( !empty( $cart_data ) )
         $custom_items = $cart_data;
     if(isset($cart_item['remark']) && $custom_field_value = $cart_item['remark'] )
     $custom_items[] = array(
         'name' => __( 'Reamrk', 'woocommerce' ),
         'value' => $custom_field_value,
         'display' => $custom_field_value,
     );
     return $custom_items;
    }
    
  5. 保存自定义属性到购物车

    add_action( 'woocommerce_add_order_item_meta', 'tshirt_order_meta_handler', 10, 3 );
    function tshirt_order_meta_handler( $item_id, $cart_item, $cart_item_key ) {
     $custom_field_value = $cart_item['remark'];
     if( ! empty($custom_field_value) )
         wc_update_order_item_meta( $item_id, 'remark', $custom_field_value );
    }
    

场景:客户在购买商品时,有时候需要用户添加一些自定义信息,比如:备注、颜色等。

实现:我们以添加一个备注属性作为案例

  1. 添加产品属性
    产品->属性->添加属性(属性slug:remark)
  2. 在产品详情页面添加输入框

    function add_name_remark() {
         echo ' <input type="text" name="remark" value="" />';
    }
    add_action( 'woocommerce_before_add_to_cart_button', 'add_name_remark' );
    
  3. 保存自定义属性

    add_action( 'woocommerce_add_cart_item_data', 'save_in_cart_my_custom_product_field', 10, 2 );
    function save_in_cart_my_custom_product_field( $cart_item_data, $product_id ) {
     if( isset( $_POST['remark] ) ) {
     $cart_item_data[ 'remark' ] = $_POST['remark'];
     // When add to cart action make an unique line item
     $cart_item_data['unique_key'] = md5( microtime().rand() );
     WC()->session->set( 'custom_data', $_POST['remark'] );
     }
     return $cart_item_data;
    }
    
  4. 在购物车和结账页面显示自定义属性

    // 显示自定义数据
    add_filter( 'woocommerce_get_item_data', 'render_custom_field_meta_on_cart_and_checkout', 10, 2 );
    function render_custom_field_meta_on_cart_and_checkout( $cart_data, $cart_item ) {
     $custom_items = array();
     if( !empty( $cart_data ) )
         $custom_items = $cart_data;
     if(isset($cart_item['remark']) && $custom_field_value = $cart_item['remark'] )
     $custom_items[] = array(
         'name' => __( 'Reamrk', 'woocommerce' ),
         'value' => $custom_field_value,
         'display' => $custom_field_value,
     );
     return $custom_items;
    }
    
  5. 保存自定义属性到购物车

    add_action( 'woocommerce_add_order_item_meta', 'tshirt_order_meta_handler', 10, 3 );
    function tshirt_order_meta_handler( $item_id, $cart_item, $cart_item_key ) {
     $custom_field_value = $cart_item['remark'];
     if( ! empty($custom_field_value) )
         wc_update_order_item_meta( $item_id, 'remark', $custom_field_value );
    }
    

有时候我们需要根据产品id获取产品信息

相关函数

wc_get_product()

案例

$product = wc_get_product($id);
$post_thumbnail_id = $product->get_image_id(); //获取产品缩略图id
$images = wp_get_attachment_image_src($post_thumbnail_id,'full');//获取缩略图地址
$product->get_name();//获取产品名称
$product->get_price();//获取产品价格

WooCommerce定义了许多钩子,我们可以利用这些钩子完成一些自定义的功能

  1. woocommerce_default_address_fields:下单地址过滤器钩子
  2. woocommerce_checkout_fields :checkout所有信息过滤器钩子
  3. woocommerce_before_checkout_billing_form :
  4. woocommerce_after_checkout_billing_form
  5. woocommerce_before_checkout_registration_form
  6. woocommerce_after_checkout_registration_form
  7. woocommerce_before_checkout_shipping_form
  8. woocommerce_after_checkout_shipping_form
  9. woocommerce_before_order_notes
  10. woocommerce_after_order_notes

用途

  1. 禁用某个地址字段
     add_filter( 'woocommerce_default_address_fields' , 'disable_address_fields_validation' );
     function disable_address_fields_validation( $address_fields_array ) {
         unset( $address_fields_array['state']['validate']);
         unset( $address_fields_array['postcode']['validate']);
         unset( $address_fields_array['first_name']['validate']);
         unset( $address_fields_array['company']['validate']);
         unset( $address_fields_array['country']['validate']);
         unset( $address_fields_array['city']['validate']);
         unset( $address_fields_array['address_1']['validate']);
         unset( $address_fields_array['address_2']['validate']);
         return $address_fields_array;
     }
    
  2. 禁用某个字段
     add_filter( 'woocommerce_checkout_fields ' , 'disable_checkout_fields_validation' );
     function disable_checkout_fields_validation( $woo_checkout_fields_array  ) {
         unset( $woo_checkout_fields_array['billing']['billing_phone']['validate'] );
         unset( $woo_checkout_fields_array['billing']['billing_company'] ); // remove company field
         unset( $woo_checkout_fields_array['billing']['billing_country'] );
         unset( $woo_checkout_fields_array['billing']['billing_address_1'] );
         unset( $woo_checkout_fields_array['billing']['billing_address_2'] );
         unset( $woo_checkout_fields_array['billing']['billing_city'] );
         unset( $woo_checkout_fields_array['billing']['billing_state'] ); // remove state field
         unset( $woo_checkout_fields_array['billing']['billing_postcode'] );
         return $woo_checkout_fields_array;
     }
    
  3. 设置某个字段必填/非必填
    add_filter( 'woocommerce_checkout_fields' , 'misha_not_required_fields', 9999 );
    function misha_not_required_fields( $checkout_field ) {
     // 将字段设置为非必填
     unset( $checkout_field['billing']['billing_last_name']['required'] ); // 这就是重点
     unset( $checkout_field['billing']['billing_phone']['required'] );
     // 将字段设置为必填
     // $checkout_field['billing']['billing_company']['required'] = true;
     return $checkout_field;
    }
    
  4. 更改标签名和占位符
    add_filter( 'woocommerce_checkout_fields' , 'update_labels_placeholders', 9999 );
    function update_labels_placeholders( $checkout_field ) {
     // first name can be changed with woocommerce_default_address_fields as well
     $checkout_field['billing']['billing_first_name']['label'] = 'new label';
     $checkout_field['order']['order_comments']['placeholder'] = 'new placeholder';
     return $checkout_field;
    }
    

wordpress初始只定义了文章分类,但如果需要自定义分类改怎么办呢?不用担心,wordpress官方已经给我们准备好了

相关钩子函数

register_taxonomy( string $taxonomy, array|string $object_type, array|string $args = array() ),注册分类法

案例

给文章类型为book的文章添加两个分类“genre”,‘“writer”

/**
 * Create two taxonomies, genres and writers for the post type "book".
 *
 * @see register_post_type() for registering custom post types.
 */
function wpdocs_create_book_taxonomies() {
    // Add new taxonomy, make it hierarchical (like categories)
    $labels = array(
        'name'              => _x( 'Genres', 'taxonomy general name', 'textdomain' ),
        'singular_name'     => _x( 'Genre', 'taxonomy singular name', 'textdomain' ),
        'search_items'      => __( 'Search Genres', 'textdomain' ),
        'all_items'         => __( 'All Genres', 'textdomain' ),
        'parent_item'       => __( 'Parent Genre', 'textdomain' ),
        'parent_item_colon' => __( 'Parent Genre:', 'textdomain' ),
        'edit_item'         => __( 'Edit Genre', 'textdomain' ),
        'update_item'       => __( 'Update Genre', 'textdomain' ),
        'add_new_item'      => __( 'Add New Genre', 'textdomain' ),
        'new_item_name'     => __( 'New Genre Name', 'textdomain' ),
        'menu_name'         => __( 'Genre', 'textdomain' ),
    );

    $args = array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => 'genre' ),
    );

    register_taxonomy( 'genre', array( 'book' ), $args );

    unset( $args );
    unset( $labels );

    // Add new taxonomy, NOT hierarchical (like tags)
    $labels = array(
        'name'                       => _x( 'Writers', 'taxonomy general name', 'textdomain' ),
        'singular_name'              => _x( 'Writer', 'taxonomy singular name', 'textdomain' ),
        'search_items'               => __( 'Search Writers', 'textdomain' ),
        'popular_items'              => __( 'Popular Writers', 'textdomain' ),
        'all_items'                  => __( 'All Writers', 'textdomain' ),
        'parent_item'                => null,
        'parent_item_colon'          => null,
        'edit_item'                  => __( 'Edit Writer', 'textdomain' ),
        'update_item'                => __( 'Update Writer', 'textdomain' ),
        'add_new_item'               => __( 'Add New Writer', 'textdomain' ),
        'new_item_name'              => __( 'New Writer Name', 'textdomain' ),
        'separate_items_with_commas' => __( 'Separate writers with commas', 'textdomain' ),
        'add_or_remove_items'        => __( 'Add or remove writers', 'textdomain' ),
        'choose_from_most_used'      => __( 'Choose from the most used writers', 'textdomain' ),
        'not_found'                  => __( 'No writers found.', 'textdomain' ),
        'menu_name'                  => __( 'Writers', 'textdomain' ),
    );

    $args = array(
        'hierarchical'          => false,
        'labels'                => $labels,
        'show_ui'               => true,
        'show_admin_column'     => true,
        'update_count_callback' => '_update_post_term_count',
        'query_var'             => true,
        'rewrite'               => array( 'slug' => 'writer' ),
    );

    register_taxonomy( 'writer', 'book', $args );
}
// hook into the init action and call create_book_taxonomies when it fires
add_action( 'init', 'wpdocs_create_book_taxonomies', 0 );

相关函数

1.add_menu_page:添加顶级菜单

add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );   
//$page_title (字符串) (必须) 当选择菜单时,该文本将被显示在网页的标题中。
//$menu_title (字符串) (必须) 在菜单上显示的名称文本
//capability  (字符串) (必须) 用户权限,定义了具有哪些权限的用户会看到这个子菜单
//menu_slug  (字符串) (必须) 这个菜单的名称是指这个菜单(应该是菜单的唯一)。在3.0版本之前,这被称为文件(或处理)参数。如果函数的参数被省略了,这menu_slug应该是PHP文件处理菜单页面内容的显示。
//function  (字符串) (可选) 显示菜单页的页面内容的功能。
/*
默 认值: None. 从技术上讲,函数的参数是可选的,但如果它没有提供,那么WordPress的假设包括PHP文件将生成的管理界面,无需调用一个函数。大多数插件作者选 择把页面生成代码放在主插件文件中的函数中。如果在函数的参数指定,可以使用的menu_slug参数任意字符串。这允许使用的页面,如 ?page=my_super_plugin_page 而不是 ?page=my-super-plugin/admin-options.php.
该函数必须在两种方法中引用:
如果该函数是一个类的成员,它应该被引用为 array( $this, 'function_name' )
在所有其他情况下,使用函数名本身就足够了
*/
//icon_url (字符串) (可选) 该菜单的左侧菜单。
//position  (整 数) (可选) 菜单显示的位置,
/*这个菜单应该出现在那个菜单里面。默认情况下,如果省略此参数,则菜单将出现在菜单结构的底部。数字越高,菜单的位置越低。警告:如果两 个菜单项使用相同的位置属性,其中的项目可能被覆盖,所以只有一项显示!使用十进制来代替整型值可以减少冲突的风险,例如 63.3 而不是 63 (Note: Use quotes in code, IE ‘63.3’).常用位置,4、6、59、99、100。 
*/

position 一些默认值

 2 Dashboard
 4 Separator
 5 Posts
 10 Media
 15 Links
 20 Pages
 25 Comments
 59 Separator
 60 Appearance
 65 Plugins
 70 Users
 75 Tools
 80 Settings
 99 Separator

案例

function register_bwp_menu_page(){   
    add_menu_page( 'title标题', '菜单标题', 'administrator', 'bwp_slug','bwp_menu_page_function','',100);   
}   

function bwp_menu_page_function(){   
    echo '<h1>这是顶级菜单设置页面</h1>';   
}   
add_action('admin_menu', 'register_bwp_menu_page');

相关网址

https://developer.wordpress.org/reference/functions/add_menu_page/

在开发wordpress过程中,有些数据需要异步请求后台。而wordpress已经提供了一系列接口和钩子供我们使用,以便我们开发接口功能。

相关钩子和函数

用法

1、定义接口钩子

function mini_cart()
{
    // 写自己的业务逻辑
    $data = [];
    return $data;
    wp_die();//必须加上结束函数
}
add_action('wp_ajax_mini_cart', 'mini_cart');
add_action('wp_ajax_nopriv_mini_cart', 'mini_cart');

2、前端请求

var ajax_data = {
    action: "mini_cart",
}
jQuery.ajax({
    url:"<?php echo admin_url('admin-ajax.php')?>",// php输出固定的请求地址
    data:ajax_data,
    success:function(data){
        //处理逻辑
    }
})

在开发wordpress过程中,有些数据需要异步请求后台。而wordpress已经提供了一系列接口和钩子供我们使用,以便我们开发接口功能。

相关钩子和函数

用法

1、定义接口钩子

function mini_cart()
{
    // 写自己的业务逻辑
    $data = [];
    return $data;
    wp_die();//必须加上结束函数
}
add_action('wp_ajax_mini_cart', 'mini_cart');
add_action('wp_ajax_nopriv_mini_cart', 'mini_cart');

2、前端请求

var ajax_data = {
    action: "mini_cart",
}
jQuery.ajax({
    url:"<?php echo admin_url('admin-ajax.php')?>",// php输出固定的请求地址
    data:ajax_data,
    success:function(data){
        //处理逻辑
    }
})

有时候我们需要自定义购物车的信息,这时就需要实现清楚购物车的相关函数,以便我们操作

  1. WC()->cart->get_cart():获取购物车信息
  2. woocommerce_cart_item_product:购物车产品过滤钩子
  3. WC()->cart->is_empty()判断购物车是否为空

获取购物车信息案例

foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
    // 产品信息
    $_product = apply_filters('woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key);
    // 产品id
    $product_id = apply_filters('woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key);
    // $_product->exists():产品是否存在
    if ($_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters('woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key)) {
        $product_name = apply_filters('woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key);
        $thumbnail = apply_filters('woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key);
        $product_price = apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key);
        $product_permalink = apply_filters('woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink($cart_item) : '', $cart_item, $cart_item_key);
        wp_kses_post($product_name);
        $_product->get_sku();
    }
$cart_item['quantity']; // 购物车商品数量

相关函数

WC_Order:根据id获取订单
wc_get_order:

基础用法

  1. 访问普通数据
    $order_id = 1;
    $order = new WC_Order( $order_id );
    $orderid  = $order->get_id(); // 获取订单 ID
    $parent_id = $order->get_parent_id(); // 获取父级订单 ID
    $user_id   = $order->get_user_id(); // 获取用户 ID
    $user      = $order->get_user(); // 获取 WP_User 对象
    // 获取订单状态
    $order_status  = $order->get_status(); // 获取订单状态
    // Get Order Dates
    $date_created  = $order->get_date_created(); // 获取创建日期
    $date_modified = $order->get_date_modified(); // 获取修改日期
    $date_completed = $order->get_date_completed(); // 获取订单完成日期
    $date_paid = $order->get_date_paid(); // 获取订单付款日期
    //获取订单账单详情
    $billing_first_name = $order->get_billing_first_name();
    $billing_last_name = $order->get_billing_last_name();
    $billing_company = $order->get_billing_company();
    $billing_address1 = $order->get_billing_address_1();
    $billing_address2 = $order->get_billing_address_2();
    $billing_city = $order->get_billing_city();
    $billing_state = $order->get_billing_state();
    $billing_postcode = $order->get_billing_postcode();
    $billing_country = $order->get_billing_country();
    $billing_email = $order->get_billing_email();
    $billing_phone = $order->get_billing_phone();
    $billing_formatted_name = $order->get_formatted_billing_full_name();
    $billing_formatted_address = $order->get_formatted_billing_address();
    //获取订单物流详情
    $shipping_first_name = $order->get_shipping_first_name();
    $shipping_last_name = $order->get_shipping_last_name();
    $shipping_company = $order->get_shipping_company();
    $shipping_address1 = $order->get_shipping_address_1();
    $shipping_address2 = $order->get_shipping_address_2();
    $shipping_city = $order->get_shipping_city();
    $shipping_state = $order->get_shipping_state();
    $shipping_postcode = $order->get_shipping_postcode();
    $shipping_country = $order->get_shipping_country();
    $shipping_formatted_name = $order->get_formatted_shipping_full_name();
    $shipping_formatted_address = $order->get_formatted_shipping_address();
    //获取订单付款详情
    $currency      = $order->get_currency(); // 获取所用的货币 
    $payment_title = $order->get_payment_method_title(); // 获取付款方式名称
    $payment_method = $order->get_payment_method(); // 获取付款方式 ID
    $fees = $order->get_fees(); // 获取订单手续费
    $subtotal = $order->get_subtotal(); // 获取订单费用小计
    $total_tax = $order->get_total_tax(); // 获取订单总税费
    $total = $order->get_total(); // 获取订单总费用
    
  2. 访问一些有权限的数据
    $order_id = 1;
    $order = wc_get_order( $order_id );
    $order_data = $order->get_data();
    
  3. 如果订单有多个项目
    foreach ( $order->get_items() as $item_id => $item ) {
    $product = $item->get_product();
    $product_id = $item->get_product_id();
    $variation_id = $item->get_variation_id();
    $name = $item->get_name();
    $quantity = $item->get_quantity();
    $subtotal = $item->get_subtotal();
    $total = $item->get_total();
    $tax = $item->get_subtotal_tax();
    $all_meta = $item->get_meta_data();
    $single_meta = $item->get_meta( '_meta_key', true );
    $type = $item->get_type();
    // 等等...
    }
    

在WooCommerce商店上为客户提供优惠券是提供奖励或折扣的好方法。默认系统会开启优惠券功能,在购物车和结账界面都会显示优惠券字段,给用户输入

开启关闭方法有三种

  1. 完全禁用优惠券代码。
    WooCommerce->设置->常规,取消勾选“启用优惠券代码的使用”复选框,即可完全禁用购物车和结帐页面上的优惠券代码字段

  2. 只希望在购物车页面上隐藏优惠券代码字段,但在结帐页面上显示优惠券功能

     // 隐藏购物车页面上的优惠券代码字段
     function disable_coupon_on_cart( $enabled ) {
         if ( is_cart() ) {
             $enabled = false;
         }
         return $enabled;
     }
     add_filter( 'woocommerce_coupons_enabled', 'disable_coupon_on_cart' );
    
  3. 只希望在结帐页面上隐藏优惠券功能,但显示在购物车页面上

    // 隐藏结账页面上优惠券代码字段
    function disable_coupon_on_checkout( $enabled ) {
     if ( is_checkout() ) {
         $enabled = false;
     }
     return $enabled;
    }
    add_filter( 'woocommerce_coupons_enabled', 'disable_coupon_on_checkout' );
    

主题开发主要文件

  • 404.php – 当找不到被访问的页面时使用该页面展示,也就是我们所谓的错误页面
  • archive.php – 文档默认归档页面,用于显示文章列表
  • comments.php – 评论模板文件,用户显示评论框和评论列表
  • footer.php WordPress全局页脚文件,是一个公共文件,比如你可以在这里放一下需要全局引入的js文件、jq等。(一般百度统计代码什么的都是放在这儿)
  • functions.php – 主题核心函数文件,用于实现各种功能,你在这里添加的php函数,可以在你整个模板中直接调用
  • header.php – 主题公用头部文件,通俗点就是页眉
  • image.php – 主题图片展示文件,用于显示图片
  • index.php – 默认首页文件,系统默认文件,当找不到其他页面文件时默认也使用该文件展示【必须有】
  • page.php – 默认页面文件,在WordPress中有基础的两种文章类型,一个是post、一个是page,而这个文件就是page类型展示详情的文件
  • page-{id}.php – 如果页面ID是6,WordPress将会查找page-6.php
  • readme.txt – 一般不用,用于说明主题
  • screenshot.png – 主题封面图片,后台主题列表显示的封面
  • search.php – 默认搜索结果展示页面
  • sidebar.php – 默认侧边栏文件
  • single.php – 默认文章内容页展示页面
  • single-{post_type}.php – 如果文章类型是videos(即视频),WordPress就会去查找single-videos.php(WordPress 3.0及以上版本支持)
  • style.css – 默认文章样式表文件,包含主题基本信息
  • author-{nicename}.php – 如果作者的昵称为rami,WordPress将会查找author-rami.php(WordPress 3.0及以上版本支持)
  • author-{id}.php – 如果作者ID为6,WordPress将会查找author-6.php(WordPress 3.0及以上版本支持)
  • author.php:作者详情页页面,你在WordPress站点中点击一个文章作者即可跳到此页面,又可被称为个人主页
  • category.php:分类目录页面,你在WordPress下建立的分类,都会跳转到这个页面,可以称之为分类详情页、分类列表页
  • category-{id}.php -如果分类ID为6,WordPress将会查找category-6.php
  • category-{slug}.php – 如果分类的缩略名为news,WordPress将会查找category-news.php(WordPress 2.9及以上版本支持)
  • archive-{post_type}.php—如果你的主题有自定义文章类型,比如按照官方网站教程,注册了一个名为book的文章类型,那么它的归档页面模板就是category-book.php,如果没有这个文件,它是不会使用其它文件来代替的,将会直奔404
  • taxonomy-{taxonomy_slug}.php-这是自定义分类法的分类页,比如上面你注册了一个book的文章类型,然后你注册一个分类法author,它的别名是authors,以便让文章按作者分类。那么这个作者分类页的模板文件就是taxonomy-authors.php
  • xxx.php(文件名随便),自定义页面模板 – 在WordPress后台创建页面的时候,右侧边栏可以选择页面的自定义模板
  • page-{slug}.php – 如果页面的缩略名是news,WordPress将会查找 page-news.php(WordPress 2.9及以上版本支持)
  • sytle.css:必须有,主题样式
  • tag-{slug}.php – 如果标签缩略名为sometag,WordPress将会查找tag-sometag.php
  • tag-{id}.php – 如果标签ID为6,WordPress将会查找tag-6.php(WordPress 2.9及以上版本支持)
  • tag.php
要求:使用elementor编辑页面后需要把该页面设置成首页 实现: 1. 使用elementor编辑保存好页面 1. 在WordPress后台依次打开:设置 – 阅读 – 静态页面 2. 选择刚才保存好的页面
要求:使用elementor编辑页面后需要把该页面设置成首页 实现: 1. 使用elementor编辑保存好页面 1. 在WordPress后台依次打开:设置 – 阅读 – 静态页面 2. 选择刚才保存好的页面
https://developer.wordpress.org/reference/
## 基本模板文件 ``` style.css //主题样式文件 index.php //首页模板文件 header.php //头部模板文件 single.php //单篇文章模板文件 archive.php //存档/分类模板文件 searchform.php //搜索表单模板文件 search.php //搜索模板文件 404.php //404模板文件 comments.php //留言模板文件 footer.php //底部模板文件 sidebar.php //侧边栏模板文件 page.php //静态页面模板文件 front-page.php //静态首页模板文件 tag.php //标签存档模板文件 category.php //分类存档模板文件 ```
WordPress 有六个默认的用户角色可供选择,从最少功能到最多功能在此处排序: - 订阅者。这个角色是最不宽容的。订阅者可以管理他们的个人资料并阅读网站上的文章。除此之外,没有其他权限。 - 贡献者。这里的主要权限是贡献者可以创建文章。但是,无法直接发布和删除文章。贡献者可以删除草稿,仅此而已。 - 作者。该角色更加个性化,因为除了您自己的内容之外,您无法处理站点上的其他内容。作者可以创建、编辑、发布和删除文章,添加图像等媒体,以及添加分类法。但是,作者不能创建新分类,只能添加现有分类。 - 编辑。此角色处理内容和相关方面,例如评论。它允许用户发布、修改和删除站点上的任何文章或页面、审核评论和管理分类法。 - 管理员。如果您创建了一个站点,或者是该站点的第一个用户,那么您就是管理员。您获得最多的权限,并且可以不受限制地做任何您想做的事情。 - 超级管理员。如果您运行 WordPress 多站点模式(Multisite),超级管理员将负责整个网络,而不是只负责一个站点。如果 WordPress 站点不是网络的一部分,您将不会看到此用户角色。