WordPress自定义文章类型入门:从零开始构建你的第一个自定义内容类型

· 阅读约需7分钟

引言

WordPress 自定义文章类型(Custom Post Types,简称 CPT)是 WordPress 最强大的功能之一。它允许你创建不同于默认文章和页面的自定义内容类型,比如产品、项目、案例、图书、电影等。通过自定义文章类型,你可以将 WordPress 从一个简单的博客系统转变为一个功能强大的内容管理系统(CMS)。本文将带你从零开始,学习如何创建和使用 WordPress 自定义文章类型。

一、自定义文章类型基础

什么是自定义文章类型?

自定义文章类型是 WordPress 中用于存储不同类型内容的机制。WordPress 默认提供了几种文章类型:

  • post:文章
  • page:页面
  • attachment:附件
  • revision:修订版本
  • nav_menu_item:导航菜单项

通过自定义文章类型,你可以创建自己的内容类型,每个类型都有自己的编辑界面、分类法和模板。

为什么需要自定义文章类型?

  • 内容组织:将不同类型的内容分开管理
  • 自定义字段:为特定内容类型添加专属字段
  • 独立模板:为不同内容类型设计不同的展示方式
  • 权限控制:对不同内容类型设置不同的权限
  • SEO 优化:为不同内容类型设置独立的 URL 结构

二、创建自定义文章类型

1. 使用代码创建

在主题的 functions.php 文件中添加以下代码:

<?php
// 注册自定义文章类型:产品
function create_product_post_type() {
    $labels = array(
        'name'                  => _x('产品', 'Post Type General Name', 'text_domain'),
        'singular_name'         => _x('产品', 'Post Type Singular Name', 'text_domain'),
        'menu_name'             => __('产品', 'text_domain'),
        'name_admin_bar'        => __('产品', 'text_domain'),
        'archives'              => __('产品归档', 'text_domain'),
        'attributes'            => __('产品属性', 'text_domain'),
        'parent_item_colon'     => __('父级产品:', 'text_domain'),
        'all_items'             => __('所有产品', 'text_domain'),
        'add_new_item'          => __('添加新产品', 'text_domain'),
        'add_new'               => __('添加新', 'text_domain'),
        'new_item'              => __('新产品', 'text_domain'),
        'edit_item'             => __('编辑产品', 'text_domain'),
        'update_item'           => __('更新产品', 'text_domain'),
        'view_item'             => __('查看产品', 'text_domain'),
        'view_items'            => __('查看产品', 'text_domain'),
        'search_items'          => __('搜索产品', 'text_domain'),
        'not_found'             => __('未找到', 'text_domain'),
        'not_found_in_trash'    => __('回收站中未找到', 'text_domain'),
        'featured_image'        => __('产品图片', 'text_domain'),
        'set_featured_image'    => __('设置产品图片', 'text_domain'),
        'remove_featured_image' => __('移除产品图片', 'text_domain'),
        'use_featured_image'    => __('使用产品图片', 'text_domain'),
        'insert_into_item'      => __('插入到产品', 'text_domain'),
        'uploaded_to_this_item' => __('上传到此产品', 'text_domain'),
        'items_list'            => __('产品列表', 'text_domain'),
        'items_list_navigation' => __('产品列表导航', 'text_domain'),
        'filter_items_list'     => __('筛选产品列表', 'text_domain'),
    );

    $args = array(
        'label'                 => __('产品', 'text_domain'),
        'description'           => __('产品描述', 'text_domain'),
        'labels'                => $labels,
        'supports'              => array('title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields'),
        'taxonomies'            => array('category', 'post_tag'),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
        'menu_icon'             => 'dashicons-cart',
    );

    register_post_type('product', $args);
}
add_action('init', 'create_product_post_type', 0);
?>

2. 参数详解

supports(支持的功能)

'supports' => array(
    'title',           // 标题
    'editor',          // 内容编辑器
    'excerpt',         // 摘要
    'author',          // 作者
    'thumbnail',       // 特色图片
    'trackbacks',      // 引用通知
    'custom-fields',   // 自定义字段
    'comments',        // 评论
    'revisions',       // 修订版本
    'page-attributes', // 页面属性(模板、排序)
    'post-formats'     // 文章格式
)

menu_icon(菜单图标)

WordPress 提供了多种内置图标:

// 常用图标
'menu_icon' => 'dashicons-admin-post'      // 文章图标
'menu_icon' => 'dashicons-admin-page'      // 页面图标
'menu_icon' => 'dashicons-cart'            // 购物车
'menu_icon' => 'dashicons-products'        // 产品
'menu_icon' => 'dashicons-book'            // 书籍
'menu_icon' => 'dashicons-star-filled'     // 星星
'menu_icon' => 'dashicons-heart'           // 爱心
'menu_icon' => 'dashicons-smiley'          // 笑脸
'menu_icon' => 'dashicons-format-quote'    // 引用
'menu_icon' => 'dashicons-format-gallery'  // 画廊

public(公开性设置)

'public' => true,  // 等价于以下设置:
// 'show_ui' => true
// 'show_in_menu' => true
// 'show_in_nav_menus' => true
// 'show_in_admin_bar' => true
// 'exclude_from_search' => false
// 'publicly_queryable' => true

三、创建自定义分类法

1. 为自定义文章类型添加分类

<?php
// 注册自定义分类法:产品分类
function create_product_taxonomy() {
    $labels = array(
        'name'                       => _x('产品分类', 'Taxonomy General Name', 'text_domain'),
        'singular_name'              => _x('产品分类', 'Taxonomy Singular Name', 'text_domain'),
        'menu_name'                  => __('产品分类', 'text_domain'),
        'all_items'                  => __('所有分类', 'text_domain'),
        'parent_item'                => __('父级分类', 'text_domain'),
        'parent_item_colon'          => __('父级分类:', 'text_domain'),
        'new_item_name'              => __('新分类名称', 'text_domain'),
        'add_new_item'               => __('添加新分类', 'text_domain'),
        'edit_item'                  => __('编辑分类', 'text_domain'),
        'update_item'                => __('更新分类', 'text_domain'),
        'view_item'                  => __('查看分类', 'text_domain'),
        'search_items'               => __('搜索分类', 'text_domain'),
    );

    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true, // true = 类似分类,false = 类似标签
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'rewrite'                    => array('slug' => 'product-category'),
    );

    register_taxonomy('product_category', array('product'), $args);
}
add_action('init', 'create_product_taxonomy', 0);
?>

2. 创建标签式分类法

<?php
// 注册自定义标签:产品标签
function create_product_tags() {
    $labels = array(
        'name'                       => _x('产品标签', 'Taxonomy General Name', 'text_domain'),
        'singular_name'              => _x('产品标签', 'Taxonomy Singular Name', 'text_domain'),
        'menu_name'                  => __('产品标签', 'text_domain'),
        'search_items'               => __('搜索标签', 'text_domain'),
        'popular_items'              => __('热门标签', 'text_domain'),
        'all_items'                  => __('所有标签', 'text_domain'),
        'parent_item'                => null,
        'parent_item_colon'          => null,
        'edit_item'                  => __('编辑标签', 'text_domain'),
        'update_item'                => __('更新标签', 'text_domain'),
        'add_new_item'               => __('添加新标签', 'text_domain'),
        'new_item_name'              => __('新标签名称', 'text_domain'),
        'separate_items_with_commas' => __('用逗号分隔标签', 'text_domain'),
        'add_or_remove_items'        => __('添加或移除标签', 'text_domain'),
        'choose_from_most_used'      => __('从常用标签中选择', 'text_domain'),
        'not_found'                  => __('未找到标签', 'text_domain'),
    );

    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => false, // false = 标签式
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'rewrite'                    => array('slug' => 'product-tag'),
    );

    register_taxonomy('product_tag', array('product'), $args);
}
add_action('init', 'create_product_tags', 0);
?>

四、添加自定义字段

1. 使用自定义字段元框

<?php
// 添加自定义字段元框
function add_product_meta_boxes() {
    add_meta_box(
        'product_details',          // 元框 ID
        '产品详情',                 // 元框标题
        'render_product_meta_box',  // 渲染回调函数
        'product',                  // 文章类型
        'normal',                   // 上下文(normal, side, advanced)
        'high'                      // 优先级
    );
}
add_action('add_meta_boxes', 'add_product_meta_boxes');

// 渲染元框
function render_product_meta_box($post) {
    // 添加 nonce 字段用于安全验证
    wp_nonce_field('product_meta_box', 'product_meta_nonce');

    // 获取已保存的值
    $price = get_post_meta($post->ID, '_product_price', true);
    $sku = get_post_meta($post->ID, '_product_sku', true);
    $stock = get_post_meta($post->ID, '_product_stock', true);

    echo '<div style="margin-bottom: 15px;">';
    echo '<label style="display: block; margin-bottom: 5px; font-weight: bold;">产品价格</label>';
    echo '<input type="number" step="0.01" name="product_price" value="' . esc_attr($price) . '" style="width: 100%; padding: 8px;">';
    echo '</div>';

    echo '<div style="margin-bottom: 15px;">';
    echo '<label style="display: block; margin-bottom: 5px; font-weight: bold;">产品 SKU</label>';
    echo '<input type="text" name="product_sku" value="' . esc_attr($sku) . '" style="width: 100%; padding: 8px;">';
    echo '</div>';

    echo '<div style="margin-bottom: 15px;">';
    echo '<label style="display: block; margin-bottom: 5px; font-weight: bold;">库存数量</label>';
    echo '<input type="number" name="product_stock" value="' . esc_attr($stock) . '" style="width: 100%; padding: 8px;">';
    echo '</div>';
}

// 保存自定义字段
function save_product_meta($post_id) {
    // 验证 nonce
    if (!isset($_POST['product_meta_nonce']) || !wp_verify_nonce($_POST['product_meta_nonce'], 'product_meta_box')) {
        return;
    }

    // 检查自动保存
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // 检查权限
    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    // 保存数据
    if (isset($_POST['product_price'])) {
        update_post_meta($post_id, '_product_price', sanitize_text_field($_POST['product_price']));
    }

    if (isset($_POST['product_sku'])) {
        update_post_meta($post_id, '_product_sku', sanitize_text_field($_POST['product_sku']));
    }

    if (isset($_POST['product_stock'])) {
        update_post_meta($post_id, '_product_stock', sanitize_text_field($_POST['product_stock']));
    }
}
add_action('save_post_product', 'save_product_meta');
?>

2. 在前端显示自定义字段

<?php
// 在单篇产品页面显示自定义字段
function display_product_fields($content) {
    if (is_singular('product')) {
        global $post;

        $price = get_post_meta($post->ID, '_product_price', true);
        $sku = get_post_meta($post->ID, '_product_sku', true);
        $stock = get_post_meta($post->ID, '_product_stock', true);

        $extra_content = '<div class="product-details" style="background: #f5f5f5; padding: 20px; margin: 20px 0; border-radius: 5px;">';
        $extra_content .= '
<h3>产品信息</h3>';

        if ($price) {
            $extra_content .= '
<p><strong>价格:</strong>¥' . esc_html($price) . '</p>';
        }

        if ($sku) {
            $extra_content .= '
<p><strong>SKU:</strong>' . esc_html($sku) . '</p>';
        }

        if ($stock) {
            $extra_content .= '
<p><strong>库存:</strong>' . esc_html($stock) . ' 件</p>';
        }

        $extra_content .= '</div>';

        $content .= $extra_content;
    }

    return $content;
}
add_filter('the_content', 'display_product_fields');
?>

五、创建自定义模板

1. 单篇文章模板

创建 single-product.php 文件:

<?php get_header(); ?>

<div id="primary" class="content-area">
    <main id="main" class="site-main">

    <?php while (have_posts()) : the_post(); ?>

        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
                <?php the_title('<h1 class="entry-title">', '</h1>'); ?>
            </header>

            <div class="entry-content">
                <?php the_content(); ?>

                <?php
                // 显示自定义字段
                $price = get_post_meta(get_the_ID(), '_product_price', true);
                $sku = get_post_meta(get_the_ID(), '_product_sku', true);
                $stock = get_post_meta(get_the_ID(), '_product_stock', true);
                ?>

                <div class="product-info">

<h2>产品详情</h2>
                    <table class="product-table">

<tr>

<td>价格</td>

<td>¥<?php echo esc_html($price); ?></td>
                        </tr>

<tr>

<td>SKU</td>

<td><?php echo esc_html($sku); ?></td>
                        </tr>

<tr>

<td>库存</td>

<td><?php echo esc_html($stock); ?> 件</td>
                        </tr>
                    </table>
                </div>
            </div>
        </article>

    <?php endwhile; ?>

    </main>
</div>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

2. 归档页面模板

创建 archive-product.php 文件:

<?php get_header(); ?>

<div id="primary" class="content-area">
    <main id="main" class="site-main">

        <header class="page-header">
            <h1 class="page-title">产品列表</h1>
        </header>

        <div class="product-grid">
        <?php if (have_posts()) : while (have_posts()) : the_post(); ?>

            <div class="product-item">
                <a href="<?php the_permalink(); ?>">
                    <?php if (has_post_thumbnail()) : ?>
                        <div class="product-image">
                            <?php the_post_thumbnail('medium'); ?>
                        </div>
                    <?php endif; ?>

                    <h2 class="product-title"><?php the_title(); ?></h2>

                    <?php
                    $price = get_post_meta(get_the_ID(), '_product_price', true);
                    if ($price) :
                    ?>
                        <p class="product-price">¥<?php echo esc_html($price); ?></p>
                    <?php endif; ?>
                </a>
            </div>

        <?php endwhile; ?>

        <?php the_posts_navigation(); ?>

        <?php else : ?>

<p>没有找到产品。</p>
        <?php endif; ?>
        </div>

    </main>
</div>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

六、查询自定义文章类型

1. 使用 WP_Query 查询

<?php
// 查询产品
$args = array(
    'post_type'      => 'product',
    'posts_per_page' => 10,
    'post_status'    => 'publish',
    'orderby'        => 'date',
    'order'          => 'DESC',
);

$query = new WP_Query($args);

if ($query->have_posts()) :
    echo '<div class="product-list">';
    while ($query->have_posts()) : $query->the_post();
        echo '<div class="product-item">';
        echo '
<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';

        $price = get_post_meta(get_the_ID(), '_product_price', true);
        if ($price) {
            echo '<p class="price">¥' . esc_html($price) . '</p>';
        }

        echo '</div>';
    endwhile;
    echo '</div>';

    // 分页
    echo paginate_links(array(
        'total' => $query->max_num_pages
    ));

    wp_reset_postdata();
else :
    echo '
<p>没有找到产品。</p>';
endif;
?>

2. 按分类查询

<?php
// 按产品分类查询
$args = array(
    'post_type'      => 'product',
    'posts_per_page' => -1,
    'tax_query'      => array(
        array(
            'taxonomy' => 'product_category',
            'field'    => 'slug',
            'terms'    => 'electronics', // 分类别名
        )
    )
);

$query = new WP_Query($args);
?>

3. 按自定义字段查询

<?php
// 按价格范围查询
$args = array(
    'post_type'      => 'product',
    'posts_per_page' => -1,
    'meta_query'     => array(
        array(
            'key'     => '_product_price',
            'value'   => array(100, 500),
            'type'    => 'numeric',
            'compare' => 'BETWEEN',
        )
    ),
    'orderby'        => 'meta_value_num',
    'meta_key'       => '_product_price',
    'order'          => 'ASC',
);

$query = new WP_Query($args);
?>

七、实战案例:完整的产品系统

1. 完整的产品自定义文章类型

<?php
// 完整的产品系统
function complete_product_system() {
    // 注册产品文章类型
    $labels = array(
        'name'                  => '产品',
        'singular_name'         => '产品',
        'menu_name'             => '产品',
        'add_new'               => '添加产品',
        'add_new_item'          => '添加新产品',
        'edit_item'             => '编辑产品',
        'new_item'              => '新产品',
        'view_item'             => '查看产品',
        'search_items'          => '搜索产品',
        'not_found'             => '未找到产品',
        'not_found_in_trash'    => '回收站中未找到产品',
    );

    $args = array(
        'labels'                => $labels,
        'public'                => true,
        'has_archive'           => true,
        'supports'              => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'),
        'menu_icon'             => 'dashicons-cart',
        'menu_position'         => 5,
        'rewrite'               => array('slug' => 'products'),
    );

    register_post_type('product', $args);

    // 注册产品分类
    register_taxonomy('product_category', 'product', array(
        'label'        => '产品分类',
        'hierarchical' => true,
        'rewrite'      => array('slug' => 'product-category'),
        'show_admin_column' => true,
    ));

    // 注册产品标签
    register_taxonomy('product_tag', 'product', array(
        'label'        => '产品标签',
        'hierarchical' => false,
        'rewrite'      => array('slug' => 'product-tag'),
        'show_admin_column' => true,
    ));
}
add_action('init', 'complete_product_system');

// 添加产品元框
function add_product_metaboxes() {
    add_meta_box('product_info', '产品信息', 'render_product_info', 'product', 'side', 'default');
}
add_action('add_meta_boxes', 'add_product_metaboxes');

function render_product_info($post) {
    wp_nonce_field('product_info_nonce', 'product_info_nonce');

    $price = get_post_meta($post->ID, '_price', true);
    $sale_price = get_post_meta($post->ID, '_sale_price', true);
    $sku = get_post_meta($post->ID, '_sku', true);
    $stock = get_post_meta($post->ID, '_stock', true);
    $weight = get_post_meta($post->ID, '_weight', true);

    echo '
<p><label>价格:<input type="number" step="0.01" name="price" value="' . esc_attr($price) . '" class="widefat"></label></p>';
    echo '
<p><label>促销价:<input type="number" step="0.01" name="sale_price" value="' . esc_attr($sale_price) . '" class="widefat"></label></p>';
    echo '
<p><label>SKU:<input type="text" name="sku" value="' . esc_attr($sku) . '" class="widefat"></label></p>';
    echo '
<p><label>库存:<input type="number" name="stock" value="' . esc_attr($stock) . '" class="widefat"></label></p>';
    echo '
<p><label>重量(kg):<input type="number" step="0.1" name="weight" value="' . esc_attr($weight) . '" class="widefat"></label></p>';
}

function save_product_info($post_id) {
    if (!isset($_POST['product_info_nonce']) || !wp_verify_nonce($_POST['product_info_nonce'], 'product_info_nonce')) {
        return;
    }

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    $fields = array('price', 'sale_price', 'sku', 'stock', 'weight');
    foreach ($fields as $field) {
        if (isset($_POST[$field])) {
            update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field]));
        }
    }
}
add_action('save_post_product', 'save_product_info');
?>

2. 显示产品列表的短代码

<?php
// 产品列表短代码
function product_list_shortcode($atts) {
    $atts = shortcode_atts(array(
        'category' => '',
        'limit'    => 10,
        'order'    => 'DESC',
    ), $atts);

    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => $atts['limit'],
        'order'          => $atts['order'],
    );

    if ($atts['category']) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'product_category',
                'field'    => 'slug',
                'terms'    => $atts['category'],
            )
        );
    }

    $query = new WP_Query($args);

    ob_start();

    if ($query->have_posts()) :
        echo '<div class="product-grid">';
        while ($query->have_posts()) : $query->the_post();
            echo '<div class="product-card">';
            if (has_post_thumbnail()) {
                echo '<div class="product-thumbnail">' . get_the_post_thumbnail(get_the_ID(), 'medium') . '</div>';
            }
            echo '<h3 class="product-title"><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';

            $price = get_post_meta(get_the_ID(), '_price', true);
            $sale_price = get_post_meta(get_the_ID(), '_sale_price', true);

            if ($sale_price && $sale_price < $price) {
                echo '<p class="product-price"><del>¥' . esc_html($price) . '</del> <ins>¥' . esc_html($sale_price) . '</ins></p>';
            } elseif ($price) {
                echo '<p class="product-price">¥' . esc_html($price) . '</p>';
            }

            echo '</div>';
        endwhile;
        echo '</div>';
        wp_reset_postdata();
    else :
        echo '
<p>没有找到产品。</p>';
    endif;

    return ob_get_clean();
}
add_shortcode('product_list', 'product_list_shortcode');
?>

使用短代码:

[product_list category="electronics" limit="12"]

八、高级技巧

1. 修改主查询

<?php
// 修改产品归档页面的主查询
function modify_product_archive($query) {
    if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
        $query->set('posts_per_page', 12);
        $query->set('orderby', 'meta_value_num');
        $query->set('meta_key', '_price');
        $query->set('order', 'ASC');
    }
}
add_action('pre_get_posts', 'modify_product_archive');
?>

2. 添加自定义列到管理列表

<?php
// 添加自定义列
function add_product_columns($columns) {
    $new_columns = array();

    foreach ($columns as $key => $value) {
        if ($key == 'title') {
            $new_columns[$key] = $value;
            $new_columns['price'] = '价格';
            $new_columns['sku'] = 'SKU';
            $new_columns['stock'] = '库存';
        } else {
            $new_columns[$key] = $value;
        }
    }

    return $new_columns;
}
add_filter('manage_product_posts_columns', 'add_product_columns');

// 显示自定义列内容
function show_product_columns($column, $post_id) {
    switch ($column) {
        case 'price':
            $price = get_post_meta($post_id, '_price', true);
            echo $price ? '¥' . esc_html($price) : '-';
            break;
        case 'sku':
            $sku = get_post_meta($post_id, '_sku', true);
            echo esc_html($sku) ?: '-';
            break;
        case 'stock':
            $stock = get_post_meta($post_id, '_stock', true);
            echo esc_html($stock) ?: '-';
            break;
    }
}
add_action('manage_product_posts_custom_column', 'show_product_columns', 10, 2);
?>

3. 使自定义列可排序

<?php
// 使列可排序
function make_product_columns_sortable($columns) {
    $columns['price'] = 'price';
    $columns['sku'] = 'sku';
    $columns['stock'] = 'stock';
    return $columns;
}
add_filter('manage_edit-product_sortable_columns', 'make_product_columns_sortable');

// 排序逻辑
function product_column_orderby($query) {
    if (!is_admin()) {
        return;
    }

    $orderby = $query->get('orderby');

    if ('price' == $orderby) {
        $query->set('meta_key', '_price');
        $query->set('orderby', 'meta_value_num');
    }

    if ('sku' == $orderby) {
        $query->set('meta_key', '_sku');
        $query->set('orderby', 'meta_value');
    }

    if ('stock' == $orderby) {
        $query->set('meta_key', '_stock');
        $query->set('orderby', 'meta_value_num');
    }
}
add_action('pre_get_posts', 'product_column_orderby');
?>

九、最佳实践

1. 性能优化

<?php
// 为自定义字段添加索引(提升查询性能)
// 在插件激活时运行
function add_custom_field_indexes() {
    global $wpdb;

    // 为常用的 meta key 添加索引
    $wpdb->query("ALTER TABLE {$wpdb->postmeta} ADD INDEX price_index (meta_key(20), meta_value(20))");
}
register_activation_hook(__FILE__, 'add_custom_field_indexes');
?>

2. 数据验证和清理

<?php
// 严格的数据验证
function save_product_data($post_id) {
    // 验证价格
    if (isset($_POST['price'])) {
        $price = floatval($_POST['price']);
        if ($price >= 0) {
            update_post_meta($post_id, '_price', $price);
        }
    }

    // 验证库存
    if (isset($_POST['stock'])) {
        $stock = intval($_POST['stock']);
        if ($stock >= 0) {
            update_post_meta($post_id, '_stock', $stock);
        }
    }

    // 清理 SKU
    if (isset($_POST['sku'])) {
        $sku = sanitize_text_field($_POST['sku']);
        update_post_meta($post_id, '_sku', $sku);
    }
}
?>

3. 权限控制

<?php
// 为自定义文章类型设置自定义权限
function set_product_capabilities() {
    $role = get_role('editor');

    // 添加产品相关权限
    $role->add_cap('edit_product');
    $role->add_cap('read_product');
    $role->add_cap('delete_product');
    $role->add_cap('edit_products');
    $role->add_cap('edit_others_products');
    $role->add_cap('publish_products');
    $role->add_cap('read_private_products');
    $role->add_cap('delete_products');
    $role->add_cap('delete_private_products');
    $role->add_cap('delete_published_products');
    $role->add_cap('delete_others_products');
    $role->add_cap('edit_private_products');
    $role->add_cap('edit_published_products');
}
add_action('admin_init', 'set_product_capabilities');
?>

十、总结与扩展

你已经学会了:

  1. ✅ 创建自定义文章类型
  2. ✅ 创建自定义分类法
  3. ✅ 添加自定义字段
  4. ✅ 创建自定义模板
  5. ✅ 查询自定义文章类型
  6. ✅ 高级技巧和最佳实践

下一步可以学习:

  • 高级自定义字段(ACF):使用 ACF 插件更轻松地管理自定义字段
  • 自定义状态(Post Status):创建自定义的文章状态
  • REST API 集成:为自定义文章类型添加 REST API 支持
  • 多语言支持:使自定义文章类型支持多语言
  • 导入导出:自定义文章类型的数据导入导出

推荐资源:


希望这篇教程能帮助你入门 WordPress 自定义文章类型。自定义文章类型是 WordPress 开发中非常重要的技能,掌握它将让你能够构建更加复杂和专业的网站。

Happy Coding! 🚀