遇到的問(wèn)題
在 WordPress WP_Query 參數(shù)中,有兩個(gè)參數(shù)用到了 MySQL 的 offset 語(yǔ)句,一個(gè)是 paged,一個(gè)是 offset,paged 是為了實(shí)現(xiàn)分頁(yè),offset 是為了跳過(guò)某些文章不顯示,如果這兩個(gè)同時(shí)出現(xiàn),會(huì)怎么樣呢?答案是,offset 可以用,分頁(yè)失效。
需要同時(shí)用到這兩個(gè)參數(shù)的情況很少,常見(jiàn)的一種情況是在索引(也就是 WordPress 中的分類(lèi)或標(biāo)簽存檔頁(yè)面)需要跳過(guò)前一篇或者幾篇文章不顯示,當(dāng)然,在索引頁(yè)面,分頁(yè)也是需要的。
解決辦法
要實(shí)現(xiàn)這種效果,我們就需要對(duì) WordPres 分頁(yè)功能動(dòng)一下手腳了,我們主要通過(guò)以下兩個(gè) WordPress 鉤子實(shí)現(xiàn)這個(gè)功能。
- pre_get_posts:在 WordPress 查詢(xún)?cè)试S之前,調(diào)整 WordPress 查詢(xún)參數(shù),在這里,我們需要用這個(gè)鉤子保證 offset 參數(shù)只應(yīng)用在第一頁(yè),
- found_posts:允許我們調(diào)整 WordPress 文章查詢(xún)結(jié)果總數(shù)量
第一步是使用 pre_get_posts 同時(shí)處理 offset 和分頁(yè),這個(gè)鉤子把WordPress查詢(xún)對(duì)象傳遞到自定義功能中,在自定義功能中,我們可以對(duì)查詢(xún)對(duì)象進(jìn)行修改。在下面的例子中,我們需要在WordPress 博客存檔頁(yè)面跳過(guò)前10篇文章。
add_action('pre_get_posts', 'myprefix_query_offset', 1 );
function myprefix_query_offset(&$query) {
//開(kāi)始之前,確定我們?cè)谡_的位置
if ( ! $query->is_posts_page ) {
return;
}
//首先,定義需要跳過(guò)的文章數(shù)量
$offset = 10;
//下一步,獲取設(shè)置中每頁(yè)現(xiàn)實(shí)文章的數(shù)量
$ppp = get_option('posts_per_page');
//下一步,檢測(cè)和處理分頁(yè)
if ( $query->is_paged ) {
//手動(dòng)確定查詢(xún)偏移量(偏移量 + 當(dāng)前頁(yè)數(shù) (減1) x 每頁(yè)文章數(shù))
$page_offset = $offset + ( ($query->query_vars['paged']-1) * $ppp );
//應(yīng)用調(diào)整后的偏移量
$query->set('offset', $page_offset );
} else {
//如果是首頁(yè),只設(shè)置偏移量就可以了
$query->set('offset',$offset);
}
}
OK,兩個(gè)參數(shù)可以同時(shí)使用了,但是還存在一個(gè)問(wèn)題,WordPress 計(jì)算總文章數(shù)量的時(shí)候,不會(huì)把跳過(guò)的文章考慮進(jìn)入,比如我們數(shù)據(jù)庫(kù)里面有 25 篇文章,每頁(yè)顯示 10 篇,如果沒(méi)有偏移,分頁(yè)數(shù)為 3,這是正常的,設(shè)置了偏移量之后,正確的分頁(yè)數(shù) 2,事實(shí)是,如果我們不做進(jìn)一步處理,WordPress 現(xiàn)實(shí)出來(lái)了分頁(yè)仍然是 3,這時(shí)候如果點(diǎn)一下第三頁(yè),不出意外肯定是404 頁(yè)面,因?yàn)楝F(xiàn)實(shí)的內(nèi)容總共才 15 篇,這一頁(yè)根本不存在。這個(gè)問(wèn)題修復(fù)起來(lái)也很簡(jiǎn)單,請(qǐng)看下面的代碼。
add_filter('found_posts', 'myprefix_adjust_offset_pagination', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {
//定義需要跳過(guò)的文章的數(shù)量
$offset = 10;
//確保我們修改的是正確的查詢(xún)對(duì)象
if ( $query->is_posts_page ) {
//用找到的文章數(shù)量減去偏移的文章數(shù)量...
return $found_posts - $offset;
}
}
應(yīng)該是類(lèi)似的需求很小,所以 WordPress開(kāi)發(fā)團(tuán)隊(duì)忽略了這個(gè) “bug”,以上是 WordPress 官方給去的解決方案,當(dāng)然,解決問(wèn)題的辦法不止一種,如果你有更好的解決方案,歡迎在評(píng)論中提出。

