一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

wordpress博客category page 404 错误解决办法 (url静态化)

时间:2016-10-28 编辑:简简单单 来源:一聚教程网

假期无事,又重新将自己的网站(第6小站)上线,放弃了原来的dokuwiki(优点:部署简单,无需数据库支持,ui简洁;缺点:文章管理逻辑奇特,需要手写markdown),然后自豪的采用wordpress,搞定主题,一阵改头换面之后,发现了一些美中不足的东西———丑陋的url,贴几个大家感受下:

sixther.me/?p=85             #特定文章的url,根据post_id查询
sixther.me/?m=201512         #查看特定日期的文章,根据date string查询
sixther.me/?category=15      #查看特定类别的文章,根据catetory_id查询
sixther.me/?tag=monitor      #查看特定标签的文章,根据tag_string查询
sixther.me/?author=1         #查看特定作者的文章,根据author_id查询
注:这些写法都省略了index.php,完整的写法应为:
https://sixther.me/index.php?author=1
url也属于UI的一部分,也应该做到简洁友好,至少也得让网络爬虫认识,第一步,先使用wordpress自带的固定链接设置将其静态化,这样设置完之后,上面的url变成了如下样子:
固定链接:https://sixther.me/%postname%.html

sixther.me/vim-template-for-python-file.html
sixther.me/2015/12
sixther.me/category/linux
sixther.me/tag/python
sixther.me/author/sixther
对,这应该是合理的,也应该是最终的目标,但这时候出现大问题了,所有的链接,包括文章,分类,日期,标签,作者都变成了404页面,不知道这一点算不算是wordpress的bug,固定链接的功能不应该就是这样的么,也或许跟版本有关系,第6小站用的是4.4的版本,也就是说,目前的网站不认识这些优雅的url,只认识上面那些丑陋的url,这种情况可以通过nginx来解决,细思一下,也不能完全解决,因为优雅的url里面都是name属性的东西,丑陋的url里都是id属性的东西,只有tag跟date可以用rewrite搞定,先加上再说:

rewrite ^/([0-9]+)/([0-9]+) /index.php?m=$1$2 last;
rewrite ^/tag/(.*) /index.php?tag=$1 last;
bingo!!
再来考虑剩下的几个,显然,解决办法有两个,一是找到index.php通过name查询结果的参数,另一个是让程序生成href的时候用id来生成,那只能去看wordpress代码了,最开始注意到了auth-template.php的文件里面有个get_author_posts_url函数:

function get_author_posts_url($author_id, $author_nicename = '') {
        global $wp_rewrite;
        $auth_ID = (int) $author_id;
        $link = $wp_rewrite->get_author_permastruct();
        if ( empty($link) ) {
                $file = home_url( '/' );
                $link = $file . '?author=' . $auth_ID;
        } else {
                if ( '' == $author_nicename ) {
                        $user = get_userdata($author_id);
                        if ( !empty($user->user_nicename) )
                                $author_nicename = $user->user_nicename;
                }
                $link = str_replace('%author%', $author_nicename, $link);
                //$link = str_replace('%author%', $author_id, $link);
                $link = home_url( user_trailingslashit( $link ) );
        }
        $link = apply_filters( 'author_link', $link, $author_id, $author_nicename );
        return $link;
}
注释那一行是我本来打算改的,后来事实证明这样可以将按照author id查询改好,可以看到,生成author_posts_url的方法就是将%author%替换为$author_nicename,有点mvc基础的同学都会明白%author%就是模版变量,那category,post应该也是这样做的吧,用"%category% && str_replace"的关键字搜索category-template.php文件,却并没有类似代码,真是搞不懂wordpress的代码逻辑,有机会一定得梳理下,第二种办法就追到这里没再下去了。
然后就是各种google了,基本关键字就是“wordpress api,wordpress category 404...”之类的,然后就发现了query.php的文件,打开文件的第一行就让我看到了解决问题的希望(是一行注释):

/**
 * WordPress Query API
 *
 * The query API attempts to get which part of WordPress the user is on. It
 * also provides functionality for getting URL query information.
 *
再往下看,犹如发现新大陆:

public function fill_query_vars($array) {
                $keys = array(
                        'error'
                        , 'm'
                        , 'p'
                        , 'post_parent'
                        , 'subpost'
                        , 'subpost_id'
                        , 'attachment'
                        , 'attachment_id'
                        , 'name'
                        , 'static'
                        , 'pagename'
                        , 'page_id'
                        , 'second'
                        , 'minute'
                        , 'hour'
                        , 'day'
                        , 'monthnum'
                        , 'year'
                        , 'w'
                        , 'category_name'
                        , 'tag'
                        , 'cat'
                        , 'tag_id'
                        , 'author'
                        , 'author_name'
                        , 'feed'
                        , 'tb'
                        , 'paged'
                        , 'comments_popup'
                        , 'meta_key'
                        , 'meta_value'
                        , 'preview'
                        , 's'
                        , 'sentence'
                        , 'title'
                        , 'fields'
                        , 'menu_order'
                );
套用琅琊榜里的一句话:“女人的感觉就是这么不讲道理”,此刻我的感觉也是百分百确认这些就是index.php支持的查询参数列表,没有再细看代码,直接修改nginx rewrite规则,没有修改哪怕是一行wordpress的代码,完整规则如下:

rewrite ^/(.*).html /index.php?name=$1 last;
rewrite ^/([0-9]+)/([0-9]+) /index.php?m=$1$2 last;
rewrite ^/tag/(.*) /index.php?tag=$1 last;
rewrite ^/page/([0-9]+) /index.php?paged=$1 last;
rewrite ^/author/(.*) /?author_name=$1 last;
rewrite ^/category/(.*) /?category_name=$1 last;
all bingo!!!
彩蛋:
查问题的过程中,发现了一个叫wp-json的东西,可以通过json查询相应内容,如果想开发wordpress的app,这个一定用的上。

热门栏目