前回の続き。例によって、あまり人に読まれる事を考慮してません(笑)

ここまでのあらすじ

(´-ω-`) oO

(´=ω・`) え、なに?

というわけで、

今日は記事本体を見ていきます。

記事を表示するのは幾つかパターンあるみたい。

  • 個別表示(パーマリンク)
  • 一覧表示
    • フロントページ
    • 検索
    • カテゴリー
    • タグ

今現在の仮の状態

今は記事の部分の出力はこんな感じ。

  • wp-content/themes/ginpen/index.php (部分)
<div id="main">
<ul>
<?php
while ( have_posts() ) {
  the_post();
  echo '<li><a href="';
  echo the_permalink();
  echo '">';
  echo the_title();
  echo '</a></li>';
  // get_template_part( 'content', get_post_format() );
}
?>
</ul>
</div>

ulはもちろん今だけです。本丸はコメントアウトしてあるget_template_part()の部分。

まあ関数の名前を見ればなんとなくわかる気がする。

get_template_part( $slug, $name )

テーマのその名前のテンプレートパーツをインクルードします。name を指定した場合は、特定の部分をインクルードします。{slug}.php ファイルが無い場合は、インクルードしません。

というわけでcontent.phpだな。

  • wp-content/themes/twentyeleven/content.php

100行程度。まずはこれをじっくり見てゆきます。

記事の外枠

  • wp-content/themes/twentyeleven/content.php #11
    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

IDとクラス。

記事ヘッダー

んーちょっと長め。

  • wp-content/themes/twentyeleven/content.php #12
        <header class="entry-header">
            <?php if ( is_sticky() ) : ?>
                <hgroup>
                    <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyeleven' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
                    <h3 class="entry-format"><?php _e( 'Featured', 'twentyeleven' ); ?></h3>
                </hgroup>
            <?php else : ?>
            <h1 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyeleven' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h1>
            <?php endif; ?>

            <?php if ( 'post' == get_post_type() ) : ?>
            <div class="entry-meta">
                <?php twentyeleven_posted_on(); ?>
            </div><!-- .entry-meta -->
            <?php endif; ?>

            <?php if ( comments_open() && ! post_password_required() ) : ?>
            <div class="comments-link">
                <?php comments_popup_link( '<span class="leave-reply">' . __( 'Reply', 'twentyeleven' ) . '</span>', _x( '1', 'comments number', 'twentyeleven' ), _x( '%', 'comments number', 'twentyeleven' ) ); ?>
            </div>
            <?php endif; ?>
        </header><!-- .entry-header -->

twentyeleven_posted_on()functions.phpで定義されてる。

  • wp-content/themes/twentyeleven/functions.php #554
if ( ! function_exists( 'twentyeleven_posted_on' ) ) :
/**
 * Prints HTML with meta information for the current post-date/time and author.
 * Create your own twentyeleven_posted_on to override in a child theme
 *
 * @since Twenty Eleven 1.0
 */
function twentyeleven_posted_on() {
    printf( __( '<span class="sep">Posted on </span><a href="%1$s" title="%2$s" rel="bookmark"><time class="entry-date" datetime="%3$s" pubdate>%4$s</time></a><span class="by-author"> <span class="sep"> by </span> <span class="author vcard"><a class="url fn n" href="%5$s" title="%6$s" rel="author">%7$s</a></span></span>', 'twentyeleven' ),
        esc_url( get_permalink() ),
        esc_attr( get_the_time() ),
        esc_attr( get_the_date( 'c' ) ),
        esc_html( get_the_date() ),
        esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
        sprintf( esc_attr__( 'View all posts by %s', 'twentyeleven' ), get_the_author() ),
        esc_html( get_the_author() )
    );
}
endif;

こんな感じか:

  • if: フロントページに固定?
    • タイトルとリンクと「注目」を表示
  • else:
    • タイトルとリンクを表示
  • if: この投稿は「記事」?
    • twentyeleven_posted_on() (投稿日時と投稿者を表示)
      • 投稿日時を、記事へのリンクとして出力
      • 投稿者名を、投稿者ページへのリンクとして出力
  • if: コメントが有効?
    • コメントへのリンクを表示

記事本文

お、短い。

  • wp-content/themes/twentyeleven/content.php #35
        <?php if ( is_search() ) : // Only display Excerpts for Search ?>
        <div class="entry-summary">
            <?php the_excerpt(); ?>
        </div><!-- .entry-summary -->
        <?php else : ?>
        <div class="entry-content">
            <?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?>
            <?php wp_link_pages( array( 'before' => '<div class="page-link"><span>' . __( 'Pages:', 'twentyeleven' ) . '</span>', 'after' => '</div>' ) ); ?>
        </div><!-- .entry-content -->
        <?php endif; ?>

wp_link_pages()は「< prev | 0 | 1 | 2 | next >」みたいなリンクを表示するみたい。使った事無いけど、本文中に<!--nextpage-->を記述する事で分割できるとか。そんな機能知らなかった。

記事フッター

これもまた長いので分割。

外枠

  • wp-content/themes/twentyeleven/content.php #46
        <footer class="entry-meta">
            <?php $show_sep = false; ?>

$show_sepはここからしばらく使うフラグで、これがtrueのときは区切りを表示してからそこの部分を出力するようになる。ここではカテゴリーとタグの間に「|」を表示している。

カテゴリーとタグ

  • wp-content/themes/twentyeleven/content.php #48
            <?php if ( 'post' == get_post_type() ) : // Hide category and tag text for pages on Search ?>
            <?php
                /* translators: used between list items, there is a space after the comma */
                $categories_list = get_the_category_list( __( ', ', 'twentyeleven' ) );
                if ( $categories_list ):
            ?>
            <span class="cat-links">
                <?php printf( __( '<span class="%1$s">Posted in</span> %2$s', 'twentyeleven' ), 'entry-utility-prep entry-utility-prep-cat-links', $categories_list );
                $show_sep = true; ?>
            </span>
            <?php endif; // End if categories ?>
            <?php
                /* translators: used between list items, there is a space after the comma */
                $tags_list = get_the_tag_list( '', __( ', ', 'twentyeleven' ) );
                if ( $tags_list ):
                if ( $show_sep ) : ?>
            <span class="sep"> | </span>
                <?php endif; // End if $show_sep ?>
            <span class="tag-links">
                <?php printf( __( '<span class="%1$s">Tagged</span> %2$s', 'twentyeleven' ), 'entry-utility-prep entry-utility-prep-tag-links', $tags_list );
                $show_sep = true; ?>
            </span>
            <?php endif; // End if $tags_list ?>
            <?php endif; // End if 'post' == get_post_type() ?>
  • if: 記事? (検索時にカテゴリーやタグを隠す)
    • カテゴリー取得
    • if: カテゴリーある?
      • カテゴリーを出力 (複数あればカンマで区切る)
      • 区切りが必要だよって覚えておく
    • タグ取得
    • if: タグある?
      • if: 区切りが必要?
        • 区切り「|」出力
      • タグ出力
      • 区切りが必要だよって覚えておく

__()は他言語対応だけかと思いきや、ここでは反復にも使ってる。便利なんだなー。

コメント

  • wp-content/themes/twentyeleven/content.php #73
            <?php if ( comments_open() ) : ?>
            <?php if ( $show_sep ) : ?>
            <span class="sep"> | </span>
            <?php endif; // End if $show_sep ?>
            <span class="comments-link"><?php comments_popup_link( '<span class="leave-reply">' . __( 'Leave a reply', 'twentyeleven' ) . '</span>', __( '<b>1</b> Reply', 'twentyeleven' ), __( '<b>%</b> Replies', 'twentyeleven' ) ); ?></span>
            <?php endif; // End if comments_open() ?>

comments_open()のコードを読むと、中でフィルターcomments_openを呼んでいる事がわかる。

content.phpは一覧表示用のものなので、コメントの一覧は出力せず、リンクのみ。

外枠

  • wp-content/themes/twentyeleven/content.php #80
            <?php edit_post_link( __( 'Edit', 'twentyeleven' ), '<span class="edit-link">', '</span>' ); ?>
        </footer><!-- #entry-meta -->
    </article><!-- #post-<?php the_ID(); ?> -->

諸々閉じる。

まとめ

ひゃあー、これでcontent.php終わり。

実際は、ページの表示方法によって自動的にテンプレートが切り替わるらしい。だから本当はsingle.phpとかも見る必要があるんだけど、なければindex.phpになるから、まあひとまず大丈夫。その振り分けとかは明日以降に見ます。

投稿情報出力関数

基本的に全て関数を呼んだ時点で出力されます。

プログラマー的には取得と表示は分けたい気がするんだけれど、考え方的にはそれぞれが単体の「タグ」として考えるとしっくり来る感じ。つまり「タイトルを取得、出力するthe_title()関数」じゃなくて「タイトルを表示する<?php the_title(); ?>タグ」と認識する。

あと、それぞれ同名のフィルターを通るみたいです。get_hoge()ならapply_filters('get_hoge', $value)な感じで。フィルターについては稿を改める……というか、FAQぽいんで適当にググってください。

項目 関数 備考
記事URL the_permalink()
記事ID the_ID() フィルターなし
タイトル the_title() echo省略可能。エスケープなし
投稿時刻 the_time() date()と同じ書式を指定可能
投稿日付 the_date() echo省略可能。date()と同じ書式を指定可能。同じ日付は最初の一度しか出力しない
投稿者 the_author() echo省略可能
抜粋 the_excerpt()
内容 the_content() エスケープなし
カテゴリー the_category() ul>li>aを出力
タグ the_tags() 複数のa要素を出力

the_date()は「一日一回」しか使えないので、基本的にthe_time()に(書式を与えて)使用するのが良い感じみたい。ちなみに「一日一回」の判定は、コードを見る感じif ( $currentday != $previousday )でいけるみたいなので(変数はいずれもグローバル)、はてなダイアリーみたいにする場合はこれで。

補助情報

項目 関数 備考
コメント欄へのリンク comments_popup_link() a要素を出力
ページネイション wp_link_pages() 詳細はリファレンス参照
個別表示か? is_single()
検索か? is_search()
フロントページに固定か? is_sticky()
投稿種別 get_post_type() 戻り値候補: post, page, attachment, revision
他言語対応 __()
URL用エスケープ esc_url()
HTML用エスケープ esc_html()
HTML属性値用エスケープ esc_attr()

さてじゃあこれを適用してテンプレートのコードを組み立てる。

コード

  • wp-content/themes/ginpen/index.php (部分)
↑ヘッダーとか

<div id="main">
<?php
while ( have_posts() ) {
  the_post();
  get_template_part( 'content', get_post_format() );
}
?>
</div>

↓フッターとか
  • wp-content/themes/ginpen/content.php
<article id="post-<?php the_ID(); ?>">
  <header>
    <h1><a href="<?php the_permalink() ?>"><?php the_title() ?></a></h1>
  </header>
  <aside>
    <span class="post-datetime">投稿日: <a href="<?php the_permalink() ?>"><time datetime="<?php the_time('c'); ?>"><?php the_time('Y/m/d H:i'); ?></time></a></span>
    <div class="post-categories">
      カテゴリー:
      <?php the_category(); ?>
    </div>
    <span class="post-tags">
      <?php the_tags(); ?>
    </span>
  </aside>
  <div class="article-body">
<?php the_content() ?>
  </div>
  <footer>
    <?php if ( is_single() ) :?>
      <div id="comments">
        (TODO: ここにコメントを出す)
      </div>
      <div class="post-neighbers">
        (TODO: ここに隣接記事へのリンクを出す)
      </div>
    <?php else : ?>
      <div class="post-comments">
        <?php comments_popup_link(); ?>
      </div>
    <?php endif ?>
  </footer>
</article>

一人でやるブログには投稿者名とかいらないよね、というわけで出力していません。

また投稿日時とカテゴリーは空にはならないので有無の判定はせず、一方タグはラベル部分「タグ:」の出力をカバーしてくれるので、ここも判定しません。なおここの部分の区切りは、文字ではなく余白で、CSSで指定するつもりなので、そこの処理も省略。

あとtwentyeleventでは検索結果には抜粋を表示するようになってたんだけど、そうしないで常に本文を表示。なお「続きを読む」はthe_content()の内部で行われていて、フロントページや検索結果、カテゴリー、タグから一覧表示している場合は、適切に処理されてるみたいです。

次回は

コメントと隣接記事へのリンクが必要。

single.phpとか振り分けとかそのあたりを探ってゆきます。