参考:https://developer.wordpress.org/plugins/post-types/
为什么自定义文章类型(Custom Post Types)
WordPress stores the Post Types in the posts table allowing developers to register Custom Post Types along the ones that already exist.
This chapter will show you how to register Custom Post Types, how to retrieve their content from the database, and how to render them to the public.
第一步:创建(注册)post type
register Custom Post Types 注册post type
需要在你主题的 functions.php
文件下调用该函数:
register_post_type( $post_type, $args );
function wporg_custom_post_type() {
register_post_type('wporg_product',
array(
'labels' => array(
'name' => __('Products', 'textdomain'),
'singular_name' => __('Product', 'textdomain'),
),
'public' => true,
'has_archive' => true,
)
);
}
add_action('init', 'wporg_custom_post_type');
包裹在一个函数中,定义一个数组,然后挂靠到 init
这个 action 上。这样 WordPress 在初始化的时候,就会执行这个函数注册一个自定义 Post Type,因为调用 register_post_type()
的时候,必须要在 admin_menu
action 之前,在 after_setup_theme
action 之后,所以这里最好挂靠到 init
action 上。
$post_type
参数就是你自定义 Post Type 的名称,Post Type 可以自定义的功能非常多,所以这个函数里面的 $args
参数会很多。
function my_custom_post_movie() {
$labels = array(
'name' => _x( 'Movies', 'post type 名称' ),
'singular_name' => _x( 'Movie', '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' => 'Movies'
);
$args = array(
'labels' => $labels,
'description' => '我们网站的电影信息',
'public' => true,
'menu_position' => 5,
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
'has_archive' => true
);
register_post_type( 'movie', $args );
}
add_action( 'init', 'my_custom_post_movie' );
这里为了直观方便,我直接使用了中文,更好的应该是使用英文然后通过本地化函数来翻译成中文。
参考:
参数有点多,也可以使用 generatewp 工具自定义参数,然后改改,会稍微方便一点。
参考链接:http://generatewp.com/post-type/
将上面代码加到主题 functions.php
的最下面,进入后台你会发现多出了 Movies
选项,这样表示注册成功:
这时候我们可以新建 Movie 发表一篇电影类型的文章了。但是这样与文章类型基本相同,我们需要更多的自定义来完善我们的 Movie 类型。
第二步:为 Post Type 添加分类功能
就电影来说,可以分为科幻、动作、战争等类别,那么我们就为自定义的 Movie 添加分类功能,这样就可以编辑新分类以及归类我们的电影了。这个分类跟文章里面的分类性质是一样的。
函数 register_taxonomy,
使用:
register_taxonomy( $taxonomy, $object_type, $args );
就本例而言,可以配置如下常用参数:
function my_taxonomies_movie() {
$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( 'movie_category', 'movie', $args );
}
add_action( 'init', 'my_taxonomies_movie', 0 );
添加到主题之后,我们看到出现了熟悉的文章分类功能,只不过上面的文案全部变成我们自定义的内容了:
第三步:为 Post Type 添加自定义 Meta Box
我们想要添加的电影类型不能仅仅只有正文内容,我们还需要额外添加一些 导演 之类的有关内容。那么就需要添加自定义 Meta Box,Meta Box 可以在文章发表页面中添加自定义的表单,编写文章的时候可以填写额外的信息然后在前端调用出来。
自定义 Meta Box 需要用到 add_meta_box 函数:
add_meta_box( $id, $title, $callback, $post_type, $context,$priority, $callback_args );
add_action( 'add_meta_boxes', 'movie_director' );
function movie_director() {
add_meta_box(
'movie_director',
'电影导演',
'movie_director_meta_box',
'movie',
'side',
'low'
);
}
第四步:展示 Post Type 的内容
单纯创建 Post Type 只是可以让你输入内容,没有什么意义,我们还需要在前台输出自定义 Post Type 的内容。
一、自定义 Post Type 的模板和样式
根据 WordPress 的模板调用规则 我们可以得知,我们只需要创建 archive-[post_type].php 和 single-[post_type].php 就可以实现该 Post Type 的列表自定义和文章自定义。当访问 Post Type,WordPress 会优先调用这些模板来渲染。
需要注意的是,你需要在注册 Post Type 的时候设置 ‘has_archive’ => true 才会有列表。
现在我们就把主题里自带的 archive.php 和 single.php 文件复制一份命名为 archive-movie.php 和 single-movie.php,为了演示,这里我不做很多自定义,只是输出导演信息表示一下。
我们分别在 L.56 和 L.23 附近的合适位置输出 Meta Box 信息:
echo ‘导演:’.get_post_meta( get_the_ID(), ‘_movie_director’, true );
然后刷新访问电影列表和具体的电影就可以看到输出的导演信息了。
这里只是举个例子,实际中往往会自定义结构和输出的信息格式等,这里不再进一步修改。这里不再麻烦演示了。
二、调用 WP_Query 高度自定义调用 Post Type 的内容
上面操作依赖模板,如果需要高度自定义或者在页面的某个模块中调用列表,就需要用到 WP_Query 类来调用:
$args = array( 'post_type' => 'product', 'posts_per_page' => 10 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
the_title();
echo '<div class="entry-content">';
the_content();
echo '</div>';
endwhile;
查询出来之后就跟常规的主循环一样了,自定输出结构即可。
三、在首页列表中显示自定义 Post Type 的内容
虽然我们自定义好了 Post Type 同时也编写了一些内容,但是在首页的列表里面并没有显示出来。自定义的 Post Type 的内容不会自动混入主循环里面。那如何让自定义 Post Type 的内容显示出来?
你需要使用 pre_get_posts 这个 action 来做一些处理:
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
function add_my_post_types_to_query( $query ) {
if ( is_home() && $query->is_main_query() )
$query->set( 'post_type', array( 'post', 'page', 'movie' ) );
return $query;
}
在上面的 $query
变量里面设置的 post_type
数组就是要在主循环里面展示的内容,将你的自定义 Post Type填写进去就可以在首页中显示出来了。
四、设置自定义 Post Type 的固定连接
创建一个新的 Post Type 有时候也是为了更方便做 SEO,所以设置它的固定连接也非常重要。这里主要用到注册 Post Type 的参数数组里面的 rewrite
参数,常用以下几两项:
slug
=>自定义固定连接结构别名,默认是使用 Post Type 名(例如本例的 movie),可以被翻译。一般来说 Post Type 名可能与实际需要的 URL 不一样( Post Type 为 movie,但 URL 可能需要 movies),就可使用该项自定义。with_front
=> 固定连接是否以根目录为基础路径。如果你在固定连接设置页面设置你的结构为/archives/
,那么你的 Post Type 生成的连接默认为/archives/movie
如果设置该项为false
即可去掉前面的/archives/
直接基于根路径生成固定连接。
how to retrieve their content from the database,
single-{post_type}.php – for single posts of a custom post type
archive-{post_type}.php – for the archive
how to render them to the public.
参考1:https://blog.csdn.net/youcijibi/article/details/78490500
参考2:https://blog.wpjam.com/article/wordpress-post-type/