WordPressのTwenty Elevenテーマ解説:単一記事の投稿 (single.php)

WordPressのTwenty Elevenテーマ解説:単一記事の投稿 (single.php)

Posted at October 4,2011 1:55 AM
Tag:[TwentyEleven, WordPress]

WordPressの勉強も兼ねて、Twenty Elevenテーマの各テンプレートについて解説しています。確認バージョンは3.2.1です。

単一記事の投稿 (single.php)

Twenty Elevenテーマの「単一記事の投稿 (single.php)」で出力されるページは次のように、記事のコンテンツとコメントなどが表示されます。

単一記事の投稿 (single.php)

テンプレートのソースコードは次のとおりです。

<?php
/**
 * The Template for displaying all single posts.
 *
 * @package WordPress
 * @subpackage Twenty_Eleven
 * @since Twenty Eleven 1.0
 */
 
get_header(); ?>
 
        <div id="primary">
            <div id="content" role="main">
 
                <?php while ( have_posts() ) : the_post(); ?>
 
                    <nav id="nav-single">
                        <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
                        <span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>
                        <span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>
                    </nav><!-- #nav-single -->
 
                    <?php get_template_part( 'content', 'single' ); ?>
 
                    <?php comments_template( '', true ); ?>
 
                <?php endwhile; // end of the loop. ?>
 
            </div><!-- #content -->
        </div><!-- #primary -->
 
<?php get_footer(); ?>

以下、順を追ってテンプレートの内容について解説します。「WordPressのTwenty Elevenテーマ解説:メインインデックスのテンプレート (index.php)」と一部重複している部分がありますが、この記事だけで一気に読みきれるよう、他の記事への参照は行ってません。

1.ヘッダー情報の出力

ヘッダー情報はget_header()で出力します。

<?php
…中略…
get_header(); ?>

ヘッダー情報は赤枠部分が対応します。

ヘッダー情報

get_header()はwp-includes/general-template.phpに実装されています。

wp-includes/general-template.php

function get_header( $name = null ) {
    do_action( 'get_header', $name );
 
    $templates = array();
    if ( isset($name) )
        $templates[] = "header-{$name}.php";
 
    $templates[] = 'header.php';
 
    // Backward compat code will be removed in a future release
    if ('' == locate_template($templates, true))
        load_template( ABSPATH . WPINC . '/theme-compat/header.php');
}

do_action()はフックポイント「get_header」の作成を行っています。

    do_action( 'get_header', $name );

プラグインを作成している方はすでにご存知と思いますが、add_action()を使えばフックポイントに任意のアクションを追加できます。

例えばプラグインで次のコードを記述すれば、フックポイント「get_header」、つまりdo_action('get_header')の実行時にfoo()が起動され、doctype宣言の前に「foo」が出力されます。

<?php
/*
Plugin Name: Foo
Description: Foo
Version: 1.0
*/ 
function foo() {
  echo "foo";
}
add_action('get_header', 'foo');
?>

話を戻して、get_header()では、パラメータに設定した文字列をテンプレート名として利用します。「get_header('foo')」と書いておけば、「header-foo.php」を「header.php」の代わりにロードします。パラメータの設定がなければ「header.php」をロードします。

    $templates = array();
    if ( isset($name) )
        $templates[] = "header-{$name}.php";
 
    $templates[] = 'header.php';

2.記事データの取得

赤色で示したwhile文のhave_posts()とthe_post()で、記事データを取得します。

                <?php while ( have_posts() ) : the_post(); ?>
 
                    <nav id="nav-single">
                        <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
                        <span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>
                        <span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>
                    </nav><!-- #nav-single -->
 
                    <?php get_template_part( 'content', 'single' ); ?>
 
                    <?php comments_template( '', true ); ?>
 
                <?php endwhile; // end of the loop. ?>

have_posts()は投稿記事をチェックする関数で、wp-includes/query.phpに実装されています。

wp-includes/query.php

function have_posts() {
    global $wp_query;
 
    return $wp_query->have_posts();
}

投稿記事が存在する場合はtrue、存在しない場合はfalseを返却します。パラメータはありません。ここではhave_posts()をwhile文で使っていますが、メインインデックスなどif文で使用している箇所もあります。

付け加えると、単一記事や固定記事ではwhile文を利用しなくても記事データを取得できます。よって次のような構造でも良いと思いますが、認識誤りがありましたらご指摘ください。

<?php if ( have_posts() ) : the_post(); ?>
…中略…
<?php endif; ?>

the_post()は投稿データをロードする関数で、wp-includes/query.phpに実装されています。the_post()を実行しただけでは何も出力しません。

wp-includes/query.php

function the_post() {
    global $wp_query;
 
    $wp_query->the_post();
}

3.前後記事のリンクの出力

赤色部分で前後記事のリンクを出力します。

                <?php while ( have_posts() ) : the_post(); ?>
 
                    <nav id="nav-single">
                        <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
                        <span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>
                        <span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>
                    </nav><!-- #nav-single -->
 
                    <?php get_template_part( 'content', 'single' ); ?>
 
                    <?php comments_template( '', true ); ?>
 
                <?php endwhile; // end of the loop. ?>

前後記事のリンクは次の赤枠部分が該当します。

前後記事のリンク

以下は(X)HTMLマークアップの出力例です。

<span class="nav-previous"><a href="http://user-domain/?p=1" rel="prev"><span class="meta-nav">&larr;</span> 前へ</a></span>
<span class="nav-next"><a href="http://user-domain/?p=6" rel="next">次へ <span class="meta-nav">&rarr;</span></a></span>

previous_post_link()は前の記事のリンクを出力する関数、next_post_link()は次の記事のリンクを出力する関数で、いずれもwp-includes/link-template.phpに実装されています。

wp-includes/query.php

function previous_post_link($format='&laquo; %link', $link='%title', $in_same_cat = false, $excluded_categories = '') {
    adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, true);
}
function next_post_link($format='%link &raquo;', $link='%title', $in_same_cat = false, $excluded_categories = '') {
    adjacent_post_link($format, $link, $in_same_cat, $excluded_categories, false);
}

パラメータの意味は次のとおりです。

  • 第1パラメータ:リンクの文字列の書式。文字列に「%link」を設定すれば、その部分がa要素に置き換わります
  • 第2パラメータ:リンクのテキストを指定。デフォルトは前(または次)の記事タイトル(%title)
  • 第3パラメータ:同一カテゴリの前後記事だけの表示要否(ここではfalse)
  • 第4パラメータ:除外したいカテゴリID(ここでは空)

処理の中で起動されているadjacent_post_link()で実際の処理を行っています。前記事・後記事の区別は第5パラメータで行っています。

function adjacent_post_link($format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true) {
    if ( $previous && is_attachment() )
        $post = & get_post($GLOBALS['post']->post_parent);
    else
        $post = get_adjacent_post($in_same_cat, $excluded_categories, $previous);
 
    if ( !$post )
        return;
 
    $title = $post->post_title;
 
    if ( empty($post->post_title) )
        $title = $previous ? __('Previous Post') : __('Next Post');
 
    $title = apply_filters('the_title', $title, $post->ID);
    $date = mysql2date(get_option('date_format'), $post->post_date);
    $rel = $previous ? 'prev' : 'next';
 
    $string = '<a href="'.get_permalink($post).'" rel="'.$rel.'">';
    $link = str_replace('%title', $title, $link);
    $link = str_replace('%date', $date, $link);
    $link = $string . $link . '</a>';
 
    $format = str_replace('%link', $link, $format);
 
    $adjacent = $previous ? 'previous' : 'next';
    echo apply_filters( "{$adjacent}_post_link", $format, $link );
}

5.コンテンツの出力

赤色のget_template_part()でコンテンツを出力します。

                <?php while ( have_posts() ) : the_post(); ?>
 
                    <nav id="nav-single">
                        <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
                        <span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>
                        <span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>
                    </nav><!-- #nav-single -->
 
                    <?php get_template_part( 'content', 'single' ); ?>
 
                    <?php comments_template( '', true ); ?>
 
                <?php endwhile; // end of the loop. ?>

コンテンツは次の赤枠部分が該当します。

コンテンツ

get_template_part()はwp-includes/general-template.phpに実装されています。

wp-includes/general-template.php

function get_template_part( $slug, $name = null ) {
    do_action( "get_template_part_{$slug}", $slug, $name );
 
    $templates = array();
    if ( isset($name) )
        $templates[] = "{$slug}-{$name}.php";
 
    $templates[] = "{$slug}.php";
 
    locate_template($templates, true, false);
}

do_action()でフックポイント「get_template_part_スラッグ名」の作成を行っています。この場合はスラッグ名は「content」なので、フックポイント名は「get_template_part_content」になります。

また、get_header()と同様、第1パラメータと第2パラメータに設定された名前を使ってテンプレートを呼び出します。第2パラメータが設定されていれば、「スラッグ名-名前.php」でテンプレートを呼び出します。第2パラメータが設定されていなければ、「スラッグ名.php」でテンプレートを呼び出します。

単一記事の投稿(single.php)テンプレートのget_template_part()の第1パラメータは「content」、第2パラメータは「single」なので、「content-single.php」が呼び出されることになります。

6.コメントの出力

赤色のcomments_template()でコメントを出力します。

                <?php while ( have_posts() ) : the_post(); ?>
 
                    <nav id="nav-single">
                        <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
                        <span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>
                        <span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>
                    </nav><!-- #nav-single -->
 
                    <?php get_template_part( 'content', 'single' ); ?>
 
                    <?php comments_template( '', true ); ?>
 
                <?php endwhile; // end of the loop. ?>

コメントは次の赤枠部分が該当します。

<br />
コメント

comments_template()はコメントテンプレートを取得する関数で、wp-includes/comment-template.phpに実装されています(長いので掲載は割愛)。

パラメータの意味は次のとおりです。

  • 第1パラメータ:コメントテンプレート名を指定。値が空の場合は「comments.php」を取得
  • 第2パラメータ:コメント分割の要否。ここでは「true」が設定されているのでコメントを分割表示

なお、コメントの表示制御は管理画面の「設定」→「ディスカッション」で行います。

ディスカッション

コメント表示の詳細については「コメント (comments.php)」テンプレートの解説で行います。

7.フッター情報の出力

フッター情報は赤枠部分が対応します。

フッター情報

フッター情報はget_footer()で出力します。

<?php get_footer(); ?>

get_footer()は、wp-includes/general-template.phpに実装されています。

wp-includes/general-template.php

function get_footer( $name = null ) {
    do_action( 'get_footer', $name );
 
    $templates = array();
    if ( isset($name) )
        $templates[] = "footer-{$name}.php";
 
    $templates[] = 'footer.php';
 
    // Backward compat code will be removed in a future release
    if ('' == locate_template($templates, true))
        load_template( ABSPATH . WPINC . '/theme-compat/footer.php');
}
関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)