WordPressによるWEBサイト開発2 - テンプレート階層とテンプレートタグ

2012/05/23

WordPress

WordPressを使った企業サイト開発のためには、テーマを構成するテンプレートファイルの構成、ページを構築するHTMLタグの書き方、テーマの中で使用される関数の分類、そしてテーマの見た目を装飾するスタイルシートの書き方についての理解が必要になります。

ジャカルタ

インドネシアのITサービス

インターネット技術の急速な発展と普及により、優秀なIT人材を輩出することで知られるジャカルタのビヌス大学(BINUS)やバンドゥンのバンドゥン工科大学、インドネシアコンピューター大学(UNIKOM)の学生の多くがインターネット・WEB業界やソフトウェア業界を志望するようです。

続きを見る

テンプレートファイルの構成

子テーマフォルダのstyle.cssから親テーマフォルダを指定

WordPressテーマを導入すると、テーマスタイルシートstyle.css(必須スタイルシート)に、コメント形式でテーマの説明を書く必要があり、なかでも「Theme Name」にテーマ名の記述が必須です。
テンプレートファイルの構成
冒頭の「@charset 文字コード」は、外部スタイルシートの文字コードを指定します。

テーマフォルダ内に「screenshot.png」という名前でテーマのスクリーンショットを配置すると、管理画面の「テーマ」の中で表示されます。

テーマをインストールしたら、まず最初に親フォルダと同じ階層に、子テーマ用のフォルダを「親フォルダ名-child」という名前で作成し、親テーマからコピーしてきたテーマスタイルシートstyle.css のTemplateパラメータに親テーマディレクトリを指定します。

親テーマのスタイルシートを引き継ぐ場合にはfunctions.php内に以下のコードを記載します。

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
    wp_enqueue_style( 'onetone-proxxx', get_template_directory_uri() . '/style.css' );

}

テンプレートファイルのカスタマイズ

テーマのテンプレートファイルは、PHPファイルとスタイルシートから構成され、「wp-content/themes」内のテーマフォルダに格納されます。

テーマ用のPHPファイルの中に、1人だけ拡張テーマ関数を集めたfunctions.phpという色違いが居り、これがwp-includes内の関数ファイルと同様に、自動的にWordPressの初期化中にロードされ、WordPressの拡張インターフェイスのような機能を果たします。

テンプレートファイルをカスタマイズする場合は、子テーマフォルダ内に同名でコピーしたファイルをカスタマイズすることにより、先に読み込まれる親テーマのテンプレートファイルを、後に読み込まれる子テーマのテンプレートファイルが上書きします。

ただしfunctions.phpだけは、親のfunctions.phpより先に読み込まれるので、子テーマフォルダにコピーしただけでは上書きされず、同じ関数名だとエラーになるので、子テーマ側の関数名を変えて優先度を上げます。

この例では親の関数の優先度が999なので、子の関数は1000に上げることにより、親関数の後に子関数(_yama付き)を呼びます(優先度の大きいものが後に呼ばれる)。

親テーマのfunctions.phpの関数(抜粋の長さは100)

<?php

//excerpt_lengthというHOOKのタイミングでcustom_excerpt_lengthを先に読み込む。
function custom_excerpt_length( $length ) {
    return 100; 
} 
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );

子テーマのfunctions.phpの関数(抜粋の長さを80に変更する)

//excerpt_lengthというHOOKのタイミングでcustom_excerpt_length_yamaを後に読み込む。
function custom_excerpt_length_yama( $length ) {
    return 80;	
}
add_filter( 'excerpt_length', 'custom_excerpt_length_yama', 1000 );

?>

WordPressのテンプレート階層

WordPressによるWEBサイトの開発は主にテーマとプラグインの開発であり、このとき「ベーステンプレート」「モジュール」「パーツテンプレート」などの定義が曖昧な言葉が登場します。

ベーステンプレートは、WordPressがテーマごとに表示を替えるための下地になります。

  1. front-page.php ⇒ home.php ⇒ index.php : トップページ
  2. single-投稿タイプ.php ⇒ single.php : 個別ページ
  3. カスタムテンプレート名.php ⇒ page-スラッグ.php ⇒ page.php : 固定ページ
  4. category-スラッグ ⇒ category.php : カテゴリー
  5. search.php : 検索結果
  6. archive-投稿タイプ.php ⇒ archive.php : アーカイブ
  7. 404.php : 見つかりません

存在しないファイルに対するリクエストがあった場合、サーバーはレスポンスとしてHTTPステータス404を返しますが、このときブラウザ規定の「ページが見つかりません」というそっけないメッセージよりも、テーマが装備する一体感のある404.phpを表示するほうが親切です。

すべてのテーマテンプレートの階層の最下位にindex.phpがあり、とりあえずはテーマフォルダ直下に最低限index.phpとstyle.cssの2つが存在していればテーマとして成立します。

index.phpはすべてのテンプレートの最大公約数的記述をするところであり、ドメインのルートディレクトリに配置するindex.phpというファイルが「URLの後ろにファイル名を指定しない場合にデフォルトで開くトップページ」を意味するとは異なるため、サイトのトップページ用のテンプレートとしてhome.phpまたはfront-page.phpが用意されています。

企業サイトの場合、トップページ、会社案内ページ、商品紹介ページなど、内容に応じて固定ページ作成時にカスタムテンプレートで1カラムにしたり2カラムにしたり、フォーマットのレイアウトを変えるのが一般的です。

ページを構築するHTMLタグ

テンプレートに記述するHTMLタグには、大きく分けてページ定義タグ、構造化タグ、divタグの3種類があります。

  1. ページ定義タグ(html, head, body)
  2. 構造化タグ(header, footer, nav, article, aside, sectionなど)
  3. divタグ(特に意味がある塊でないレイアウト規定のためにCSSと一緒に使う)

ページ定義タグで大枠のページ構成を定義し、bodyタグ内の構造化タグ(HTML5準拠)やdivタグによって、WEBサイトを「ヘッダー領域」「サイドバー領域」「コンテンツ領域」「フッター領域」の4ブロックに区切ります。

ページを構築するHTMLタグ

パーツテンプレート(モジュールテンプレート)であるheader.phpにはHTMLヘッダーとbody内のヘッダーセクションが、footer.phpにはWEBサイトのフッター部分が保存されます。

テンプレートタグ(WordPress関数)の分類

WordPressのテンプレートであるPHPファイルから実行できる関数はテンプレートタグをも呼ばれ、ベーステンプレートからパーツテンプレートをインクルードするパーツ呼び出しタグ、WordPressの一般設定などの基本情報を表示するbloginfoタグ、WordPressループの条件として使うループタグ、ループの中で投稿やページの情報を表示するデータ取得タグ、bodyタグやarticleタグのid属性やclass属性の値をページの種類によって変えるid属性タグやclass属性タグ、wpタグに分類されます。

get_タグ(パーツ呼び出しタグ)

ベーステンプレートであるfront-page.phpまたはhome.phpまたはindex.phpから「テンプレートタグ名('パラメータ')」形式のテンプレートタグでheaderやfooterなどのパーツテンプレートを呼び出してWEBサイトを構成していきます。

関数の引数は複数パーツを持たせるためのサフィックス(接尾辞)みたいなものです。

<?php get_header(); ?>  //header.phpを読み込む

<?php get_sidebar(); ?>  //sidebar.phpを読み込む

<?php get_sidebar('categories'); ?>  //sidebar-categories.phpを読み込む
<?php get_sidebar('archives'); ?>  //sidebar-categories.phpを読み込む

<?php get_footer(); ?>  //footer.phpを読み込む

ヘッダー、フッター、サイドバーが呼び出すパーツの代表格ですが、これ以外にも以下のようなパーツ呼び出し用のテンプレートタグがあります。

<?php

  get_seach_form();
  get_comments_template();
  get_permalink(4);  //投稿番号4のリンクURLを取得

  <!-- カスタムテンプレートyama.php -->
  get_template_part('yama'); 
  <!-- カスタムテンプレートyama-01.php -->
  get_template_part('yama', '01'); 

php ?>

カスタムテンプレート呼び出し関数get_template_part()の、第一引数であるファイル名(スラッグ)は必須で、第二引数であるサフィックス(接尾辞)は任意です。

yama-01.phpというファイル1個しかなければ、get_template_part('yama-01')でいいのですが、この場合yama.phpというファイルを探してくれません。

get_template_part('yama', '01')にしておけば、最初にyama-01.phpを探して、なければyama.phpを探してくれるので、今後yama-02.php以降が必要になる場合に汎用性が出てきます。

bloginfoタグ(一般タグ)

bloginfoタグでは管理画面で設定したサイトの基本情報を表示できます。

<body>
<h1><?php bloginfo('name'); ?></h1>
<p><?php bloginfo('description'); ?></p>
<ul>

<li><?php bloginfo('url'); ?></li>
<li><?php bloginfo('stylesheet_url'); ?></li>
<li><?php bloginfo('template_url'); ?></li>
<li><?php bloginfo('template_directory'); ?></li>
<li><?php bloginfo('charset'); ?></li>
<li><?php bloginfo('html_type'); ?></li>
<li><?php bloginfo('rss_url'); ?></li>
<li><?php bloginfo('rss2_url'); ?></li>
<li><?php bloginfo('atom_url'); ?></li>
<li><?php bloginfo('pingback_url'); ?></li>

</ul>
</body>

have_タグとis_タグ(条件分岐タグ)

PHPコード「while{~}」はテンプレートタグ「while:~endwhile」と同じ意味であり、PHPコード「if(){~}」はテンプレートタグ「if():~endif」と同じ意味であり、WordPressテンプレートタグではifやelseやwhileなどの条件文の後ろをコロンで締め、条件部分を視覚的に分かりやすくすることができます。

if(条件){
    処理1;
}else{
    処理2;
}
if(条件):
    処理1;
else:
    処理2;
endif;

HTMLの中にPHPを埋め込むWordPressテーマのテンプレートファイルではコロン締め、functions.phpのようなPHPだけの記述の際は通常の{}で書きます。

PHP的書き方

<?php if(have_posts()){ ?>
	<?php while(have_posts()){ the_post(); ?>
		<h2><?php the_title(); ?></h2>
	<?php } ?>
<?php } ?>

WordPressテンプレートタグ的書き方

<?php 
if(have_posts()):
    while(have_posts()): the_post(); 
?>
	<h2><?php the_title(); ?></h2>
     <?php the_content(); ?>
<?php 
    endwhile; 
endif; 
?>

「if(have_posts()):」でエントリーが存在すれば「while(have_posts()):」でエントリーが存在する限りループし、「 the_post();」で投稿情報をグローバル変数$postから取得し、「the_title();」タイトルと「the_content();」コンテンツを表示します。

無限ループにならないのは、the_post()を実行するたびに、$postに格納された投稿を取り出すと同時に削除するからであり、投稿が空になるとhave_post()がfalseになり、ループが終了します。

have_posts()以外に条件分岐用のテンプレートタグとしてis_タグがあります。

<!php
  is_home();  //トップページかどうか調べる
  is_single(); //個別記事ページsingle.phpかどうか調べる
  is_page();  //固定ページpage.phpかどうか調べる
  is_category();  //カテゴリページcategory.phpかどうか調べる
  is_search();  //検索結果ページsearch.phpかどうか調べる
  is_user_logged_in();  //ユーザーがログインしているかどうか
  is_admin();  //管理画面かどうか
  is_main_query();  //現在のクエリがメインクエリかどうか
?>

the_タグ(ループの中で使うタグ)

条件分岐のwhileで繰り返しているときの記事情報を、DBのデータから読み込み表示するタグです。

上記のthe_title()とthe_content()以外にエントリー取得用のループ内で使うテンプレートタグは以下のようなものがあります。

<?php
  the_excerpt(); :記事の抜粋
  the_permalink(); :記事のリンク
  the_date(); :記事の作成日(同一日複数記事の場合最初の記事にのみ表示)
  the_time(); :記事の投稿日
  the_author(); :記事の著者
  the_category(); :記事のカテゴリ
  the_tags(); :記事のタグ
  the_post_thumbnail(); :記事のアイキャッチ画像
  the_search_query(); :検索キーワードを表示
?>

あたりまえですが、DBから取得するのはコンテンツだけなので、CSSのための開始終了タグは別途定義する必要があります。

<h2 class="title"><?php the_title(); ?></h2>
<div class="categories"><?php the_category(); ?></div>
<section class="content"><?php the_content(); ?></section>

またthe_time()はループの中で使用する必要があるとCodexに明記されているにもかかわらず、日付アーカイブページのタイトル表示に使用します。

本来ならwp_title()で表示できるべきですが、表示される日付フォーマットが日本語対応が不十分であるため、代用としてthe_time()を使用します。

<?php if(is_month()): ?>
    //本来はループの中で使用するが、月別アーカイブならその月の日付を表示する。
    <?php the_time('Y年m月'); ?> 
<?php else : ?>
    //現在表示しているページのタイトルで個別記事なら投稿タイトル、カテゴリアーカイブページならカテゴリ名
    <?php wp_title(''); ?> 
<?php endif; ?>	

id属性タグとclass属性タグ

上述のようにWordPressはページの種類ごとに表示を替えるためのテンプレートが分かれており、ヘッダやフッタなどはパーツテンプレートとして分割管理します。

パーツテンプレートであるheader.phpのbodyタグのクラス属性をページの種類のよって変化させるのがbody_class()関数であり、このフロントページの例ではログイン中の場合はhomeやlogged-inやadmin-barなど使いそうもないやつまでゾロゾロくっついています。

ちなみに個別記事はsingle、アーカイブはarchive、カテゴリーにはcategoryになります。

//HTMLソース
<body <?php body_class(); ?>>

//フロント表示
<body class="home blog logged-in admin-bar no-customize-support">

//個別ページ表示
<body class="single single-post postid-1 single-format-standard logged-in admin-bar no-customize-support">

WordPressループの中で投稿の種類によってクラス属性を変化させるのがpost_class()関数です。

//HTMLソース
 <article id="post-<?php the_ID(); ?>" <?php post_class('news'); ?>>
 
 //表示
 <article id="post-1" class="news post-1 post type-post status-publish format-standard has-post-thumbnail hentry category-1">

wp_タグ

wp_title()は現在表示しているページのタイトルで、個別記事なら投稿タイトル、カテゴリアーカイブページならカテゴリ名となります。

wp_title();  //現在のページのタイトル
wp_enqueue_script();  //JavaScript読み込みの重複を防ぎ最適のタイミングで読み込む
wp_list_categories($args);  //カテゴリーページへのリンク一覧をli囲みで表示 
wp_nav_menu($args);  //カスタムメニューの表示

連想配列である引数$argsに値をセットし、表示のされかたを調整します。

$args=array(
    'title_li'=>'カテゴリナビ',
    'show_count'=>true
);
wp_list_categories($args);

カスタムメニュー表示も同じように引数で調整します。

$args=array(
    'menu'=>'global-navigation',  //管理画面で作成したメニューの名前
    'container'=>false  //ulタグを囲んでいるdivタグを削除
);
wp_nav_menu($args);

WordPressテーマ開発のルールとして、headタグ内にwp_head関数を、footerタグ内にwp_foot関数を記述しておきます。

テーマの利用者がインストールするプラグインにはwp_head関数やwp_footer関数によって呼び出されるものもあり、ヘッダー読み込み時やフッター読み込み時に、実行させたいプラグインを開発できるようになります。

<head>
wp_head();  //中身はdo_action('wp_head')であり、head終了タグの直前でwp_headアクションを実行
</head>

<footer>
</footer>
wp_footer();  //中身はdo_action('wp_footer')であり、body終了タグの直前でwp_footerアクションを実行
</body>

wp_enqueue_script('スクリプトのハンドルネーム')関数で、JavaScriptをプラグインごとの重複読み込みを回避し、適切なタイミングで読み込みます。

//HTMLソース
<?php wp_enqueue_script('jquery'); ?>

//表示
<script type='text/javascript' src='http://localhost/wordpress/wp-includes/js/jquery/jquery.js?ver=1.11.3'></script>

スタイルシートによるページ装飾

スタイルシートはheadタグ(header.php)内に、テンプレートルートからCSSを指定します。

<link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/style.css" type="text/css" />

WEBサイトが複雑になってくるとstyle.cssが大きくなるので、ベースのスタイルはbase.cssと分ける場合がありますが、ベースに明確な定義があるわけではありません。