自定义文章类型
什么是自定义文章类型?
自定义文章类型(Custom Post Types,CPT)允许你创建 WordPress 默认文章和页面之外的内容类型。
内置内容类型
| 类型 | 说明 | 是否有存档页 |
|---|---|---|
| Post | 博客文章 | 有 |
| Page | 静态页面 | 有 |
| Attachment | 媒体文件 | 无 |
| Revision | 修订版本 | 无 |
| Navigation Menu | 导航菜单项 | 无 |
自定义文章类型的应用场景
- 作品集 - 展示设计/开发作品
- 产品 - 电商网站产品
- 案例研究 - 客户案例
- 食谱 - 美食博客
- 视频 - 视频库
- 评价/评测 - 产品评测
- 员工 - 团队成员介绍
注册自定义文章类型
基本代码
php
<?php
// functions.php 或插件文件
function my_custom_post_types() {
// 注册自定义文章类型
register_post_type('portfolio', array(
'labels' => array(
'name' => '作品集',
'singular_name' => '作品',
'add_new' => '添加新作品',
'add_new_item' => '添加新作品',
'edit_item' => '编辑作品',
'new_item' => '新作品',
'view_item' => '查看作品',
'search_items' => '搜索作品',
'not_found' => '未找到作品',
'not_found_in_trash'=> '回收站中未找到作品',
'parent_item_colon' => '父级作品:',
),
'hierarchical' => false,
'description' => '我们的项目作品集',
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-portfolio',
'capability_type' => 'post',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'),
'taxonomies' => array('category', 'post_tag'),
'has_archive' => true,
'rewrite' => array('slug' => 'portfolio'),
'query_var' => true,
'show_in_rest' => true, // 古腾堡编辑器支持
));
}
add_action('init', 'my_custom_post_types');完整参数说明
php
<?php
register_post_type('post_type_name', array(
// === 标签 (Labels) ===
'labels' => array(
'name' => '名称',
'singular_name' => '单数名称',
'add_new' => '添加',
'add_new_item' => '添加新项目',
'edit_item' => '编辑',
'new_item' => '新项目',
'view_item' => '查看',
'view_items' => '查看所有',
'search_items' => '搜索',
'not_found' => '未找到',
'not_found_in_trash' => '回收站中未找到',
'parent_item_colon' => '父级:',
'all_items' => '所有项目',
'archives' => '存档',
'attributes' => '属性',
'insert_into_item' => '插入到',
'uploaded_to_this_item' => '上传到这个',
'featured_image' => '特色图片',
'set_featured_image' => '设置特色图片',
'remove_featured_image' => '移除特色图片',
'use_featured_image' => '使用特色图片',
'menu_name' => '菜单名称',
),
// === 公开性 (Public) ===
'public' => true, // 对管理员和前端可见
'show_ui' => true, // 在后台显示 UI
'show_in_nav_menus' => true, // 在导航菜单中显示
'show_in_admin_bar' => true, // 在后台工具栏显示
'exclude_from_search' => false, // 从搜索结果中排除
'publicly_queryable' => true, // 允许公共查询
'can_export' => true, // 允许导出
// === 层级 ===
'hierarchical' => false, // true=页面样式, false=文章样式
// === UI ===
'capability_type' => 'post', // 权限类型
'menu_position' => null, // 菜单位置
'menu_icon' => null, // 菜单图标 (Dashicons)
'register_meta_box_cb' => null, // 注册 Meta Box 的回调
// === 功能支持 ===
'supports' => array(
'title', // 标题
'editor', // 内容编辑器
'author', // 作者
'thumbnail', // 特色图片
'excerpt', // 摘要
'trackbacks', // 引用
'custom-fields', // 自定义字段
'comments', // 评论
'revisions', // 修订版本
'page-attributes', // 页面属性 (顺序)
'post-formats', // 文章格式
),
// === 分类法 ===
'taxonomies' => array(), // 关联的分类法
// === 永久链接 ===
'permalink_epmask' => 'EP_PERMALINK',
'rewrite' => array(
'slug' => 'custom-slug',
'with_front' => true,
'feeds' => true,
'pages' => true,
'ep_mask' => EP_PERMALINK,
),
'query_var' => true, // 查询变量名
'show_in_rest' => true, // REST API 支持 (Gutenberg)
// === 其他 ===
'_builtin' => false, // 是否为内置类型
'_edit_link' => 'post.php?post=%d',
));菜单图标参考
使用 WordPress Dashicons:
php
// 常用图标
'dashicons-portfolio' // 作品集
'dashicons-products' // 产品
'dashicons-testimonial' // 评价
'dashicons-admin-custom' // 自定义图标
'dashicons-book' // 书籍
'dashicons-money' // 金钱
'dashicons-calendar' // 日历
'dashicons-video' // 视频创建分层自定义文章类型
类似于页面,可以有父级和子级:
php
<?php
register_post_type('documentation', array(
'labels' => array(
'name' => '文档',
'singular_name' => '文档',
),
'hierarchical' => true, // 重要:启用层级
'supports' => array(
'title',
'editor',
'page-attributes', // 支持父级选择
'thumbnail'
),
'rewrite' => array('slug' => 'docs'),
));创建存档页模板
archive-{post_type}.php
php
<?php
/**
* 作品集存档页模板
*/
get_header(); ?>
<main class="portfolio-archive">
<header class="archive-header">
<h1>我们的作品</h1>
<p>浏览我们完成的项目</p>
</header>
<?php
// 分类过滤
$terms = get_terms('portfolio_category');
if ($terms): ?>
<div class="portfolio-filters">
<button class="filter-btn active" data-filter="all">全部</button>
<?php foreach ($terms as $term): ?>
<button class="filter-btn" data-filter="<?php echo $term->slug; ?>">
<?php echo $term->name; ?>
</button>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="portfolio-grid">
<?php
// 循环输出作品
while (have_posts()): the_post();
// 获取分类
$terms = get_the_terms(get_the_ID(), 'portfolio_category');
$term_class = $terms ? implode(' ', wp_list_pluck($terms, 'slug')) : '';
?>
<article class="portfolio-item <?php echo $term_class; ?>">
<a href="<?php the_permalink(); ?>">
<?php if (has_post_thumbnail()): ?>
<div class="item-image">
<?php the_post_thumbnail('medium_large'); ?>
</div>
<?php endif; ?>
<div class="item-content">
<h2><?php the_title(); ?></h2>
<?php if (has_excerpt()): ?>
<p><?php the_excerpt(); ?></p>
<?php endif; ?>
<?php if ($terms): ?>
<div class="item-categories">
<?php foreach ($terms as $term): ?>
<span class="category-tag"><?php echo $term->name; ?></span>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</a>
</article>
<?php endwhile; ?>
</div>
<?php the_posts_pagination(); ?>
</main>
<?php get_footer(); ?>创建单页模板
single-{post_type}.php
php
<?php
/**
* 作品集单页模板
*/
get_header(); ?>
<main class="portfolio-single">
<?php while (have_posts()): the_post(); ?>
<article id="portfolio-<?php the_ID(); ?>">
<!-- 特色图片 -->
<?php if (has_post_thumbnail()): ?>
<div class="portfolio-hero">
<?php the_post_thumbnail('full'); ?>
</div>
<?php endif; ?>
<div class="portfolio-content">
<!-- 标题 -->
<header class="portfolio-header">
<h1><?php the_title(); ?></h1>
<!-- 元信息 -->
<div class="portfolio-meta">
<?php
$client = get_post_meta(get_the_ID(), 'client_name', true);
$year = get_post_meta(get_the_ID(), 'project_year', true);
$url = get_post_meta(get_the_ID(), 'project_url', true);
?>
<?php if ($client): ?>
<div class="meta-item">
<strong>客户:</strong> <?php echo esc_html($client); ?>
</div>
<?php endif; ?>
<?php if ($year): ?>
<div class="meta-item">
<strong>年份:</strong> <?php echo esc_html($year); ?>
</div>
<?php endif; ?>
<?php if ($url): ?>
<div class="meta-item">
<strong>链接:</strong>
<a href="<?php echo esc_url($url); ?>" target="_blank">
访问网站 ↗
</a>
</div>
<?php endif; ?>
</div>
</header>
<!-- 项目画廊 -->
<?php
$gallery = get_post_meta(get_the_ID(), 'project_gallery', true);
if ($gallery && is_array($gallery)): ?>
<div class="portfolio-gallery">
<h2>项目展示</h2>
<div class="gallery-grid">
<?php foreach ($gallery as $image_id): ?>
<div class="gallery-item">
<?php echo wp_get_attachment_image($image_id, 'large'); ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<!-- 内容 -->
<div class="portfolio-description">
<?php the_content(); ?>
</div>
</div>
<!-- 导航 -->
<nav class="portfolio-navigation">
<div class="nav-previous">
<?php previous_post_link('%link', '← 上一个项目'); ?>
</div>
<div class="nav-next">
<?php next_post_link('%link', '下一个项目 →'); ?>
</div>
</nav>
<!-- 相关作品 -->
<?php
$related = new WP_Query(array(
'post_type' => 'portfolio',
'posts_per_page' => 3,
'post__not_in' => array(get_the_ID()),
'tax_query' => array(
array(
'taxonomy' => 'portfolio_category',
'field' => 'term_id',
'terms' => wp_get_post_terms(get_the_ID(), 'portfolio_category', array('fields' => 'ids')),
),
),
));
if ($related->have_posts()): ?>
<section class="related-portfolio">
<h3>相关作品</h3>
<div class="related-grid">
<?php while ($related->have_posts()): $related->the_post(); ?>
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail('thumbnail'); ?>
<span><?php the_title(); ?></span>
</a>
<?php endwhile; ?>
</div>
</section>
<?php
endif;
wp_reset_postdata();
?>
</article>
<?php endwhile; ?>
</main>
<?php get_footer(); ?>自定义文章类型查询
WP_Query 方法
php
<?php
// 查询自定义文章类型
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
);
// 条件过滤
$args = array(
'post_type' => 'portfolio',
'posts_per_page' => -1, // 获取全部
'post_status' => 'publish',
'meta_key' => 'project_year',
'meta_value' => '2024',
'meta_compare' => '>=',
);
// 分类过滤
$args = array(
'post_type' => 'portfolio',
'tax_query' => array(
array(
'taxonomy' => 'portfolio_category',
'field' => 'slug',
'terms' => 'web-design',
),
),
);
$query = new WP_Query($args);
?>
<?php if ($query->have_posts()): ?>
<?php while ($query->have_posts()): $query->the_post(); ?>
<!-- 输出内容 -->
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>使用 pre_get_posts 钩子
php
<?php
// 在存档页面包含自定义文章类型
function add_portfolio_to_home($query) {
if (!is_admin() && $query->is_main_query()) {
if (is_home()) {
$query->set('post_type', array('post', 'portfolio'));
}
}
}
add_action('pre_get_posts', 'add_portfolio_to_home');高级用法
Flush Rewrite Rules
创建或更新自定义文章类型后,需要刷新永久链接:
php
<?php
// 方法 1: 保存永久链接设置页面
// 方法 2: 激活主题时
function my_rewrite_flush() {
my_custom_post_types(); // 重新注册
flush_rewrite_rules(); // 刷新规则
}
add_action('after_switch_theme', 'my_rewrite_flush');
// 方法 3: 激活插件时
register_activation_hook(__FILE__, function() {
my_custom_post_types();
flush_rewrite_rules();
});自定义列
php
<?php
// 后台列表添加自定义列
function set_custom_columns($columns) {
$columns['portfolio_client'] = '客户';
$columns['portfolio_year'] = '年份';
$columns['thumbnail'] = '缩略图';
return $columns;
}
add_filter('manage_portfolio_posts_columns', 'set_custom_columns');
function custom_column_content($column, $post_id) {
switch ($column) {
case 'portfolio_client':
echo get_post_meta($post_id, 'client_name', true);
break;
case 'portfolio_year':
echo get_post_meta($post_id, 'project_year', true);
break;
case 'thumbnail':
if (has_post_thumbnail()) {
echo get_the_post_thumbnail($post_id, array(60, 60));
}
break;
}
}
add_action('manage_portfolio_posts_custom_column', 'custom_column_content', 10, 2);