5330-myloop-1

ページに投稿を表示するショートコード

WordPressをコンテンツ管理システムとして使う場合、サイトトップはブログのように投稿(ポスト)を時系列で表示するのではなく、奇麗にデザインされた固定ページを用意し、投稿は一部だけを(例えば新着記事5件とか)ページ上にリストで表示するなんてことをよくやります。

WordPressをブログっぽくしたくない時、トップページでループ(投稿のまとまりのこと。WordPressのテーマのテンプレートで投稿を連続表示させるファイルはloop.phpと呼ばれます。)をまるごと表示ではなく、一部だけ表示するようにして、投稿は別の専用ページ上で表示するようにします。こうした作り方をする際、ループを任意のページに簡単に差し込めるショートコードを作っておけば、ページごとにコードが微妙に異なるテンプレートを用意せずとも、このカスタマイズが簡単に実現できます。会員制サイトで著者とカテゴリーで分類すれば、特定の会員のお知らせを表示するページなんかも作れます。ショートコードを使うので、お客さま側で簡単に表示の順番を入れ替えたり、レイアウトを変えたりできます。あと、カスタム投稿タイプを使って専用のお知らせ入力欄を作り、好きな場所に表示するなど、ページの中に色々なコンテンツを一括して掲載することができるようになります。投稿の種類と表示場所が自由に選べるだけでも、できることは色々広がりそうです。

(上の例では、Post UI Tabsプラグインを使って、ページのコンテンツを3つのタブに分類し、その一つ”お知らせ”に著者web5330によって書かれた投稿のループを差し込んでいます。)

いろいろ応用が利くループを表示するショートコードですが、日本語で書かれた作り方の情報がほとんどありません。英語では多少ありますが、情報が多少古いのと、ループ部分の出力の仕方が単純なリスト表示だけだったりしたので、元のコードを改変して、WordPressのloop.phpで出力している形式のものを作ってみました。

ちなみに元のコードはこちらです:

WordPress shortcode: Display the loop

改変版コードはこちらです:

function myLoop($atts, $content = null) {
    extract(shortcode_atts(array(
        "query" => '',
        "category" => '',
        "author_name" => '',
        "posts_per_page" => '',
    ), $atts));
    global $wp_query,$paged,$post;
    $temp_query = $wp_query;
    $temp_paged = $paged;
    $temp_post = $post;

    $wp_query= null;
    $wp_query = new WP_Query();
    if(!empty($category_name)){
        $query .= '&category_name='.$category_name;
    }
    if(!empty($author_name)){
        $query .= '&author_name='.$author_name;
    }
    if(!empty($posts_per_page)){
        $query .= '&posts_per_page='.$posts_per_page;
    }
    if(!empty($query)){
        $query .= $query;
    }
    $wp_query->query($query);
    ob_start();
    ?>

    <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
        <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
	    <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyten' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>

	    <div class="entry-meta">
	        <?php twentyten_posted_on(); ?>
	    </div><!-- .entry-meta -->

	    <div class="entry-content">
	        <?php the_content(); ?>
	    </div>
	</div>
    <?php endwhile; ?>

    <?php
    $wp_query = null;
    $wp_query = $temp_query;
    $paged = null;
    $paged = $temp_paged;
    $post = null;
    $post = $temp_post;
    $content = ob_get_contents();
    ob_end_clean();
    return $content;
}
add_shortcode("loop", "myLoop");

?>

上のコードをfunctions.phpに差し込めば、loopショートコードが使えるようになります。テーマの変更を自由にしたい場合はプラグインにすると良いでしょう。利用できるパラメーターはcategory_name、author_name、posts_per_pageの3つを用意しました。WP_Queryで使えるパラメーターは何でも追加できるので、パラメーターは好きに改変してください。shortcode_attsの配列にパラメーターを追加するだけでOKです。

ショートコード API

WP_Queryの説明は下のリンクを参照してください。リンク先にも説明されているように、使えるパラメーターはquery_postsと同じです。

関数リファレンス/WP Query
テンプレートタグ/query posts

ページにショートコードを差し込む際の記述は以下のとおりです:

[loop category_name="work" author_name="web5330" posts_per_page="5"]

上のショートコードをページの好きな場所に差し込むことで、WordPressの投稿からカテゴリーがwork(仕事)、著者がweb5330(nicenameを使います。ニックネームではないので注意!)、最新の投稿5件をWordPressのデフォルトのループ同様フル記事で表示します。ページ送りもできるはずなので、htmlのアウトプットを変えたいときは、ob_start()からob_get_contents()の間のhtmlを変えれば、好きなhtmlを出力できます。

このショートコードが一個あるだけ、色々できることが広がるので皆さんも試してみてください。