當(dāng)前位置:首頁(yè)>WordPress建站>WordPress開(kāi)發(fā)>WordPress函數(shù):query_posts(查詢文章)

WordPress函數(shù):query_posts(查詢文章)

描述

query_posts() 可以用來(lái)控制在循環(huán)(Loop)中顯示哪些文章。它可以替換主查詢,而使用一個(gè)新的查詢來(lái)獲取文章。要清除 query_posts() 的新查詢,可以使用 wp_reset_query() 來(lái)重置查詢。

我們強(qiáng)烈建議您使用 pre_get_posts 來(lái)替代 query_posts() ,同時(shí)使用 is_main_query 來(lái)檢查主查詢。

舉個(gè)例子,在首頁(yè)(homepage),你可以看到最新的10篇文章。如果你想僅僅顯示 5 篇文章(不在乎分頁(yè)),你可以像這樣使用 query_posts() :

query_posts( 'posts_per_page=5' );

下面是在 functions.php 中使用  pre_get_posts 實(shí)現(xiàn)類型的結(jié)果:

function five_posts_on_homepage( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', '5' );
    }
}
add_action( 'pre_get_posts', 'five_posts_on_homepage' );

注:pre_get_posts 動(dòng)作無(wú)法正常工作于 頁(yè)面(Page) 查詢。

注意事項(xiàng)

query_posts() 只是一種查詢數(shù)據(jù)庫(kù)獲取文章列表的方法。在使用 query_posts() 之前,你需要了解它的弊端。

改變主循環(huán)(Alters Main Loop)

query_posts() 是通過(guò)替換查詢條件來(lái)改變主循環(huán)生成的內(nèi)容的。一旦你使用 query_posts(), 你文章的相關(guān)的全局變量和模板標(biāo)簽都將改變。條件標(biāo)簽(Conditional tags)在你調(diào)用  query_posts() 之后也會(huì)發(fā)生改變——這可能是也可能不是預(yù)期的結(jié)果。

二級(jí)循環(huán)(Secondary Loops)

要?jiǎng)?chuàng)建 二級(jí)列表(例如:在頁(yè)面底部顯示相關(guān)文章列表,或者在邊欄小工具中顯示一個(gè)列表), 嘗試使用 WP_Query 或 get_posts() 來(lái)獲取文章。

如果你一定要用 query_posts() ,請(qǐng)確保你在上一個(gè)使用了 query_posts() 的循環(huán)結(jié)束的地方,使用 wp_reset_query() 來(lái)重置查詢。

分頁(yè)(Pagination)

分頁(yè)將無(wú)法正常工作,除非你適當(dāng)設(shè)置 ‘paged’ 查詢: adding the paged parameter

額外的SQL查詢

如果你在模板頁(yè)面中使用 query_posts ,WordPress 就會(huì)在 query_posts 時(shí)執(zhí)行數(shù)據(jù)庫(kù)查詢和檢索記錄(即它是如何知道是服務(wù)于哪個(gè)模板頁(yè)面!)所以,當(dāng)你使用 query_posts() 覆蓋了默認(rèn)的查詢,你基本上就扔掉了默認(rèn)的查詢以及它的結(jié)果,并重新對(duì)數(shù)據(jù)庫(kù)執(zhí)行了另一個(gè)查詢。

這也許不是一個(gè)問(wèn)題,尤其是如果你正在處理一個(gè)較小的基于博客的網(wǎng)站。但是對(duì)于大型網(wǎng)站、大型數(shù)據(jù)庫(kù)以及較高的訪客流量來(lái)說(shuō),你就要考慮使用其他查詢方式來(lái)減少 SQL查詢了,比如直接修改默認(rèn)的查詢(在它被請(qǐng)求前)。使用請(qǐng)求(request)過(guò)濾器可是實(shí)現(xiàn)這點(diǎn)。

‘parse_query’ 和 ‘pre_get_posts’ 過(guò)濾器也可用來(lái)修改內(nèi)部用于生成SQL查詢數(shù)據(jù)庫(kù)的 $query 對(duì)象。

用法

<?php
// 查詢
query_posts( $args );

// 循環(huán)
while ( have_posts() ) : the_post();
    echo '<li>';
    the_title();
    echo '</li>';
endwhile;

// 重置查詢
wp_reset_query();
?>

在模板文件的循環(huán)前面添加 query_posts() ,wp_query 對(duì)象將根據(jù)你給定的參數(shù)生成一個(gè)新的 SQL 查詢。當(dāng)你這樣做時(shí),WordPress 將忽視通過(guò)URL檢索到的其他參數(shù)(例如 頁(yè)碼或分類)。

保留現(xiàn)有的查詢參數(shù)

如果你想保留原來(lái)的查詢參數(shù)作為當(dāng)前查詢的一部分,然后添加或重寫一些參數(shù),你可以在 query_posts() 中使用全局變量 $query_string 。

例如,要修改文章的顯示順序并且不影響接下來(lái)的查詢,你可以在循環(huán)(The Loop)前面使用下面的代碼:

global $query_string;
query_posts( $query_string . '&order=ASC' );

當(dāng)你通過(guò)這種方式使用 query_posts() , 參數(shù)的前面必須添加一個(gè) & 。或者你可以合并原來(lái)的查詢數(shù)組到到你的參數(shù)數(shù)組:

global $wp_query;
$args = array_merge( $wp_query->query_vars, array( 'post_type' => 'product' ) );
query_posts( $args );

結(jié)合參數(shù)

從上面的例子中,你可能已經(jīng)注意到,你可以使用 & 來(lái)結(jié)合參數(shù):

query_posts( 'cat=3&year=2004' );

在首頁(yè)查詢當(dāng)前月份的分類ID為 13 的文章:

if ( is_home() ) {
	query_posts( $query_string . '&cat=13&monthnum=' . date( 'n', current_time( 'timestamp' ) ) );
}

下面的例子,將返回一組文章(分類ID為 1 和 3 、顯示 2 篇文章、根據(jù)標(biāo)題降序排列):

query_posts( array( 'category__and' => array(1,3), 'posts_per_page' => 2, 'orderby' => 'title', 'order' => 'DESC' ) );

下面的例子將返回分類ID為 1 和 標(biāo)簽為 “apples”的文章:

query_posts( 'cat=1&tag=apples' );

你可以使用加號(hào) + 來(lái)添加更多標(biāo)簽:

query_posts( 'cat=1&tag=apples+apples' );

參數(shù)

參數(shù)詳情請(qǐng)閱讀 Parameter section of the WP_Query class article.

下面的例子同樣可以用于 WP_Query 對(duì)象。

例子

在首頁(yè)排除分類

將下面的代碼添加到 index.php 文件,這樣首頁(yè)將顯示 除了分類ID為 3 以外的其他所有文章:

<?php
if ( is_home() ) {
	query_posts( 'cat=-3' );
}
?>

你還可以以此類推添加更多要排除的分類:

<?php
if ( is_home() ) {
	query_posts( 'cat=-1,-2,-3' );
}
?>

檢索某一篇文章

要檢索某一篇文章,可以使用下面的代碼:

query_posts( 'p=5' );

注:如果檢索的是一個(gè)附件,那你應(yīng)該使用 attachment_id 代替 p :

query_posts( 'attachment_id=5' );

如果你想使用“閱讀更多(Read More)”功能,你就需要在查詢中設(shè)置全局變量 $more 的值為 0 :

<?php
// 檢索 ID 為 5 的文章
query_posts( 'p=5' );

// 設(shè)置 $more 為 0 以便僅僅獲取文章的第一部分
global $more;
$more = 0;

// 循環(huán)
while (have_posts()) : the_post();
	the_content( '閱讀全文 ?' );
endwhile;
?>

一個(gè)分類的所有文章

在 設(shè)置 > 閱讀 中,“博客頁(yè)面最多顯示”的設(shè)置可以影響你的結(jié)果。為了克服這個(gè)問(wèn)題,你可以添加 ‘posts_per_page’ 參數(shù),例如:

query_posts( array ( 'category_name' => 'my-category-slug', 'posts_per_page' => -1 ) );

這樣將顯示這個(gè)分類的所有文章。

但是,對(duì)于子分類(subcategories or child categories), ‘The Category Name’ 可能就沒(méi)辦法生效,請(qǐng)使用 ‘category-slug’ 替代。閱讀 Function_Reference/is_category

if (is_category('category-slug')): 

	 query_posts(array('category_name' => 'my-category-slug', 'posts_per_page' => -1 )); 

endif; 

聚合 Feeds

在 設(shè)置 > 閱讀 中,“Feed 中顯示最近”的設(shè)置 或者  ‘posts_per_rss’ 參數(shù)將在 Feed 中覆蓋任何查詢的 ‘posts_per_page’ 參數(shù)。

為了克服這個(gè)問(wèn)題(例如在自定義的 ics Feed 中,輸出所有符合條件的文章),可以使用 "posts_limit" 過(guò)濾器:

if ( isset ( $query->query_vars['feed'] ) and ( $query->query_vars['feed'] == 'ics' ) )
{
	add_filter( 'post_limits', '__return_empty' );
}

傳遞變量到 query_posts

有兩種方法可以傳遞一個(gè)變量到查詢中,你可以根據(jù)自己的需求選擇。就像其他例子一樣,將下面的代碼添加到循環(huán)的上面:

例 1

在這個(gè)例子中,我們?cè)诓樵冞\(yùn)行前串連查詢條件。首先分配變量,然后串連,然后運(yùn)行它。在這里,我們從其他地方拉來(lái)一個(gè)分類變量:

// 分配參數(shù)作為當(dāng)前分類
$categoryvariable = $cat;

// 串連查詢
$args = 'cat=' . $categoryvariable . '&orderby=date&order=ASC';

// 運(yùn)行查詢
query_posts( $args );

例 2

在這個(gè)例子中,雙引號(hào)是告訴 PHP 這是一個(gè)閉合。對(duì)于這個(gè)例子,我們獲取當(dāng)前 月份 和 年份,然后告訴 query_posts() 顯示當(dāng)前 年/月 的文章。此外,我們使用升序排列(ASE) ,這樣,最老的文章將顯示在頁(yè)面的頂部:

$current_year = date('Y');
$current_month = date('m');

query_posts( "cat=22&year=$current_year&monthnum=$current_month&order=ASC" );

例 3

這個(gè)例子解析如何刪除一個(gè)完整的文章列表,并且進(jìn)行分頁(yè)處理。我們可以使用默認(rèn)的 $query_string 告訴 query_posts() 顯示所有文章列表。我們還可以自定義 posts_per_page 這個(gè)查詢參數(shù)為 –1 到 任何數(shù)量 來(lái)設(shè)置每頁(yè)顯示的文章數(shù)。最后,你可能想使用  posts_nav_link() 來(lái)導(dǎo)航生成的文章存檔。

query_posts( $query_string . '&posts_per_page=-1' );

例 4

如果你不需要使用 $query_string 變量,另一種方法是將所有的參數(shù)添加到一個(gè)數(shù)組中,即使在更加復(fù)雜的情況下,也清晰明了。上面 例 2 可以使用下面的代碼實(shí)現(xiàn):

$args = array(
	'cat'      => 22,
	'year'     => $current_year,
	'monthnum' => $current_month,
	'order'    => 'ASC'
);
query_posts( $args );

正如你所見(jiàn),通過(guò)這種方式,所有的變量都放置在獨(dú)立的行中,這就非常容易閱讀了。

例 5

它甚至可以使用數(shù)組方式(例 4)來(lái)查詢多個(gè)分類。只需提供分類別名(taxonomy slug),多個(gè)別名使用逗號(hào)隔開(kāi)。在下面的例子中,我們會(huì)得到 Bruce Campbell 或 Chuck Norris 的movie文章:

$args = array(
	'post_type'=> 'movie',
	'actor'    => 'Bruce Campbell, Chuck Norris',
	'order'    => 'ASC'
);
query_posts( $args );

所在文件

query_posts() 包含在  wp-includes/query.php.

其他資源

為了更深入的討論 WordPress 生成和處理查詢,請(qǐng)閱讀這些文章:

相關(guān)函數(shù)

類: WP_Query – 詳細(xì)的 WP_Query 類概述

類: $wpdb – 使用 $wpdb 對(duì)象的概述

函數(shù): get_query_var()

函數(shù): get_posts() – 一個(gè)專門返回文章數(shù)組的函數(shù)

函數(shù): get_pages() – 一個(gè)專門返回頁(yè)面數(shù)組的函數(shù)

函數(shù): have posts() – 一個(gè)確定查詢是否返回文章的條件

函數(shù): the_post() – 用于自動(dòng)設(shè)置查詢后的循環(huán)

函數(shù): rewind_posts() – 重置當(dāng)前循環(huán)

函數(shù): setup_postdata() – 為循環(huán)中的私有查詢?cè)O(shè)置查詢數(shù)據(jù)

函數(shù): wp_reset_postdata() – 恢復(fù)以前的查詢(通常在一環(huán)內(nèi)循環(huán))

函數(shù): wp_reset_query()

函數(shù): is_main_query() – 確保被改變的僅僅是主查詢

動(dòng)作鉤子: pre_get_posts – 在執(zhí)行之前修改 WordPress 的查詢

過(guò)濾鉤子: found_posts – 修改 WP_Query 對(duì)象的 found_posts 的值

教程: Displaying Posts Using a Custom Select Query

教程: Making Advanced Taxonomy Queries

教程: Making Custom Queries using Offset and Pagination

聲明:本站所有文章,如無(wú)特殊說(shuō)明或標(biāo)注,均為本站原創(chuàng)發(fā)布。任何個(gè)人或組織,在未征得本站同意時(shí),禁止復(fù)制、盜用、采集、發(fā)布本站內(nèi)容到任何網(wǎng)站、書籍等各類媒體平臺(tái)。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。

給TA打賞
共{{data.count}}人
人已打賞
歡迎關(guān)注WordPress大學(xué)公眾號(hào) WPDAXUE
WordPress開(kāi)發(fā)

WordPress函數(shù):get_bloginfo(獲取博客信息)

2013-4-7 10:00:07

WordPress開(kāi)發(fā)

如何創(chuàng)建WordPress自定義查詢

2013-4-10 9:13:55

2 條回復(fù) A文章作者 M管理員
  1. 大師傅

    為什么我在rss里面能看到文章,但是用軟件就獲取不到呢,我還加了防采集的代碼。

  2. wp_reset_query()和 wp_reset_query() 一般都是配對(duì)使用的吧

?
個(gè)人中心
購(gòu)物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

望城县| 定边县| 东宁县| 邵阳市| 原平市| 天台县| 东丽区| 武夷山市| 万源市| 晋宁县| 宁强县| 曲水县| 当雄县| 福安市| 长乐市| 盐城市| 阳城县| 吉木萨尔县| 虎林市| 怀安县| 精河县| 扬州市| 韩城市| 府谷县| 林州市| 多伦县| 永州市| 宝山区| 新龙县| 赤水市| 凌云县| 龙岩市| 呼和浩特市| 保亭| 黔西县| 伊宁县| 莲花县| 师宗县| 东宁县| 彭州市| 涟水县|