最近自己在修改一个采用Wordpress程序的博客的时候需要用到一个特殊的功能:我需要判断这篇文章是属于哪些分类,如果属于我设定的分类下的文章,则输出一个DIV内容。按道理说实现这个功能应该不算太难,因为印象中wordpress有相关的函数。简单查阅了一些资料后发现is_category和in_category这两个函数,最后是靠in_category函数实现的。具体方法也很简单:
in_category(array( ’1′, ’2′, ’3′)) ) 这段函数的意思是识别分类目录ID为1、2、3这三个分类,可以利用这个功能实现特定分类使用自定义模板或内容等。
这其中还有个小插曲让我纠结了很久,那就是in_category和is_category的差别,它们的差别让我想实现的功能差点就黄掉了。这里贴出来做个记录:
in_category:判断当前文章或指定文章是否属于某个指定类别,只有直属的类别,不包括直属类别的父辈类别;可以在循环内使用,也可以独立使用。
is_category:判断是否正在显示一个类别归档页面。
也就是说,如果你要在wordpress里面判断某个东西是否属于某分类,则用in_category,而如果是想判断某个分类的表现,那就要用is_category函数。
in_category() is often used to take different actions within the Loop depending on the current post's category, e.g.
<?php if ( in_category( 'pachyderms' )) { // They have long trunks... } elseif ( in_category( array( 'Tropical Birds', 'small-mammals' ) )) { // They are warm-blooded... } else { // & c. } ?>
During a request for an individual post (usually handled by the single.php template), you can test that post's categories even before the Loop is begun.
You could use this to switch templates like so:
<?php if ( in_category('fruit') ) { include 'single-fruit.php'; } elseif ( in_category('vegetables') ) { include 'single-vegetables.php'; } else { // Continue with normal Loop if ( have_posts() ) : while ( have_posts() ) : the_post(); // ... } ?>
(The Custom Post Templates Plugin allows for creation of templates for single posts. It also shows an example of how to add a template which is used for all posts in a given category, not just a single post. That example is commented out in the plugin by default but can be easily implemented by uncommenting the appropriate lines.)
When showing a category archive, or showing a category's posts via WP_Query() or get_posts(), or when hooking into the main query using is_main_query(), WordPress retrieves posts from the specified category and any descendant (child) categories, but in_category() tests only against a post's assigned categories, not ancestors (parents) of those categories.
For example, if you have a post assigned to the subcategory Fruit → Bananas and not the category Fruit, the Fruit category archive will show the "Bananas" post, but callingin_category('fruit')
for that post always returns false.
You can list both the ancestor category and every possible descendant category, e.g.,
<?php if ( in_category( array( 'fruits', 'apples', 'bananas', 'cantaloupes', 'guavas', /*etc*/ ) )) { // These are all fruits } ?>
but you'd have to edit the code every time you moved or added any of the "Fruit" categories.
A more-flexible method is to use or adapt the post_is_in_descendant_category function defined below (you need to copy the function definition below into a template, plugin, or theme functions file before calling it). You can use it together with in_category() like this (in this example 11 is the "Fruit" category's ID number):
// Post is assigned to "fruit" category or any descendant of "fruit" category? <?php if ( in_category( 'fruit' ) || post_is_in_descendant_category( 11 ) ) { // These are all fruits… } ?>
If you'd rather refer to the category by name you can use, e.g.,
if ( $category_to_check = get_term_by( 'name', 'fruit', 'category' )) post_is_in_descendant_category($category_to_check->term_id);
<?php /** * Tests if any of a post's assigned categories are descendants of target categories * * @param int|array $cats The target categories. Integer ID or array of integer IDs * @param int|object $_post The post. Omit to test the current post in the Loop or main query * @return bool True if at least 1 of the post's categories is a descendant of any of the target categories * @see get_term_by() You can get a category by name or slug, then pass ID to this function * @uses get_term_children() Passes $cats * @uses in_category() Passes $_post (can be empty) * @version 2.7 * @link http://codex.wordpress.org/Function_Reference/in_category#Testing_if_a_post_is_in_a_descendant_category */ if ( ! function_exists( 'post_is_in_descendant_category' ) ) { function post_is_in_descendant_category( $cats, $_post = null ) { foreach ( (array) $cats as $cat ) { // get_term_children() accepts integer ID only $descendants = get_term_children( (int) $cat, 'category' ); if ( $descendants && in_category( $descendants, $_post ) ) return true; } return false; } } ?>