代码/插件两种方法在Wordpress中快速使用自定义文章类型

自从 Wordpress 有了自定义文章类型,它终于完全彻底地成为一个 CMS 系统了。
比如,我想新增一个「品牌」类型,创建一些品牌数据,每个品牌有自己的一些属性(名称、官网、微博、微信等信息)就非常适合用自定义文章类型来实现。

代码方法

自定义文章类型的使用也很简单,如果通过代码实现的话,只要在主题文件的 function.php 中稍作修改,即可实现。
可以这样实现:

function my_custom_post_brand() {
  $labels = array(
    'name'               => _x( 'Brands', 'post type 名称' ),
    'singular_name'      => _x( 'Brand', 'post type 单个 item 时的名称,因为英文有复数' ),
    'add_new'            => _x( '新建品牌', '添加新内容的链接名称' ),
    'add_new_item'       => __( '新建一个品牌' ),
    'edit_item'          => __( '编辑品牌' ),
    'new_item'           => __( '新品牌' ),
    'all_items'          => __( '所有品牌' ),
    'view_item'          => __( '查看品牌' ),
    'search_items'       => __( '搜索品牌' ),
    'not_found'          => __( '没有找到有关品牌' ),
    'not_found_in_trash' => __( '回收站里面没有相关品牌' ),
    'parent_item_colon'  => '',
    'menu_name'          => '品牌'
  );
  $args = array(
    'labels'        => $labels,
    'description'   => '体育品牌信息',

    'public'        => true,
    'menu_position' => 5,
    'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
    'has_archive'   => true
  );
  register_post_type( 'brand', $args );
}
add_action( 'init', 'my_custom_post_brand' );

效果如下:

对于自定义的品牌类型,要想用单独的分类进行管理(独立于博客文章的分类),可使用如下代码:

// 添加品牌分类
function my_taxonomies_brand() {
  $labels = array(
    'name'              => _x( '品牌分类', 'taxonomy 名称' ),
    'singular_name'     => _x( '品牌分类', 'taxonomy 单数名称' ),
    'search_items'      => __( '搜索品牌分类' ),
    'all_items'         => __( '所有品牌分类' ),
    'parent_item'       => __( '该品牌分类的上级分类' ),
    'parent_item_colon' => __( '该品牌分类的上级分类:' ),
    'edit_item'         => __( '编辑品牌分类' ),
    'update_item'       => __( '更新品牌分类' ),
    'add_new_item'      => __( '添加新的品牌分类' ),
    'new_item_name'     => __( '新品牌分类' ),
    'menu_name'         => __( '品牌分类' ),
  );
  $args = array(
    'labels' => $labels,
    'hierarchical' => true,
  );
  register_taxonomy( 'brand_category', 'brand', $args );
}
add_action( 'init', 'my_taxonomies_brand', 0 );

效果如下:

品牌类型有一些特定的属性,比如品牌名、官网等,可通过如下代码实现:

// 新建一个 Metabox,实现在后台进行编辑
add_action( 'add_meta_boxes', 'brand_info' );
function brand_info() {
    add_meta_box(
        'brand_info',
        '品牌信息',
        'brand_info_meta_box',
        'brand',
        'normal',
        'low'
    );
}

// 定义表单
function brand_info_meta_box($post) {

    // 创建临时隐藏表单,为了安全
    wp_nonce_field( 'brand_info_meta_box', 'brand_info_meta_box_nonce' );
    // 获取之前存储的值
    $name = get_post_meta( $post->ID, 'name', true );
    $weibo = get_post_meta( $post->ID, 'weibo', true );
    $site = get_post_meta( $post->ID, 'site', true );
    $wxid = get_post_meta( $post->ID, 'wxid', true );

    ?>

    <p><label for="name">中文名</label></p>
    <input type="text" id="name" name="name" value="<?php echo esc_attr( $name ); ?>" placeholder="输入品牌中文名称" >
  <br>

    <p><label for="weibo">微博</label></p>
    <input type="text" id="weibo" name="weibo" value="<?php echo esc_attr( $weibo ); ?>" placeholder="输入微博昵称" >

    <p><label for="site">官网</label></p>
    <input type="text" id="site" name="site" value="<?php echo esc_attr( $site ); ?>" placeholder="输入品牌官网地址" >

    <p><label for="wxid">微信号</label></p>
    <input type="text" id="wxid" name="wxid" value="<?php echo esc_attr( $wxid ); ?>" placeholder="输入品牌官网地址" >
    <?php
}

// 提交时的动作
add_action( 'save_post', 'brand_info_save_meta_box' );
function brand_info_save_meta_box($post_id){

    $name = sanitize_text_field( $_POST['name'] );
    $weibo = sanitize_text_field( $_POST['weibo'] );
    $site = sanitize_text_field( $_POST['site'] );
    $wxid = sanitize_text_field( $_POST['wxid'] );
    update_post_meta( $post_id, 'name', $name );
    update_post_meta( $post_id, 'weibo', $weibo );
    update_post_meta( $post_id, 'site', $site );
    update_post_meta( $post_id, 'wxid', $wxid );
}
add_action("manage_posts_custom_column",  "brand_custom_columns");

效果如下:

如果要修改品牌列表(全部文章)显示的信息,可用这段代码实现:

add_filter("manage_edit-brand_columns", "brand_edit_columns");
function brand_custom_columns($column){
    global $post;
    switch ($column) {
        case "name":
            echo get_post_meta( $post->ID, 'name', true );
            break;
    }
}
function brand_edit_columns($columns){

    $columns['name'] = '品牌名';

    return $columns;
}

效果如下:

插件方法

如果你只有一个自定义类型,那么上面的代码不仅能胜任,还可以精细定制一些细节(比如这个类型的属性、校验规则等)。但是,如果有很多自定义类型,用代码的话,就要复制粘贴很多遍,还要更改变量名和显示名称,非常麻烦。
有些插件已经实现了自定义类型的功能,可以傻瓜化地添加和管理。比如 Types

Types 有免费版和两个不同的付费版。如果仅使用自定义文章类型功能的话,免费版就足够了。

你可以根据自己的需要,选择代码方法或插件方法。我的建议是,如果只有一个自定义类型,可以用代码方法,这样定制化的可能性更大;如果有多个自定义类型,还是通过插件管理比较方便。

阅读 173