參考: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/