Wordpress的loop,確實是非常實用。不過假若你希望為loop加設一些規則,讓它只能夠顯示部分的文章?那麼我們就需要用到wordpress的query_posts。但query_posts,也有另一個問題,它可算是wordpress的一個核心編碼來,隨意修改,很容易弄出問題,那麼又有沒有一個更安全的選擇?沒錯,他就是我們今天的主角: WP_Query。透過它我們就能夠在安全的環境下,去為loop,加設額外的規則了。當然,這並不是WP_Query唯一的功能,不過第二個功能,一般都是用於開發wordpress插件上,與主題關係不大,這裡我們就不說了。
既然我們都說,WP_Query的用途是來修改loop的,那麼我們就從loop開始看起吧。大家看到這篇,相信對loop都已經並不陌生,一般列出文章的loop,是長這樣:
<?php if(have_posts()): while( have_posts()):the_post(); ?>
<?php endwhile; else: endif;?>
不過我們現在並不是要普通的loop,而是希望可以加入WP_Query,去修改loop,那麼我們的編碼該是怎樣?這裡先給大家看看修改後編碼的模樣吧。
$the_query = new WP_Query( $args );
<?php if($the_query->have_posts()):
while($the_query-> have_posts()):$the_query->the_post();?>
<?php endwhile; else: endif ; wp_reset_postdata();?>
我相信聰明的你應該很簡單,就看得出分別吧,沒錯,這裡我們加添了$the_query = new WP_Query( $args );
這個編碼的重點,在於後方new WP_Query( $args ),我們透過加入new WP_Query,去加設規則,而規則即是$args,接著我們把這堆編碼安排了一個代號給他,這裡就是$the_query(這裡的名字可隨你喜歡而更改),完成後,我們就可以大肆地透過$the_query->的方式,安插到下方的loop了。
除了上述的分別外,你應該也注意到,我們也加入了這段編碼在底部。不過為什麼需要呢?它就好像一個安全鎖,確保你增設的規則,就只會在這個loop裏,能夠使用。雖說WP_Query本身是蠻安全,但假若你有天突然忘了查看,然後很遺憾,有代號重複使用了。那麼你代號重複的編碼,也就因為這樣,而變成互相影響著。而加入了wp_reset_postdata();
,就可以完全杜絕這情況出現了,
怎樣,是不是很簡單呢?
不過,我們還沒說那些規則,是要怎樣訂立,我們接著看下去吧
這其實並沒有您想的這麼困難,我們先來看看編碼吧:
$args = array(
);
我們只需要把$args = array();放在$the_query = new WP_Query( $args );上方,那麼就可以了,至於你要加入的設定則會放在array內。
我們就以之前在Day20 裏的文章,作為例子,去完成你第一個的WP_Query吧。
<?php query_posts( 'posts_per_page=5' ); ?>
<?php if(have_posts()): while( have_posts()):the_post(); ?>
你會發現我們之前所用的,是 query_posts,這是一個不好的習慣來的,我們可承擔不起,它潛在的風險呢! 不過wp_query有什麼相關的編碼,可以使用呢?
我們可以在Pagination Parameters 裏找到答案。大家仔細留意一下,就會注意到posts_per_page,這個編碼也是要來調整頁面可以顯示的頁數的,我們可以利用這編碼,來做到相同效果。我們來看看該怎麼做吧:
$args = array(
'posts_per_page' => 5,
);
$query = new WP_Query( $args );
其實,這裡也是只是利用array,來修改wordpress系統,這個資料庫裡面,預先設定好的數值,例如這裡我們就把posts_per_page的數值,設定為5, 這樣wordpress就會顯示最新的五篇文章了。順帶一提,假若大家把數值設為-1,那麼列出的文章數,就不會有任何限制了。不過,相信大家看了這麼多天的array,這裡對你來說,已經不難了解,對吧^^
不過,假若你有五篇文章,但您希望最新的文章,並不會在這loop顯示出來,而是獨立地作為網頁的封面,看起來像是這樣子:
(不過我們希望上方是最新文章,然後下方是較舊的就是了)
那麼可以怎樣?這裡最大的問題是,若果我們上方是寫posts_per_page' => 1,下方為posts_per_page' => 4,那麼你就會看到,最新的文章,就會同時出現在上方和下方。我們可以怎樣做呢?最好的解決方法是,我們是可以透過在下方的loop,加入offset=> 1,來把第一篇文章從下方的loop篩選掉,那麼就可以做到了
編碼片段:
$args = array(
'posts_per_page' => 4,
'offset' => 1
);
$query = new WP_Query( $args );
接下來,讓我來說明一下,究竟有什麼限制,什麼設定,是可以加入到WP_Query裏,而這些設定,究竟有什麼進階一點的用法吧。不過當然,WP_Query的參數是非常多,這裡有點難全部都為大家詳細說明,我們這裡,主要只會去說文章,頁面,分類,標籤在wp_query裏,一些最常用到的參數,若大家希望詳細了解,可以到wordpress WP_Query裏查看。
既然大家們要製作主題,那麼少不了就會需要在主頁等地方,調整一下,你會希望顯示什麼頁面。不過那些設定,究竟需要什麼編碼呢?我們一起來看看吧。
我們這裡就從最簡單的開始吧,我們怎樣設定只顯示某一文章或頁面呢?方法,其實和我們之前,在搜尋系統,設定分類和標籤,來限制出來的搜尋結果,是相近的。我們也是需要用到頁面/文章的id或名字,來設定,您希望會顯示什麼。所以說,那些id數字,也是用相同的方法找到嗎?沒錯,方法是一樣的。
當你進入文章/頁面的版面,接著只需要輕劃到你想要的文章,你會看到下方的連結同樣是有數字出現的,這個就是了,例如這裡就會是9。
至於編碼呢?我們直接來看下方的編碼,你就會明白了:
$args = array(
//文章的
'p' => '9', //文章id
'name' => 'post_name' //文章名稱
//頁面的
'page_id' => '9' , //頁面id
'pagename' => 'page_name' //頁面名稱
);
這應該不難理解吧,我就不再為編碼多作解釋了。不過這裡,有一個小補充,假若可以的話,還是建議盡量使用id,而不是名稱,為什麼呢?要知道,文章/頁面的id,是由wordpress分配,我們較難隨意更改,但名稱則不同,無論任何時候,只要你喜歡,就可以簡單地在wordpress裏,把名稱更改。這代表什麼?就是你每次修改後,你都要回來再更改一次,這無可否認,會令你增添不少麻煩,對吧。這也是為什麼我會說,假若可以的話,還是使用id吧。
在我們繼續說下去之前,首先,這裡我們先解釋一下,什麼是post type吧。其實我們在使用wordpress的時候,也常會見到Post type 。我們常用到的,文章和頁面這兩個地方,就是Post type的例子了。Post type,其實和電腦的資料夾頗為相像,都是要來分門別類用的,wordpress原設的post type ,除了文章和頁面外,還有幾個是,鮮為人知的,包括是Attachments附件(包括了影片,圖片這些),Revisions文章版本(wordpress在你每一個更新後,都會有一個版本存下來,這個就是要來拿出這些內容),Menus選單,Custom CSS(你平時在使用wordpress主題時,不是有個地方可以加入額外的css嗎,這個就是在說那裡),Changesets 自定義設定(每個主題不是都有個地方,讓你可以調整字體,修改header,footer等等,icon等等,這個就是指那裏,而這也像revisions一樣,每個更新也會存下來的,透過這,就能夠拿出這些記錄出來了)。
除了官方的設定之外,你也是可以自己加設一個新的post type,來做分門別類用,這個我們稱為custom post types,主要是透過register_post_type 這個編碼,來做到的,這個編碼一般是會放到function.php的。不過詳細的使用方法,因為篇幅所限,這裡我就不詳細說明了,有興趣可以到wordpress的register_post_type裏詳細查看,假若有機會,我會再在之後的文章補充的。
說了這麼久,相信大家也有個基本的概念吧,那麼實際上我們又可以怎樣使用呢?例如上方的編碼:
$args = array(
'p' => '9'
'name' => 'post_name' );
其實我們也應該要加入post-type讓系統知道,它該到那個分類去找,該顯示什麼,所以應該是這樣子才對
$args = array(
'p' => '9'
'name' => 'post_name'
'post-type' => 'post' );
除了這樣外我們也可以用attachment,要來用提出文章裏的圖片,例如這樣子:
$args = array(
'p' => '9'
'name' => 'post_name'
'post-type' => 'attachment' );
看到這裡應該會更清楚明白為何上方要特定說明,post_type是post吧。因為若你並沒有指定,那麼你可以是要它提供文章裏的文字,也可以是圖片,你又沒說,誰會知道呢?
至於你設定好的custom post type 呢,其實方法也是差不多,通常custom post type是長這樣子的:
function register_support() {
$args = array(
);
register_post_type( 'support', $args );
}
像平常register一樣,我們會設一個名字,例如這裡就是support,接著我們會在array裡面,放一堆設定,最後那部份和平常會有點不同,我們不再是加入add_action來啟動,而是換了register_post_type,來把這新的post_type可以出現在我們的wordpress裡面。
若果你希望在wp_query使用?那麼我們只需要把你設好的名字作為你的post-type,就可以了,例如這樣:
'post_type' => 'support'
不過你並不是每次都希望是顯示一個文章/頁面的,那麼假若你希望同時顯示數個特定文章,可以怎樣?
我們可以利用到post__in 和 post_not__in,來做到這效果,這裡大家必需要非常留意那些橫線的長度,不然很容易會出錯的。
post_in : 假若你有什麼文章,是希望可以放進去,那麼就可以使用了,不過要注意的是,這裡只可以使用、post_id ,編碼例子:
$args = array(
'post__in' => array(
'9',
'10',
'11',
'12'
)
'post_type' => 'post'
);
那麼你就會看到9,10,11,12 這幾篇文章出現了。
post_not_in : 假若你有什麼文章/頁面,是不希望放進去,那麼就可以使用了,同樣這裡也只可以使用post id編碼例子:
$args = array(
'post_not__in' => array(
'9',
'10',
'11',
'12'
)
'post_type' => 'post'
);
那麼這幾篇文章,都不會顯示出來了。
這篇文章就先到這裡暫停,免得文章看起來這麼冗長,也讓大家太難吸收,至於分類和標籤的部分,我將留會在day25天的文章裏。
覺得wp_query
不是很好用XD雖然在出the_post()
出文章或是列表可以寫得很乾淨,但是在使用中仍然有不順手的地方,比如說為何參數field為何不能是陣列之類的XD還是直接wpdb->query
開發時程會減低更多些哈哈
雖然我也覺得有點不方便,不過盡可能我還是會用wp_query(小弟懶惰,經驗也並不豐富,不太想理會database安全的問題),除非到很複雜的地方,例如製作plugin,要使用到複雜data的時候。
再這,這篇文章是給新手看的,所以我想,也不用這麼複雜吧><