wordpress进阶教程(三):创建自定义分类法

前面刚建了给wordpress创建新的文章类型函数:register_post_type()该函数还有个taxonomies参数,用来给自定义文章类型添加分类法制止,给wordpress添加默认的分类和标签支持方法很简单,只需要在创建文章类型的时候设置taxonomies参数如下:

  1. 'taxonomies'=> array('category','post_tag'),  

效果如图:

自定义文章类型添加分类支持

然后这在实际中的用法很少,一般情况下我们使用新的分类法,比如我们要做一个企业站,给产品做了一个新的文章类型product。我们要给产品归类,可以按类别分,比如电脑、手机。还可以按产地分,比如:国产山寨、水货,还可以按价格区间分,比如:1000元以下、1000到3000,等等,我们就需要同时有3个分类法:类别、产地、价格区间。

本部分教程的第一篇中我们也提到了,在wp-includes/post.php文件中wordpress使用register_taxonomy函数创建了分类-category和标签-post_tag两个分类法。

下面是register_taxonomy函数的参数好用法:

  1. <?php   
  2. register_taxonomy($taxonomy$object_type$args);   
  3. //$taxonomy 字符串型,必需,分类法的名称,用英文哦   
  4. //$object_type 数组或字符串,必需,分类法所对应的文章类型   
  5. //$args--可选,配置参数   
  6. ?>   

$args参数是个数组,跟register_post_type函数的$args参数类似,详细:
label-
labels-数组:

  • 'name'
  • 'singular_name'
  • 'search_items'
  • 'popular_items'
  • 'all_items'
  • 'parent_item'
  • ....略

public-
show_in_nav_menus-是否在菜单设置页面显示
....略,参考register_post_type函数

实例,在前面的一篇文章中,我们新建了一个book文章类型,下面我们为这个book文章类型添加一个国家-country分类法支持,完整代码如下(保留了上面添加的分类和标签支持):

  1. <?php   
  2. add_action('init', 'my_custom_init');   
  3. function my_custom_init()    
  4. {   
  5.   $labels = array(   
  6.     'name' => '书本name',   
  7.     'singular_name' => '书本singularname',   
  8.     'add_new' => 'Add_new',   
  9.     'add_new_item' => 'add_new_item',   
  10.     'edit_item' => 'edit_item',   
  11.     'new_item' => 'new_item',   
  12.     'view_item' => 'view_item',   
  13.     'search_items' => 'search_items',   
  14.     'not_found' =>  'not_found',   
  15.     'not_found_in_trash' => 'not_found_in_trash',    
  16.     'parent_item_colon' => '',   
  17.     'menu_name' => 'menu_name'   
  18.   
  19.   );   
  20.   $args = array(   
  21.     'labels' => $labels,   
  22.     'description'=> '嘿,这是一个自定义的文章类型',   
  23.     'public' => true,
  24.     'publicly_queryable' => true,   
  25.     'show_ui' => true,    
  26.     'show_in_menu' => true,    
  27.     'query_var' => true,   
  28.     'rewrite' => true,   
  29.     'capability_type' => 'post',   
  30.     'has_archive' => true,    
  31.     'hierarchical' => false,   
  32.     'menu_position' => null,   
  33.     'taxonomies'=> array('category','post_tag'),   
  34.     'supports' => array('title','editor','author','thumbnail','excerpt','comments')   
  35.   );    
  36.   register_post_type('book',$args);   
  37.      
  38.   $labels = array(   
  39.         'name' => '国籍',    
  40.         'singular_name' => 'country',   
  41.         'search_items' =>  '搜索' ,   
  42.         'popular_items' => '热门' ,   
  43.         'all_items' => '所有' ,   
  44.         'parent_item' => null,   
  45.         'parent_item_colon' => null,   
  46.         'edit_item' => '编辑' ,    
  47.         'update_item' => '更新' ,   
  48.         'add_new_item' => '添加' ,   
  49.         'new_item_name' => '国籍名称',   
  50.         'separate_items_with_commas' => '按逗号分开' ,   
  51.         'add_or_remove_items' => '添加或删除',   
  52.         'choose_from_most_used' => '从经常使用的类型中选择',   
  53.         'menu_name' => '国籍分类',   
  54.     );    
  55.   
  56.     register_taxonomy(   
  57.         'country',   
  58.         array('book'),   
  59.         array(   
  60.             'hierarchical' => true,   
  61.             'labels' => $labels,   
  62.             'show_ui' => true,   
  63.             'query_var' => true,   
  64.             'rewrite' => array( 'slug' => 'country' ),   
  65.         )   
  66.     );   
  67. }   
  68. ?>  

添加国籍分类法

 

更新--前台使用方法

文章类型归档模板:如果你需要一个现实所有该文章类型的模板,请在后台新建一个archive-{post_type}.php,比如上面的book类型,新建archive-book.php,用这个模板文件默认可显示所有book类型的文章。

分类模板:taxonomy-{taxonomy_slug}.php-这是自定义分类法的分类页,比如上面代码中我们新建了一个分类法country,使用taxonomy-country.php文件,就是这个分类法的分类页面了。

代码获取分类:对于默认的分类,我们可以使用get_categories()函数来获取分类,对于自定义分类法,这个函数同样适用,只是注意taxonomy 参数。

通过ID获取分类连接:默认分类我们通过分类ID获取分类链接是使用函数:get_category_link()。但是自定义分类法我们应该使用get_term_link()函数,函数用法这里就不说了,请看官自己到官网查看。

已有59条评论

  1. wp小白
    wp小白 : 回复

    树哥你好,我默认文章内型新建了一个名为 n 的分类,现在就是文章页面包屑导航栏调用
    代码: the_terms( $term->ID, ‘n’, false, ‘ > ‘ ); 现在可以输出显示,但它的顺序是子分类 ->主分类,如何让它显示顺序为先主分类再子分类

    • 阿树工作室
      阿树工作室 回复wp小白: 回复

      给你一个范例,不过以products分类法为例:

      1. //范例分类法为products   
      2.   
      3. $output = ;   
      4.   
      5. $currentterm = get_queried_object(); //获取当前分类   
      6. $parent = $currentterm->parent; //当前分类的父分类ID   
      7.   
      8. /**下面循环获取父分类的父分类**/  
      9. while ( $parent ):   
      10.     $parents[] = $parent//将分类ID按顺序存储在 $parents数组   
      11.     $new_parent = get_term_by( ‘id’, $parent,’products’ );   
      12.     $parent = $new_parent->parent;   
      13. endwhile;   
      14.   
      15. /**下面把$parents里面的分类循环输出**/  
      16. if ( !emptyempty$parents ) ):   
      17.     $parents = array_reverse$parents ); //将数组里面的顺序倒一下   
      18.     foreach ( $parents as $parent ):   
      19.         $item = get_term_by( ‘id’, $parent,’products’ );   
      20.         $output .= ‘<a href=“‘.get_term_link((int)$item->term_id,’products’).'”>’.$item->name.'</a>’.$delimiter;   
      21.     endforeach;   
      22. endif;   
      23. $output .= ‘<span class=“t”>’.$currentterm->name .'</span>’;   
      24. echo $output;  
  2. Mickee
    Mickee : 回复

    你好,我想让这个分类法在写文章时,以下拉菜单的形式显示,怎么做?

    • 阿树工作室
      阿树工作室 回复Mickee: 回复

      分类选择是个多选项,下拉是单选,所以wp默认是复选框。如果要改成下拉菜单,没有尝试过。

  3. evy
    evy : 回复

    非常感谢博主的回复,没想到那么快就回我,真是太感激了。我重新保存了一下固定链接 就好了。谢谢博主

  4. evy
    evy : 回复

    这篇文章写的好详细,感谢博主分享。可是看了一下啊日期已经比较早,不知道博主现在还会不会回复。这里有个问题在网上搜了很久没找到解决办法,想请教一下博主。
    我新创建了一个产品类型 register_post_type( ‘product’, $args );然后又创建了一个产品分类register_taxonomy( ‘p_type’, ‘product’, $args );
    在后端都显示很好,我同时创建了taxonomy-p_type.php文件,还有我具体的产品类型例如衣服cloth
    taxonomy-p_type-cloth.php ,可以当我点击get_term_link(get_term_by(‘name’, ‘衣服’, ‘p_type’));这个链接是,总是显示的是Index.php页面,在分类里面预览也是到index.php。 我又重新创建了archive-p_type.php 也没有调用。 请问博主能不能帮忙分析一下呢?不胜感激。

    • 阿树工作室
      阿树工作室 回复evy: 回复

      安装 custom_post_type_permalink 这个插件试试,然后重新设置一下固定链接

  5. Jim
    Jim : 回复

    怎样在首页输出自定义分类下的文章 求大神赐码

    • 阿树工作室
      阿树工作室 回复Jim: 回复

      不明白你要的,不过你可以试试这里,http://www.treework.cn/wpquery/,虽然不完善,应该能给你带点思路

  6. han
    han : 回复

    请问如何控制分类排序呢

  7. han
    han : 回复

    你好。请问 ,分类完成后如何排序。比如美国,中国,日本,如何按照喜欢的顺序排序。

    • 私奔
      私奔 回复han: 回复

      同问

      • 阿树工作室
        阿树工作室 回复私奔: 回复

        你可以安装一个叫worderbypress的插件,,那个插件可以拖拽排序

  8. 托小尼
    托小尼 : 回复

    大神可以不可以给个案例包学习下

  9. 阿树工作室
    阿树工作室 : 回复

    我觉得应该是不能

  10. notsame
    notsame : 回复

    single页面想调用自定义分类下的一个属性,比如 中国的描述,可以实现吗?

  11. 西木
    西木 : 回复

    可以放一个前台读取后的截图么?谢谢了

    • 阿树工作室
      阿树工作室 回复西木: 回复

      你现在所在的教程页面,在本站后台就是一个“教程”文章类型

  12. Electronic Cigarette Wholesale

    感谢树哥

  13. JIMMY
    JIMMY : 回复

    真的很感激有这么专业的分享平台,有一问题:

    加了一个新的文章分类后,里面的类别内容还是WORDPRESS系统自带的那个文章分类列表,怎么办?要删除这些么?

    • 阿树工作室
      阿树工作室 回复JIMMY: 回复

      不可能的吧。。。

      • JIMMY
        JIMMY 回复阿树工作室: 回复

        真的,有图有真相

        • 阿树工作室
          阿树工作室 回复JIMMY: 回复

          这个啊。。如果你新建了文章类型,建议不要使用默认的文章分类,也就是在注册文章类型的函数register_post_type的参数里面有个‘taxonomies’=> array(‘category’,’post_tag’),将这个去掉就行了….

  14. sunset
    sunset : 回复

    树哥   又来请教你问题了……

    function codex_custom_init() {
    		$args = array( 'public' => true, 'label' => '首页管理','supports' => array( 'title', 'editor',  'thumbnail', 'excerpt' ) );
    		register_post_type( 'adv', $args );
    	}
    	add_action( 'init', 'codex_custom_init' );

    这是添加首页管理的菜单

    register_taxonomy( 'adv_type', 'adv', array( 'hierarchical' => true	,
    		'label' => '栏目分类', 'query_var' => true, 'rewrite' => true ) );
    		wp_insert_category(array('cat_name' => '选项卡', 'category_description' => '选项卡广告',
       'category_nicename' => 'advTab', 'category_parent' => '','taxonomy' => 'adv_type'));	

    这是添加栏目分类,效果都已经达到了,但是我在function.php中用wp_insert_post方法添加一篇属于“选项卡”的文章就不成功,已经折腾了一天,请树哥

    指点一下。

    我的代码如下:

    function create_post(){
    	$my_post = array(
      	'post_title'    => '选项卡文章测试',
      	'post_content'  => '选项卡文章测试',
      	'post_status'   => 'publish',
    	'post_type' =>	'adv',
    	'tax_input' => array('taxonomy' => 'adv_type','cat_name' => '选项卡')
    	);
    	wp_insert_post( $my_post );
    	}
    	add_action( 'init', 'create_post' );

    这样,文章是添加在了首页管理下面,但是它不属于“选项卡”下面,请树哥指点一下。

    • 阿树工作室
      阿树工作室 回复sunset: 回复

      wp_insert_post函数参数中的tax_input不是这样用的。。。

      function create_post(){
      	$my_post = array(
        	'post_title'    => '选项卡文章测试',
        	'post_content'  => '选项卡文章测试',
        	'post_status'   => 'publish',
      	'post_type' =>	'adv',
      	'tax_input' => array('adv_type' =>array(1))  //里面的1即为分类ID
      	);
      	wp_insert_post( $my_post );
      	}
      	add_action( 'init', 'create_post' );
      • sunset
        sunset 回复阿树工作室: 回复

        树哥太给力了……  按照你说的  实现了效果……  送树哥一朵玫瑰

        • 阿树工作室
          阿树工作室 回复sunset: 回复

          本站有广告。。你懂的

  15. merri
    merri : 回复

    请问问什么我taxonomy-country.php文件,在后台点击创建分类的名称,比如美国,点击后出现404错误啊?

    • 阿树工作室
      阿树工作室 回复merri: 回复

      试试后台更新固定连接…

  16. 角落
    角落 : 回复

    自定义分类怎么通过分类名称取到ID?$cat_ID = get_cat_ID(‘cat_name’)这个函数取不到

    • 阿树工作室
      阿树工作室 回复角落: 回复

      要会自己分析啊。。。在wordpress官网搜索get_cat_ID函数http://codex.wordpress.org/Function_Reference/get_cat_ID,里面有指明get_cat_ID函数位于wp-includes/category.php文件:

      function get_cat_ID( $cat_name ) {
      	$cat = get_term_by( 'name', $cat_name, 'category' );
      	if ( $cat )
      		return $cat->term_id;
      	return 0;
      }

      可以看到get_cat_ID函数调用的是get_term_by(),那你换用get_term_by函数就行了。

  17. 小胡
    小胡 : 回复

    树哥,我想问下,如何才能把“分类目录”和“标签”这两项给删除掉呢?

    • 阿树工作室
      阿树工作室 回复小胡: 回复

      试试到源文件中删除,或者用css隐藏。。

  18. woodenboy
    woodenboy : 回复

    树哥,找到原因了,没有设置screen option。谢谢

  19. woodenboy
    woodenboy : 回复

    我使用show_in_nav_menus=> true 参数在本地调试是OK的,但是我上传到bluehost的服务器上后,该参数不起做用。请帮忙找一下原因呀。

    • 阿树工作室
      阿树工作室 回复woodenboy: 回复

      额。。这个问题。。我就真不知道了

      • woodenboy
        woodenboy 回复阿树工作室: 回复

        这个参数是不是对PHP的板本与配置文件有限制呀

        • 阿树工作室
          阿树工作室 回复woodenboy: 回复

          这个应该没有限制的。。

  20. iear
    iear : 回复

    自定义类型的文章,如何才能设置成为首页置顶呢?没有首页置顶这一项啊?

    • 阿树工作室
      阿树工作室 回复iear: 回复

      wordpress的置顶功能指对默认文章有效的。。

  21. MONAD
    MONAD : 回复

    啊树哥我有个问题像请教你,比如我新建了一个VIDEO模型,里面有100个栏目,能不能给VIDEO这个模型里面的所有栏目做一个封面,这个封面里面只调用VIDEO模型里面的栏目和文章,就像你的这个BOOK模型给它弄一封面只调用BOOK分类下面的栏目和文章,

    在一个就是首页怎么调用自定义分类的栏目和文章

    望阿树哥不吝赐教!!

    • 阿树工作室
      阿树工作室 回复MONAD: 回复

      虽然我不明白你具体说的目的,自定义文章类型也和普通文章一样使用query函数,在查询的时候加个参数就行,比如文章中我们有文章类型book、分类法country,然后在后台添加一个名为“天朝”的分类-ID为666 ,我要调用这个天朝分类里面的book文章,

      $args = array(
      	'post_type'=>'book', //文章类型
      	'showposts'=>'1',显示一篇文章
      	'tax_query'=>array(
      		array(
      			'taxonomy'=>'country', //分类法为type
      			'terms'=>666  //分类ID为666
      		)
      	),
      	'order'=>'ASC' //排序
      );
      query_posts( $args );

      然后使用循环输出即可

      • monad
        monad 回复阿树工作室: 回复

        不好意思、可能是我没说明白,

        我现在已经建立了三个自定义文章类型、视频、音乐、图片、三个文章类型里面分类都很多!

        默认的首页他是调用文章类型最新文章、并且加上函数可以实现CMS样式的首页。

        我想要的就是能不能给每个文章类型也做一个首页文件、比如给图片做一个HOME-img页面来调用图片类型里面的分类和文章以实现

        每个文章类型都有一个首页。

        不知道啊树哥知道我的大概意思了吗?

        • 阿树工作室
          阿树工作室 回复monad: 回复

          我提供的类文件里面,在配置的时候$boxinfo

          $boxinfo = array('title' => 'meta box', 'id'=>'ashubox', 'page'=>array('page','post'), 'context'=>'normal', 'priority'=>'low', 'callback'=>''); 

          参数里面有个’page’=>array(‘page’,’post’)加上文章类型即可。。

          如果要单独的,请单独配置一个

        • 阿树工作室
          阿树工作室 回复monad: 回复

          额。。就是文章类型的归档?文中:文章类型归档模板:如果你需要一个现实所有该文章类型的模板,请在后台新建一个archive-{post_type}.php,比如上面的book类型,新建archive-book.php,用这个模板文件默认可显示所有book类型的文章。

          也可以参考下面GSTAR的留言。。

          • monad
            monad 回复阿树工作室: 回复

            非常感谢啊树的耐心解答、我测试一下你说的这个看看!

            还有一个问题想问问你、我照你的添加自定义字段面板只能在默认的文章类型里面显示

            怎么可以让他显示到自定义的类型里面、或者怎么给自定义的类型单独设置面板!

  22. GSTAR
    GSTAR : 回复

    请问我新建了文章类型之后。也建了archive-{post_type}.php的模板文件。然后在页面选择了该模板文件。但是前台页面没有显示该文章类型的文章。如果想在已经建好的页面中(post_type=page)调用该自定义的文章类型。应该怎么做呢?

    • 阿树工作室
      阿树工作室 回复GSTAR: 回复

      不需要用模板文件的。。就好比普通的分类页面会调用category.php文件,文章类型的“所有文章归档”页会自动调用archive-{post_type}.php文件的。。。至于地址的话,你随便访问一篇文章,url会是:ashuwp.com/{post_type}/post_name这种类型。去掉url后面的post_name就是了。。。

      • GSTAR
        GSTAR 回复阿树工作室: 回复

        感谢阿树~

        另外我又遇到个问题……^^;劳烦高手再给看看。

        我现在页面导航有两个文章列表。

        Home | News(默认文章列表) | Book(自定义那个post_type=book)

        现在的问题是,当点击book的文章时导航高亮会跳到news

        我怎么让current_page_item还留在Book上?

      • GSTAR
        GSTAR 回复阿树工作室: 回复

        额,其实是我表述有问题,不过那个问题解决了。

        根据之前的教程我在functions.php文件include了一个post-type.php文件。因此后台多了个自定义的文章列表

        我新建了archive-book.php(头部做了注释Template Name: book),然后在页面Products(page_type=page)引用了book模板。

        archive-book.php里通过下面这个循环调用

        <?php $args = array( 'post_type' => 'book' );
        $loop = new WP_Query( $args );
        while ( $loop->have_posts() ) : $loop->the_post();?>...<?php endwhile;?>

        Products页面成功显示了book列表。

        • 阿树工作室
          阿树工作室 回复GSTAR: 回复

          你新建一个archive-book.php头部不需要注释的,也不需要到后台去添加页面的,模板里面也不需要在写一个query,跟普通分类一样就行。。。

          • GSTAR
            GSTAR 回复阿树工作室: 回复

            我是想定制一个简单的后台。不修改wordpress。完全在theme文件包里面的。最后我会把后台的菜单都删掉只留下自定义的。。。

            • 阿树工作室
              阿树工作室 回复GSTAR: 回复

              你这个想法太大胆了。。后台菜单可以隐藏一部分的。。。。

  23. 浩子文
    浩子文 : 回复

    这样设置为什么写出的文章是404

    • 阿树工作室
      阿树工作室 回复浩子文: 回复

      你指的是文章单页404吗,文章单页一般使用模板文件为:single-{post_type}.php 如果还404的话,建议你更新固定链接设置(不需要重新设置,更新就行)

  24. Jason
    Jason : 回复

    请问怎么在前台读取呢

    • 阿树工作室
      阿树工作室 回复Jason: 回复

      文章已更新。。谢谢。

发表评论