WordPressオリジナルテーマ作成について語ってみるテスト、からの続き。
今回はindex.phpの作成編。

▼前回までの作成状況
themes_making2-3

とりあえずindex.phpで記事表示するところまで作ることにします。
トップページ的な役割をするものなので、single.phpと若干作りが違います。

The Loopについて

ループについて簡単に説明します。
wordpressにはループというものがあり、これは他のテンプレートタグとは別格の存在です。
記事などを表示する為に必須で、ループの中でしか使えないタグ(主にtheから始まるもの)というのがあります。

ループの開始は以下のように書きます

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

ifとwhileがセットになってる文なので、次のように分解することも出来ます。

<?php if (have_posts()) : ?>
<p>記事が存在する場合に表示する</p>
<?php while (have_posts()) : the_post(); ?>
<p>ここから繰り返し表示される</p>

:は{に置き換える事も出来ます。

終了は必ず閉じます。
また、elseで記事が存在しない場合の表示も作成出来ます。

<?php endwhile; //繰り返し終了 ?>
<?php else: //記事が存在しない場合の表示 ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; // TheLoop終了 ?>

※マルチループとかクエリとかについてはsingle.php編集後に解説予定です。

index.phpの編集

現在、index.phpはテンプレートファイルからXHTML貼り付けただけの状態になってると思います。
そこに記事表示に必要なテンプレートタグをガッと埋めていきます。
デフォルトテーマのindex.phpとか見ると、PHPソースがごちゃっと入っててウワァと思うかもしれませんが
ループ入れて表示したいものに応じたタグ入れるだけなのでそう難しくはないです。

トップページではコメントやトラックバックURLの表示とかは必要ないので、使わないソースは全部消します。
タイトル・日時・本文・カテゴリー・タグを表示することにして、以下のように変更しました。
前後記事へのリンクは残して、前後一覧ページへのリンクで使用します。tagが目立ちすぎですが、面倒なのでそのまま・・・

themes_making03-1

この時点でのindex.phpは次のようなソースになっています。
(※ul.post-metaのリストタグが間違ってたので修正済)

<?php get_header(); ?>
<div id="main">
	<div id="content">
		<div class="post">
			<h1 class="post-title">Welcome to WordPress</h1>
			<ul class="post-meta">
			<li class="date">2008/07/25</li>
			<li class="category"><a href="#">category</a></li>
			</ul>
			<div class="post-content">
			<p>フォントサイズ指定は<a href="http://tenderfeel.xsrv.jp/css/26/">[CSS]YUI フォントサイズ相対指定サンプル</a>で解説しているものを使用しています。</p>
			<p>CSSのフィルタリングで使用しているif文については、<a href="http://tenderfeel.xsrv.jp/html-xhtml/10/">IEのみに適用させるIF</a>で解説しています</p>
			<p>XML宣言が入っている事に注意してください。</p>
			</div>
			<dl class="post-tag">
			<dt>Tags</dt>
			<dd><a href="#">tag</a></dd>
			<dd><a href="#">tag</a></dd><dd><a href="#">tag</a></dd>
			</dl>
			<ul id="pagenavi">
			<li class="prev"><a href="#">&laquo; Preview</a></li>
			<li class="next"><a href="#">Next &raquo;</a></li>
			</ul>
		</div>
	</div>
</div>
<?php get_sidebar(); ?>
<?php include (TEMPLATEPATH . "/extra.php"); ?>
<?php get_footer(); ?>

以下からの解説はこのソースを元にしていますので、ご注意下さい。

ループタグを繰り返し表示部分に挿入

上で説明したループ入れます。入れる場所は、記事を表示する場所の前後です。

このサンプルソースだと、記事をpostというクラス名のDIVタグに入れてるので、
ループの開始はdiv#contentとdiv.postの間ということになります。

<div id="content">
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">

dl.post-tagとdl#pagenaviの間でdiv.postを閉じます。
その下でwhile(繰り返し)を閉じて、前後ページへのリンクを外します。
ナビゲーションを入れた後、elseで記事が見つからなかった場合の表示を作成。
最後にループのif文を閉じます。

</div>
<?php endwhile; ?>
	<ul id="pagenavi">
	<li class="prev"><a href="#">&laquo; Preview</a></li>
	<li class="next"><a href="#">Next &raquo;</a></li>
	</ul>
<?php else : ?>
<div class="post" id="notfound">
	<h1 class="post-title"><?php _e('404 Not Found', 'wtn'); ?></h1>
	<div class="post-content"><p><?php _e('お探しの記事は見つかりませんでした。', 'wtn'); ?></p></div>
</div>
<?php endif; ?>

リンク付きの記事タイトル – the_title()&the_permalink()

一覧なので、タイトルは記事へのリンク付きにします。
タグはそれぞれ次の通りです。ループ内でのみ使用可能。

<h1 class="post-title"><a href="<?php the_permalink() ?>" title="<?php printf(__('%sの全文を表示', 'wtn'), the_title_attribute('echo=0')); ?>"><?php the_title(); ?></a></h1>

the_title_attribute()は、the_title()よりも綺麗なソースでタイトルを表示するタグです。
引数のechoは0にするとPHPソースとして出力します。

printf()はPHPの出力整形関数です。
printf('フォーマット','フォーマット内に入れたい文字列')という感じの使い方になります。詳しくはPHPのマニュアル見てください。
これは次のように書いても同じです。

title="<?php the_title_attribute('echo=0'); ?>の全文を表示"

投稿日時 - the_time()&the_date()

よく投稿日時の表示方法変えたい、という質問を見かけるんでそれもついでに。
タグは2つあります。

これらの関数は、引数を何も書かずにそのまま書いた場合
オプションの「日付フォーマット」と「時刻フォーマット」で設定したもので表示されますが、
テンプレート内に書いてあるタグに引数が書いてある場合、そちらのフォーマットが優先されます。

フォーマットはPHPのdate関数のものがそのまま使えますので、詳しくはマニュアルを参照。

管理画面での設定をそのまま反映させるなら次のように書きます。

<li class="date"><?php the_date(); ?><?php the_time(); ?></li>

ただしこの場合、同じ日付の記事が並んだ時に投稿日の表示が省略されるので、
index.phpには次のように追加しました。

<li class="date"><?php the_time('Y/m/d'); ?></li>

カテゴリー - the_category()

記事が投稿されているカテゴリーを表示します。

  • the_cateogry() ・・・ カテゴリー名をリンクつきで表示

引数は、複数のカテゴリーに投稿されている場合のセパレータテキストと、
親カテゴリが存在する場合の親子関係表示方法の指定です。

ex1:カンマ区切り

<?php the_category(', '); ?>

ex2:空白区切りと親子関係の表示

<?php the_category('&nbsp;','multiple'); ?>

index.phpではカンマ区切りにしました。

<li class="category"><?php the_category(', '); ?></li>

本文の表示 – the_content()

the_content()は「続きを読む」付きで本文を表示します。
もう一つ抜粋を表示する the_excerpt()というタグがあります。

the_excerpt()を使用した場合に記事の詳細オプションで抜粋が設定されていないと、本文先頭から適当に抜き出して表示します。

the_content()はindex.phpやcategory.phpで使用された場合、
デフォルトの状態では<!--more-->よりも前の部分だけを表示し、
後の部分は「続きを読む」リンクで非表示(記事へのリンクに変換)にします。
引数を何も指定しない場合は(more…)と表示されます。

ex1:テキストの変更

<?php the_content('続きを読む &raquo;'); ?>

ex2:タイトル付き(上:codex 下:the_title_attribute使用)

<?php the_content("Continue reading " . the_title('', '', false)); ?>
<?php the_content(the_title_attribute('echo=0').' の続きを読む &raquo;'); ?>

index.phpでは次のようにしました。

<div class="post-content">
<?php the_content('Read More &raquo;'); ?>
</div>

さらにカスタマイズする方法については、moreタグの出力ソースを変更する をご覧下さい。

コメント – comments_popup_link()

アーカイブ系ページの場合、コメント数かコメントの可否の表示が一般的だと思います。

  • comments_link() ・・・ コメントへのURLを表示(記事URL+#comments)
  • comments_popup_link() ・・・ コメント数をコメントフォームへのリンク付きで表示

comments_popup_linkの書式

<?php comments_popup_link('zero','one','more','CSSclass','none');?>

引数は左から、「コメントが0件の時」「コメントが1件の時」「コメントが2件以上の時」「aタグにつけるクラス名」「コメント出来ない時」に表示するテキストです。
(コメントが2件以上ある場合の数は%で置換されます)

コメントオープン時だけ表示する場合の例

<?php if ( comments_open() ) : ?>
<p>
<?php comments_popup_link( 'No comments yet', '1 comment', '% comments so far', 'comments-link', 'Comments are off for this post'); ?>
</p>
<?php endif; ?>

comments_popup_script()をテンプレート(head内とか)に書くと、ポップアップ形式で表示するようになります。
ポップアップ表示専用のテンプレート(comments-popup.php)が必要になります。

index.phpではカテゴリーの後ろに追加しました。(ポップアップはなし)

<li class="comments"><?php comments_popup_link('Comment(0)','Comment(1)','Comment(%)','','Comment(Off)'); ?></li>

コメントオープン時だけ表示する場合は次のように書きます。

<?php if ('open' == $post-> comment_status):?>
<li class="comments"><?php comments_popup_link('Comment(0)','Comment(1)','Comment(%)','','Comment(Off)'); ?></li>
<?php endif; ?>

タグ - the_tags()

wordpressのタグ機能は2.3以上から実装されました。
幅広いバージョンにも対応させる場合は、function_exists()で関数が存在するかどうか調べた方が良いです。

  • the_tags() ・・・ リンク付きでタグを表示
  • get_the_tags() ・・・ タグをオブジェクト形式で取得する
  • get_the_tag_list() ・・・ HTML 文字列を返す。PHPソース形式なので表示はechoかprintが必要。

the_tags()の書式

<?php the_tags('before', 'separator', 'after'); ?> 

引数を何も指定しない場合は、カンマ区切りで表示されます。

index.phpでは定義リストを使用してるので、次のようになります。
if文でタグが指定されていない場合に非表示にしています。

<?php if(get_the_tags()):?>
<dl class="post-tag">
<dt>Tags</dt>
<?php the_tags('<dd>','</dd><dd>','</dd>'); ?>
</dl>
<?php endif; ?>

記事編集用リンク - edit_post_link()

あった方が俄然便利な編集リンクを追加します。
edit_post_link()タグは、ログイン状態&編集権限を持っている場合に編集ページへのリンクを表示します。

書式

 <?php edit_post_link('link', 'before', 'after'); ?> 

index.phpはコメントの後につけました。
ログインしてない状態では表示しないので、タグは引数で指定します。

<?php edit_post_link('Edit', '<li class="admin">', '</li>'); ?>

前後一覧ページへのリンク – posts_nav_link()

index.phpやcategory.phpなど、アーカイブ内での前後ページへのナビゲーションリンクを表示します。
個別記事へのリンクとは別のタグなので注意。

posts_nav_link()の書式

<?php posts_nav_link('sep','prelabel','nxtlabel'); ?>

posts_nav_link()は前後ページへのナビゲーションリンクをまとめて表示するタグです。
引数を何も指定しない状態では、中央を「—」で区切られたリンクが表示されます。
タグも指定できるので、画像も使えます。

<?php posts_nav_link(' ', '<img src="images/prev.jpg" />', '<img src="images/next.jpg" />'); ?>

どちらかのラベルしか指定しなかった場合はリンクが表示されないので、
前後どちらか片方だけリンクを表示させるという事も出来ます。

next_posts_link()とprevious_posts_link()はそれぞれ前後どちらか一方のリンクを表示します。

next_posts_linkとprevious_posts_linkの場合

<ul id="pagenavi">
<li class="prev"><?php next_posts_link('&laquo; Previous Entries') ?></li>
<li class="next"><?php previous_posts_link('Next Entries &raquo;') ?></li>
</ul>

posts_nav_linkの場合

<ul id="pagenavi">
<li class="prev"><?php posts_nav_link('','','&laquo; Previous Entries') ?></li>
<li class="next"><?php posts_nav_link('','Next Entries &raquo;','') ?></li>
</ul>

引数の名前とは逆のテキストを入れてるのに注意。

index.php編集後

以上のタグを入れると記事が表示されるようになります。

index.php編集後

編集後ソース

<?php get_header(); ?>
<div id="main">
	<div id="content">
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">
			<h1 class="post-title"><a href="<?php the_permalink() ?>" title="<?php printf(__('%sの全文を表示', 'wtn'), the_title_attribute('echo=0')); ?>"><?php the_title(); ?></a></h1>
			<ul class="post-meta">
			<li class="date"><?php the_time('Y/m/d'); ?></li><li class="category"><?php the_category('&nbsp;'); ?></li>
			<?php if ('open' == $post-> comment_status):?><li class="comments"><?php comments_popup_link('Comment(0)','Comment(1)','Comment(%)','','Comment(Off)'); ?></li><?php endif; edit_post_link('Edit', '<li class="admin">', '</li>'); ?></ul>
			<div class="post-content">
			<?php the_content('Read More &raquo;'); ?>
			</div>
			<?php if(get_the_tags()):?>
			<dl class="post-tag">
			<dt>Tags</dt>
			<?php the_tags('<dd>','</dd><dd>','</dd>'); ?>
			</dl>
			<?php endif; ?>
		</div>
		<?php endwhile; ?>
		<ul id="pagenavi">
		<li class="prev"><?php posts_nav_link('','','&laquo; Previous Entries') ?></li>
		<li class="next"><?php posts_nav_link('','Next Entries &raquo;','') ?></li>
		</ul>
		<?php else : ?>
		<div class="post" id="notfound">
			<h1 class="post-title"><?php _e('404 Not Found', 'wtn'); ?></h1>
			<div class="post-content"><p><?php _e('お探しの記事は見つかりませんでした。', 'wtn'); ?></p></div>
		</div>
		<?php endif; ?>
	</div>
</div>
<?php get_sidebar(); ?>
<?php include (TEMPLATEPATH . "/extra.php"); ?>
<?php get_footer(); ?>

まだcategory.phpなどのアーカイブ系テンプレートは作ってませんが、
カテゴリーページやタグページ等も一応表示されるようになります。

基本は以上なので、これに必要なタグを取得選択して追加・削除すれば、他のテンプレートファイルも作れます。

次回single.php編につづく。