文本是《實例講解 WordPress 自定義文章類型(共2篇)》專題的第 2 篇。閱讀本文前,建議先閱讀前面的文章:
在上篇《WordPress 自定義文章類型 介紹及實例解說(上)》,我們已經(jīng)介紹了如何創(chuàng)建自定義文章類型,接下來將更進一步地解說 自定義文章類型 這個強大的WordPress功能。
請下載本文演示的文件:http://www.ydqwiac.cn/img/2013/03/Movie-Reviews.1.zip
本教程將介紹如何為自定義文章類型創(chuàng)建自定義分類法(custom taxonomies)、管理列(admin columns)、過濾器(taxonomy filters)和存檔頁(archive page)。讓我們開始吧!
自定義文章類型的自定義分類法(Custom Taxonomy for Custom Post Types)
分類對于我們歸類和查找文章都十分有用。在 WordPress 中,我們通常使用 分類(Categories)和標(biāo)簽(Tags)作為分類方法。下面將介紹如何一步步為你的自定義文章類型創(chuàng)建自定義分類法。
步驟1:注冊自定義函數(shù)
打開上一篇文章中創(chuàng)建的插件,打開例子中的 Movie-Reviews.php ,將下面的代碼添加到 最后一個 ?> 的前面:
add_action( 'init', 'create_my_taxonomies', 0 );
步驟2:完善自定義功能和注冊自定義分類法
function create_my_taxonomies() {
register_taxonomy(
'movie_reviews_movie_genre',
'movie_reviews',
array(
'labels' => array(
'name' => 'Movie Genre',
'add_new_item' => 'Add New Movie Genre',
'new_item_name' => "New Movie Type Genre"
),
'show_ui' => true,
'show_tagcloud' => false,
'hierarchical' => true
)
);
}
在這里, register_taxonomy 函數(shù)為“movie_reviews”這個自定義文章類型創(chuàng)建了一個名為 “movie_reviews_movie_genre”的 自定義分類法【在這個例子中,是一個分類(in our case a category)】。標(biāo)簽定義的分類管理部分使用不同的字符串。
'show_ui' => true用于在儀表盤中,使分類編輯器可見。'show_tagcloud' => false控制是否顯示標(biāo)簽云。在我們的例子中,它是禁用的。'hierarchical' => true控制自定義分類法的格式。
提示:
'hierarchical' => false是指將分類(categories)轉(zhuǎn)化成標(biāo)簽(tags)。
步驟3:顯示自定義分類法
保存 Movie-Reviews.php 文件后,打開我們的自定義模板文件,也即是我們例子中的 single-movie_reviews.php,然后將下面的代碼添加到 21 行的下面:
<strong>Genre: </strong>
<?php
the_terms( $post->ID, 'movie_reviews_movie_genre' , ' ' );
?>
添加后,single-movie_reviews.php 最終的代碼應(yīng)該是這樣的:
<?php
/*Template Name: New Template
*/
get_header(); ?>
<div id="primary">
<div id="content" role="main">
<?php $mypost = array( 'post_type' => 'movie_reviews', );
$loop = new WP_Query( $mypost ); ?>
<!-- Cycle through all posts -->
<?php while ( $loop->have_posts() ) : $loop->the_post();?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<!-- Display featured image in top-aligned floating div -->
<div style="float: top; margin: 10px">
<?php the_post_thumbnail( array( 100, 100 ) ); ?>
</div>
<!-- Display Title and Author Name -->
<strong>Title: </strong><?php the_title(); ?><br />
<strong>Director: </strong>
<?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?>
<br />
<strong>Genre: </strong>
<?php
the_terms( $post->ID, 'movie_reviews_movie_genre' , ' ' );
?>
<br />
<!-- Display yellow stars based on rating -->
<strong>Rating: </strong>
<?php
$nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
if ( $star_counter <= $nb_stars ) {
echo '<img src="' . plugins_url( 'Movie-Reviews/images/icon.png' ) . '" />';
} else {
echo '<img src="' . plugins_url( 'Movie-Reviews/images/grey.png' ). '" />';
}
}
?>
</header>
<!-- Display movie review contents -->
<div class="entry-content">
<?php the_content(); ?>
</div>
<hr/>
</article>
<?php endwhile; ?>
</div>
</div>
<?php wp_reset_query(); ?>
<?php get_footer(); ?>
步驟4:結(jié)果
現(xiàn)在我們已經(jīng)成功添加了一個自定義分類法“Movie Genre”到“movie reviews”這個自定義文章類型了。我們可以在后臺添加分類和將分類分配到這自定義文章類型了。



顯示附加列(Displaying Additional Columns)
在 WordPress 自定義文章類型的后臺 文章列表 頁面,已經(jīng)包含了默認(rèn)的2個列 – 日期(Date)和評論(Comments),并且我們可以通過它們來排序文章了。如果你想添加更多的列,請按照下面的步驟進行。
步驟1:注冊函數(shù)
打開 Movie-Reviews.php 文件,在最后一個 ?> 的前面添加下面的代碼,用來注冊一個函數(shù),它會在你訪問文章列表頁面時被調(diào)用。
add_filter( 'manage_edit-movie_reviews_columns', 'my_columns' );
在這里,我們通過可變過濾器 manage_edit-(Custom_Post_Type)_columns,將自定義文章類型的 欄目列表(column list) 作為一個參數(shù)傳遞給函數(shù)。
步驟2:完善函數(shù)功能
function my_columns( $columns ) {
$columns['movie_reviews_director'] = 'Director';
$columns['movie_reviews_rating'] = 'Rating';
unset( $columns['comments'] );
return $columns;
}
我們在自定義文章類型的管理面板添加了2個列:Director 和 Rating,并且刪除了評論(Comments)這個列。
步驟3:填充列(Populating the Columns)
注冊一個函數(shù)來填充這些列
add_action( 'manage_posts_custom_column', 'populate_columns' );
步驟4:完善函數(shù)功能
function populate_columns( $column ) {
if ( 'movie_reviews_director' == $column ) {
$movie_director = esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) );
echo $movie_director;
}
elseif ( 'movie_reviews_rating' == $column ) {
$movie_rating = get_post_meta( get_the_ID(), 'movie_rating', true );
echo $movie_rating . ' stars';
}
}
在這里,由于任何自定義文章類型的列在呈現(xiàn)時,這寫函數(shù)都會被執(zhí)行,所以它會在執(zhí)行前,檢查當(dāng)前請求的列是否存在。我們已經(jīng)使用的 get_the_ID() 函數(shù)來檢索當(dāng)前行的索引,然后反過來使用 get_post_meta 檢索列(column)中的數(shù)據(jù)。
步驟5:注冊為可排序的列(Register Columns as Sortable)
現(xiàn)在讓我們來注冊一個函數(shù),它會在 WordPress 標(biāo)識排序的列時被調(diào)用。
add_filter( 'manage_edit-movie_reviews_sortable_columns', 'sort_me' );
步驟6:完善函數(shù)功能
function sort_me( $columns ) {
$columns['movie_reviews_director'] = 'movie_reviews_director';
$columns['movie_reviews_rating'] = 'movie_reviews_rating';
return $columns;
}
此功能可識別兩列讓他們排序,然后返回該數(shù)組。但是,我們的工作還沒有完成。
步驟7:按自定義字段排序(Order by Custom Field)
add_filter( 'request', 'column_ordering' );
add_filter( 'request', 'column_orderby' );
function column_orderby ( $vars ) {
if ( !is_admin() )
return $vars;
if ( isset( $vars['orderby'] ) && 'movie_reviews_director' == $vars['orderby'] ) {
$vars = array_merge( $vars, array( 'meta_key' => 'movie_director', 'orderby' => 'meta_value' ) );
}
elseif ( isset( $vars['orderby'] ) && 'movie_reviews_rating' == $vars['orderby'] ) {
$vars = array_merge( $vars, array( 'meta_key' => 'movie_rating', 'orderby' => 'meta_value_num' ) );
}
return $vars;
}
上述函數(shù)是根據(jù)查詢的URL中的變量,關(guān)聯(lián)過濾器和添加一些元素添加到查詢數(shù)組中。其實WordPress不知道改如何通過“Movie Director”和“Movie Rating”來排序,所以我們需要通過這個函數(shù)來告訴它。
我們已經(jīng)成功地增加了兩個可排序的列到管理面板中:

使用自定義分類法創(chuàng)建過濾器(Creating Filters With Custom Taxonomy)
下來,我們將演示如何使用 自定義分類法【custom taxonomies(在例子中,指分類 categories)】添加一個額外的過濾器到 WordPress后臺 的自定義文章類型 的列表頁面,這樣一來,管理員就可以顯示 屬于某個特定類別 的 自定義文章類型 元素。
步驟1:注冊函數(shù)
打開 Movie-Reviews.php 文件,在最后一個 ?> 的前面添加下面的代碼注冊一個函數(shù),這個函數(shù)將在點擊 WordPress 過濾器下拉列表的時候被調(diào)用。
add_action( 'restrict_manage_posts', 'my_filter_list' );
步驟2:完善函數(shù)功能
function my_filter_list() {
$screen = get_current_screen();
global $wp_query;
if ( $screen->post_type == 'movie_reviews' ) {
wp_dropdown_categories( array(
'show_option_all' => 'Show All Movie Genres',
'taxonomy' => 'movie_reviews_movie_genre',
'name' => 'movie_reviews_movie_genre',
'orderby' => 'name',
'selected' => ( isset( $wp_query->query['movie_reviews_movie_genre'] ) ? $wp_query->query['movie_reviews_movie_genre'] : '' ),
'hierarchical' => false,
'depth' => 3,
'show_count' => false,
'hide_empty' => true,
) );
}
}
在這里,我們使用了一個全局變量檢測當(dāng)前顯示的文章類型,還使用了一個文章查詢變量檢查是否已經(jīng)存在一個現(xiàn)有的過濾器和相應(yīng)地設(shè)置過濾器。函數(shù) wp_dropdown_categories 是用來顯示所有使用“Movie Genres”注冊的分類法。‘orderby‘, ‘show_count‘, ‘hide_empty‘, ‘depth‘ etc. 分別表示“按照不同的參數(shù)排序”“顯示每個分類的文章數(shù)”“隱藏不相關(guān)的分類”“要顯示的最大深度”來分別分類的。
步驟3:顯示過濾后的結(jié)果
現(xiàn)在的過濾器下拉列表已準(zhǔn)備好,我們會寫一些代碼來顯示過濾后的結(jié)果。繼續(xù)添加代碼注冊一個函數(shù)
add_filter( 'parse_query','perform_filtering' );
步驟4:完善函數(shù)功能
function perform_filtering( $query ) {
$qv = &$query->query_vars;
if ( ( $qv['movie_reviews_movie_genre'] ) && is_numeric( $qv['movie_reviews_movie_genre'] ) ) {
$term = get_term_by( 'id', $qv['movie_reviews_movie_genre'], 'movie_reviews_movie_genre' );
$qv['movie_reviews_movie_genre'] = $term->slug;
}
}
perform_filtering 函數(shù)會接收當(dāng)前的 WordPress 文章查詢對象,然后開始按照一個方向查詢保存在這些查詢對象中的變量。接著,它會驗證一個 電影類型(Movie Genre) 是否是這個查詢變量中的一部分,如果是,執(zhí)行查詢。
現(xiàn)在,你將可以使用過濾器來顯示指定類型的電影:

創(chuàng)建一個存檔頁(Create an Archive Page)
我們已經(jīng)為 自定義文章類型 創(chuàng)建了一個自定義模板,我們還可以創(chuàng)建一個自定義的存檔頁面覆蓋默認(rèn)的存檔模板。
步驟1:添加一個回退到存檔模板(Adding a Fallback to the Archive Template)
打開 Movie-Reviews.php,找到 include_template_function 這個函數(shù),在11行下面添加如下代碼:
elseif ( is_archive() ) {
if ( $theme_file = locate_template( array ( 'archive-movie_reviews.php' ) ) ) {
$template_path = $theme_file;
} else { $template_path = plugin_dir_path( __FILE__ ) . '/archive-movie_reviews.php';
}
在使用默認(rèn)的存檔模板前,WordPress會搜索整個當(dāng)前的主題目錄來尋找一個存檔模板。這段代碼用來檢測用戶是否在主題目錄提供了一個存檔模板,如果沒有,就檢查插件目錄。
最后 include_template_function 這個函數(shù)的代碼應(yīng)該是這樣的:
function include_template_function( $template_path ) {
if ( get_post_type() == 'movie_reviews' ) {
if ( is_single() ) {
// checks if the file exists in the theme first,
// otherwise serve the file from the plugin
if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) ) {
$template_path = $theme_file;
} else {
$template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
}
}
elseif ( is_archive() ) {
if ( $theme_file = locate_template( array ( 'archive-movie_reviews.php' ) ) ) {
$template_path = $theme_file;
} else { $template_path = plugin_dir_path( __FILE__ ) . '/archive-movie_reviews.php';
}
}
}
return $template_path;
}
步驟2:創(chuàng)建存檔模板
保存剛才的文件,然后新建一個名為 archive-movie_reviews.php 的文件,添加下面的代碼:
<?php get_header(); ?>
<section id="primary">
<div id="content" role="main" style="width: 70%">
<?php if ( have_posts() ) : ?>
<header class="page-header">
<h1 class="page-title">Movie Reviews</h1>
</header>
<table>
<!-- Display table headers -->
<tr>
<th style="width: 200px"><strong>Title</strong></th>
<th><strong>Director</strong></th>
</tr>
<!-- Start the Loop -->
<?php while ( have_posts() ) : the_post(); ?>
<!-- Display review title and author -->
<tr>
<td><a href="<?php the_permalink(); ?>">
<?php the_title(); ?></a></td>
<td><?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?></td>
</tr>
<?php endwhile; ?>
<!-- Display page navigation -->
</table>
<?php global $wp_query;
if ( isset( $wp_query->max_num_pages ) && $wp_query->max_num_pages > 1 ) { ?>
<nav id="<?php echo $nav_id; ?>">
<div class="nav-previous"><?php next_posts_link( '<span class="meta-nav">←</span> Older reviews'); ?></div>
<div class="nav-next"><?php previous_posts_link( 'Newer reviews <span class= "meta-nav">→</span>' ); ?></div>
</nav>
<?php };
endif; ?>
</div>
</section>
<br /><br />
<?php get_footer(); ?>
在這里,我們使用了一個循環(huán)(loop)來獲取所有的文章,然后使用一個表格來顯示他們。我們還定義了一個導(dǎo)航菜單(a navigation menu),如果這里的一個頁面的文章數(shù)量超過了后臺設(shè)置的最大顯示數(shù)量,就會通過 next_post_links 和 previous_post_links 函數(shù)顯示導(dǎo)航。
我們使用了全局的 wp_query 對象,其中包含有關(guān)當(dāng)前執(zhí)行的查詢的數(shù)據(jù),以便提供頁面內(nèi)容。 函數(shù) get_post_meta 用來獲取自定義字段數(shù)據(jù)。
步驟3:結(jié)果
保存該文件,并查看 Movie Reviews 的存檔列表頁。

教程到這里就要結(jié)束了。我希望你已經(jīng)能夠掌握 自定義文章類型 的重點。還有更多的細(xì)節(jié)等你去發(fā)掘!
感謝你的閱讀,隨時歡迎你的反饋。
原文:http://wp.tutsplus.com/tutorials/plugins/a-guide-to-wordpress-custom-post-types-taxonomies-admin-columns-filters-and-archives/
編譯:倡萌@WordPress大學(xué) – wpdaxue.com(稍有改動)
后話:硬著頭皮翻譯下來,感覺很生澀,又是 2 個小時的煎熬,請原諒我苦逼的英文水平吧。有能力的直接看英文吧。





倡萌大神,請教個問題:我用WP做了個電影站,其中“主演”這個是用的自定義字段,我這樣輸出:主演: ID, ‘actor’,”,’ ) ; ? > 后臺添加,前臺也能顯示,但問題是“順序”都亂了,比如說,主演一般都是重要角色排在前面,結(jié)果顯示可能在后面,也就是說原本應(yīng)該是 A B C ,結(jié)果有可能是C B A ,求教,那一行代碼該如何改動呢?拜求回復(fù) ??
非常感謝倡萌的翻譯,已用上,很不錯,不過有個問題,用這種方式的自定義文章,只要閱讀設(shè)置中的博客頁面至多顯示這一項的設(shè)置大于預(yù)設(shè)值,翻頁會出錯,請問有什么方案嗎?
謝謝倡萌的翻譯!
請教一個問題,自定義文章類型里怎么實現(xiàn)添加自定義欄目?
求分頁函數(shù)功能