WordPress的自定义文章类型(Custom Post Type)允许我们创建一种有别于blog posts但又能分组管理的文章类型,Custom Post Type在属性上更接近于Page,而非Post,它们的固定链接(Permalink)也不受制于后台-设置-固定
链接中为Post规定的链接格式。
目录
如何注册自定义文章类型
假设我们要注册名为Books
的文章类型,放写书籍杂志的信息。目标如下图所示:
方法一:用代码
注册自定义文章类型用到的函数是register_post_type,可以套用官方文档的代码示例,将下面的代码放到主题的functions.php
中。
add_action( 'init', 'sola_register_cpt_book' );
function sola_register_cpt_book() {
$labels = array(
'name' => _x('Books', 'post type general name'),
'singular_name' => _x('Book', 'post type singular name'),
'add_new' => _x('Add New', 'book'),
'add_new_item' => __('Add New Book'),
'edit_item' => __('Edit Book'),
'new_item' => __('New Book'),
'all_items' => __('All Books'),
'view_item' => __('View Book'),
'search_items' => __('Search Books'),
'not_found' => __('No books found'),
'not_found_in_trash' => __('No books found in Trash'),
'parent_item_colon' => '',
'menu_name' => 'Books'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
);
register_post_type('book',$args);
}
方法二:代码生成器
WordPress里标准化的东西基本都有代码生成器,刻意记住是没必要的,知道原理,合理利用代码生成器。比如,生成Custom Post Type可以用 – Generate WordPress Post Type。
默认的格式是什么样的
自定义文章类型默认的固定链接格式是post-slug/postname
,若不指定slug,则用post type作为slug,本例中没有指定,所有post slug就是book。与固定链接相关的参数有rewrite
和slug
。下面重点讲以下rewrite
参数。
rewrite
为true – 使用SEO有友好的链接格式。假设创建了一个book类型的文章,标题是“Harry Potter Book”,产生的链接如下:
http://mydomain.com/?post_type=book&p=3
这是最原始的格式,使用了数据库wp_post表里的ID,所以我们将rewrite设为false,去掉参数,且SEO友好。
http://mydomain.com/book/harry-potter-book
这里要注意结尾的反斜杠,结尾是否有反斜杠,取决于设置-固定链接
中的格式结尾是否有反斜杠,建议这里结尾不要带反斜杠,否则可能出现http://mydomain.com/book/harry-potter-book
与http://mydomain.com/book/harry-potter-book/
指向同一个地址的情况,对搜索引擎不友好。
怎样改成自己想要的格式
依然以book类型为例,当标题是中文时,默认的链接也是中文,url的会变得很长,分享不方便。不想手动输入英文slug,那就修改固定连接的格式,使用ID。例如,让http://mydomain.com/book/harry-potter-book
变成http://mydomain.com/book/33.html
。要达到这个目的:
- 创建新的rewrite规则翻译URL
- 用filter
post_type_link
返回我们想要的地址。
下面有两段代码,都可以实现这个要求,代码加到functions.php中,并且要到后台-设置-固定链接
中重新保存固定链接,代码才能生效。
方法一
/**
* 添加book类型的rewrite rule
*/
add_action( 'init', 'sola_custom_book_rewrite' );
function sola_custom_book_rewrite() {
global $wp_rewrite;
$queryarg = 'post_type=book&p=';
$wp_rewrite->add_rewrite_tag('%qid%', '([^/]+)', $queryarg);
$wp_rewrite->add_permastruct('book', '/book/%qid%.html', false);
}
/**
* 修改book类型的固定连接格式
*/
add_filter( 'post_type_link', 'sola_custom_book_permalink', 1, 3 );
function sola_custom_book_permalink( $post_link, $post ) {
global $wp_rewrite;
if ( $post->post_type == 'book' ){
$post = get_post();
if ( is_wp_error( $post ) ){
return $post;
}
$newlink = $wp_rewrite->get_extra_permastruct('book');
$newlink = str_replace("%qid%", $post->ID, $newlink);
$newlink = home_url(user_trailingslashit($newlink));
return $newlink;
}
return $post_link;
}
方法二
/**
* 注册rewrite rule
*/
add_action( 'init', 'sola_custom_book_rewrites_init' );
function sola_custom_book_rewrites_init(){
add_rewrite_rule(
'book/([0-9]+)?.html$',
'index.php?post_type=book&p=$matches[1]',
'top'
);
}
/**
* 修改链接格式
*/
add_filter('post_type_link', 'sola_custom_book_link', 1, 3);
function sola_custom_book_link( $link, $post ){
if ( $post->post_type == 'book' ){
return home_url( 'book/' . $post->ID .'.html' );
} else {
return $link;
}
}
效果如下图所示
Hi Sola,
想请教下针对多个Custom Post Type 如何更改结构为http://mydomain.com/slug1/postname.html?
用Custom Post Type Permalinks插件试过吗?要是不行就按照上面的代码改改吧,主要是修改正则。
Hi Sola,
我发现这种写法如果是配合多语言插件WPML使用,添加的文章链接没有多语言变化
如果你要自己写代码来改链接格式,必须连多语言的一起写进去,自定义代码wpml是照顾不到的。
你好问一下有没有办法把wordpress的文章内容分页后出现xxx.html/1 的这种情况改成xxx_1.html这样的形式呢,现在使用自定的/archives/%post_id%.html
我写了一种方法,是修改成xxx/page-1.html的,因为xxx_1容易和正常的url slug冲突,希望对你有用。
https://www.solagirl.net/permalink-with-html-suffix.html
用了Custom Post Type Permalinks后,对于bbpress论坛的帖子,电脑访问没有问题,手机访问就404,能解决么
抱歉,bbpress很久没接触了,不清楚,是不是论坛有手机版,访问链接和pc的不一样?去bbpress论坛问问吧。
标签url怎么自定义?
比如:/tag/xxx 改成 /s-tag/xxx
求教博主。/%postname%.html这种固定链接怎么处理?
能再说的详细点吗?
加我Q详细跟你说下。谢过。
抱歉,我不用qq。
这样的。就是我想把新注册的文章类型的固定链接用/&postname%.html这种形式的。而不是你教程中的/%post_id%.html形式的,那上面那段规则代码该怎么整?我不懂规则不知道怎么改,楼主要是知道的话还请给我贴一段详细代码
用插件最好,这段代码评论分页时会出问题,custom post type permalink插件可以实现你的需求
用了这个插件。导致taxonomy.php模版不能正常调用。而且链接变得好长,里面abc.com/post_type/分类/这样的形式而且模版不能正常调用。
这个插件不涉及模板的东西,如果你的模板无法调用,可能是写的有问题最好检查一下。
好吧。那你那段代码postname形式的怎么写?我现在暂时还不想用插件
$post里有title,你打印这个数组看看。把$post->ID都替换成title,当然title要处理成url可用的。我现在不方便写代码,大概意思就这样。
谢了
博主,之前按你说的写了不行,我不会重写,估计是出问题了。现在还是用着插件。。博主要是有空还是麻烦写一段自定义文章类型用/%postname%.html的吧
博主,你的文章对我启发很大。
关于register_post_type,我有个问题,hierarchical这个参数是干什么用的?我改成true似乎没有任何变化。
hierachical为true,表示这个post type可以有父子关系,就像page那样,如果你的support参数里有 page-attributes,那编辑页面就会显示Parent选项,就是page里选择parent page那个下拉菜单。
Hi,
請教一下, 我用了Custom Post Type Permalinks, 當我轉URL格式, 我也試過將它分類及不分類,
依然都是 404問題, 請問知道甚麼原因嗎?
我不太明白你的意思,将他分类及不分类是指哪个选项?
另外,修改设置后,保存两次试试。
确实很强大,但如果做成插件的话,就更强大了。
有现成的插件,custom post type permalink
方法1试过没用,方法2固定链接那里如果选择默认,打不开链接。必须要随便设置个链接格式才行,怎么回事呢,请问
这篇文章很久没更新过了,代码比较旧,好不好用我最近也没试验过。建议你直接装custom post type permalink插件,这些功能都能实现,省心。
楼主,这个代码无法评论啊,用户评论之后就出错啊,麻烦看看哈
貌似这问题你问了好几遍了,首先,不是所有的custom post type都需要评论功能,其次,用插件的话更省事,比如这个http://wordpress.org/plugins/custom-post-type-permalinks/
使用插件Custom Post Type Permalinks,简单,明了
http://wordpress.org/plugins/custom-post-type-permalinks/
这个是我经常用的插件之一,还有custom permalinks。不过对我来说弄懂原理也是很重要的事。
Sola你好,不知道为什么,我在本地调试,完全按照你的方法来弄,打开页面永远都是404啊。。。
链接是已经转换成想要的格式了,但是就是打不开。不知道是什么缘故?
解决了我的大问题
Nice~~
请问lz,使用文中提供的代码后,内容页只显示标题,不显示内容是什么问题呢??
内容显示是模板控制的,请问你用来显示custom post type的模板是怎么写的?the_content()输出了什么?更改固定链接格式通常情况下不会影响内容,最多是404错误,建议用默认主题测试一下。
你好,怎么给它添加分类和标签呢?
在注册custom post type的时候(即调用register_post_type()时)给taxonomies赋值即可,你可以参考这个例子
或者安装插件Custom content type manager,管理起来很方便
昨晚,试了下代码2,发觉可行。但是因为原来我用的固定链接是 /%year%%monthnum%%post_id%/ 这样的形式,为了统一,我把
return home_url( $mytypes[$post->post_type].’/’ . $post->ID .’.html’ );
} 里的 ‘.html’ 改成 ‘/’,但这样子就不行了,出现404错误。如何解决。
你用这段代码试一下,把book替换成你的custom post type
这样能OK了。果然高也。其实我也改过最后的代码,
add_rewrite_rule(
‘book/([0-9]+)?$’,
改成
add_rewrite_rule(
‘book/([0-9]+)?\/$’,
这样子,后面加个 /, 好象也符合规则啊,怎么会行不通?看来我对add_rewrite_rule还是不了解。
其实我和你一样,也试验过你说的方法,哈哈,我也不太清楚为啥那样不行。只是发现如果固定链接中最后有/,wordpress就会自动把所有不带/重定向到带/的,具体是什么原理我也没研究过
博主你能不能把后面这固定连接重写的弄个注释啊。。。我总共有三四种自定义文章类型。。。加三四段这个代码太笨了
那我建议你用插件Custom Post Type Permalinks
还有,就算用代码也不用写上三四遍,比如你可以这样写,只要把要更改地址的custom post type名称写到$mytypes数组中就行了
哎呀。。博主我爱死你了。。。我的自定义类型的链接老是中文。。。我百度了好久。。都没资料。。然后看了好久英文资料。。没看懂。。。然后谷歌搜索一下。。就让我找到了。。。。
哈哈,找技术资料还是用谷歌的好
请教博主,能不能推荐一个制作自定义文章类型的插件?
我一般都用register_post_type直接定义,插件没怎么用过。找了找,Custom Post Type UI这个插件基本上就是把register_post_type的参数UI化了,还可以。
只是中文翻译比较让人头大,不如直接看英文的
博主,你说的 WordPress Answers 网址是多少?
http://wordpress.stackexchange.com
英文的哦
THKS.
太棒了,正在找这个资料。试用的Custom Content Type Manager和Types这2个自定义文章类型的插件,都没提供多样化的固定链接。
我知道Custom Post Type Permalinks挺好用,支持各种格式的custom post type固定链接格式,我不想弄太多插件就用了代码,不过这个插件挺精简的。
这个这个,恕我没看懂。。 能解释下么。
有这个需求的时候就看懂了