iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
1
Modern Web

讓0基礎的你也能製作簡單wordpress主題系列 第 24

【Day 24】 Wordpress WP_Query小入門,帶你看看WP_Query世界,讓你簡單操控wordpress loop

  • 分享至 

  • xImage
  •  

Wordpress的loop,確實是非常實用。不過假若你希望為loop加設一些規則,讓它只能夠顯示部分的文章?那麼我們就需要用到wordpress的query_posts。但query_posts,也有另一個問題,它可算是wordpress的一個核心編碼來,隨意修改,很容易弄出問題,那麼又有沒有一個更安全的選擇?沒錯,他就是我們今天的主角: WP_Query。透過它我們就能夠在安全的環境下,去為loop,加設額外的規則了。當然,這並不是WP_Query唯一的功能,不過第二個功能,一般都是用於開發wordpress插件上,與主題關係不大,這裡我們就不說了。

loop裏的WP_Query

既然我們都說,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了。

wp_reset_postdata();

除了上述的分別外,你應該也注意到,我們也加入了這段編碼在底部。不過為什麼需要呢?它就好像一個安全鎖,確保你增設的規則,就只會在這個loop裏,能夠使用。雖說WP_Query本身是蠻安全,但假若你有天突然忘了查看,然後很遺憾,有代號重複使用了。那麼你代號重複的編碼,也就因為這樣,而變成互相影響著。而加入了wp_reset_postdata();,就可以完全杜絕這情況出現了,

怎樣,是不是很簡單呢?

不過,我們還沒說那些規則,是要怎樣訂立,我們接著看下去吧

規則訂立

這其實並沒有您想的這麼困難,我們先來看看編碼吧:

$args = array(
 
);

我們只需要把$args = array();放在$the_query = new WP_Query( $args );上方,那麼就可以了,至於你要加入的設定則會放在array內。

你的第一個WP_Query

我們就以之前在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,這裡對你來說,已經不難了解,對吧^^

offset

不過,假若你有五篇文章,但您希望最新的文章,並不會在這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的參數是非常多,這裡有點難全部都為大家詳細說明,我們這裡,主要只會去說文章,頁面,分類,標籤在wp_query裏,一些最常用到的參數,若大家希望詳細了解,可以到wordpress WP_Query裏查看。

文章與頁面

既然大家們要製作主題,那麼少不了就會需要在主頁等地方,調整一下,你會希望顯示什麼頁面。不過那些設定,究竟需要什麼編碼呢?我們一起來看看吧。

單一文章或頁面

我們這裡就從最簡單的開始吧,我們怎樣設定只顯示某一文章或頁面呢?方法,其實和我們之前,在搜尋系統,設定分類和標籤,來限制出來的搜尋結果,是相近的。我們也是需要用到頁面/文章的id或名字,來設定,您希望會顯示什麼。所以說,那些id數字,也是用相同的方法找到嗎?沒錯,方法是一樣的。

當你進入文章/頁面的版面,接著只需要輕劃到你想要的文章,你會看到下方的連結同樣是有數字出現的,這個就是了,例如這裡就會是9。

文章和頁面的id同樣能在網頁連結裏看到

至於編碼呢?我們直接來看下方的編碼,你就會明白了:

$args = array(
    //文章的
    'p' => '9',     //文章id
    'name' => 'post_name'    //文章名稱  
    
    //頁面的
    'page_id' => '9' ,     //頁面id
    'pagename' => 'page_name'   //頁面名稱
);

這應該不難理解吧,我就不再為編碼多作解釋了。不過這裡,有一個小補充,假若可以的話,還是建議盡量使用id,而不是名稱,為什麼呢?要知道,文章/頁面的id,是由wordpress分配,我們較難隨意更改,但名稱則不同,無論任何時候,只要你喜歡,就可以簡單地在wordpress裏,把名稱更改。這代表什麼?就是你每次修改後,你都要回來再更改一次,這無可否認,會令你增添不少麻煩,對吧。這也是為什麼我會說,假若可以的話,還是使用id吧。

Post Type

在我們繼續說下去之前,首先,這裡我們先解釋一下,什麼是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天的文章裏。


上一篇
【DAY 23 】 Wordpress 主題的comment?讓你也能夠著手設定吧
下一篇
【Day25】 帶你看看wordpress WP_Query的分類與標籤,讓你可以只顯示每個分類的第一項而不重複
系列文
讓0基礎的你也能製作簡單wordpress主題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Rach
iT邦新手 4 級 ‧ 2020-10-10 21:37:46

覺得wp_query不是很好用XD雖然在出the_post()出文章或是列表可以寫得很乾淨,但是在使用中仍然有不順手的地方,比如說為何參數field為何不能是陣列之類的XD還是直接wpdb->query開發時程會減低更多些哈哈

雖然我也覺得有點不方便,不過盡可能我還是會用wp_query(小弟懶惰,經驗也並不豐富,不太想理會database安全的問題),除非到很複雜的地方,例如製作plugin,要使用到複雜data的時候。

再這,這篇文章是給新手看的,所以我想,也不用這麼複雜吧><

我要留言

立即登入留言