WordPressのテーマ作成で気をつけてほしいこととか・アンチパターンとか。

WordPressのテーマ作成で、ありがちなアンチパターンです。

  • テンプレート内にロジックは書かない
  • query_postsは使わない。
  • wp_head(),wp_footer()はちゃんと書く
  • .alignleft, .alignright等のCSSは定義する
  • JavaScriptは、wp_enqueue_scriptを使って読み込む
  • 更新のあまりないページでも静的にせず、固定ページに入れる

テンプレート内にロジックは書かない

関数はここから引用。
http://www.2ndgate.jp/archives/614

before

<ul>
<?php while(have_posts()):the_post();?>
<li>
<?php the_post_thumbnail();?>
<p>ファイルサイズ:
<?php
$attachment = get_post_thumbnail($post->ID);
$attachment_path = get_attached_file( $attachment );
$attachment_filesize = filesize($attachment_path);
$s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
$e = floor(log($attachment_filesize)/log(1024));
echo sprintf( '%.1f '.$s[$e], ( $attachment_filesize/pow( 1024, floor($e) ) ) );
?></p>
</li>
<?php endwhile;?>
</ul>

 

読みづらいし、HTMLの修正とかしづらい…

after

テーマ内に、functions.phpという名前のファイルを用意すると、テンプレートより先に、自動的に読み込まれます。

functions.phpに以下のような関数を用意します。

function byteConvert( $bytes ){
$s = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
$e = floor( log($bytes)/log(1024) );
return sprintf('%.1f '.$s[$e], ( $bytes/pow( 1024, floor($e) ) ) );
}

function my_post_thumbnail_filesize($post_id) {
$attachment = get_post_thumbnail($post_id);
$attachment_path = get_attached_file( $attachment );
echo byteConvert(filesize($attachment_path));
};

テンプレート側はこんなかんじにします。

<ul>
<?php while(have_posts()):the_post();?>
<li>
<?php the_post_thumbnail();?>
<p>ファイルサイズ: <?php my_post_thumbnail_filesize($post->ID);?></p>
</li>
<?php endwhile;?>
</ul>

としておくと、HTML編集も楽だし、後々ファイルサイズの部分を変更することになっても、テンプレートは触らなくても大丈夫。

WordPressに限ったことでもない気がしますが、テンプレート側には可能な限りロジックは書かないでおくと、HTMLの構造とかが把握しやすいです。

query_postsは使わない

これはテンプレート内で使っちゃいけません! じゃぁなぜ使えるんだろう

テンプレート上で表示する記事を変更するので、ページング周りがおかしくなったり(まだ記事があるはずなのにページが見つかりませんになったり、記事がないはずのページにアクセスできてしまったり。)します。 メインクエリーの代わりにWP_Queryでやっても同様の事態に見舞われます。なので、メインクエリーをpre_get_postsを使って変更してあげましょう。

before

[php title=”category-hoge.php”]
<?php query_posts($query_string . ‘&posts_per_page=4’);?>

<div class=”entries”>
<?php while(have_posts()):the_post();?>
<article>
<h1><?php the_title();?></h1>
<?php the_content();?>
</article>
<?php endwhile;?>
</div>
[/php]

after

[php title=”functions.php”]
add_action( “pre_get_posts”, “my_pre_get_posts” );
function my_pre_get_posts( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_category( “hoge” ) ) {
$query->set( ‘posts_per_page’, 4 );
}
}
[/php]

[php title=”category-hoge.php”]
<div class=”entries”>
<?php while(have_posts()):the_post();?>
<article>
<h1><?php the_title();?></h1>
<?php the_content();?>
</article>
<?php endwhile;?>
</div>
[/php]

あ、管理画面からここら辺がいじれるプラグイン作りました。各投稿タイプ・タクソノミーのアーカイブでの表示件数を変更する「Powerful Posts Per Page」をリリースしました。

wp_head(),wp_footer() はちゃんと書く

プラグインやWordPress本体が出力するmetaタグ、cssやJavaScriptはここで出力されます。入れないとプラグインが上手く動かなかったりします。

.alignleft, .alignright等のCSSは定義する

.alignleft, .alignright,.aligncenter,.wp-caption等WordPressのビジュアルエディタが出力するクラスがあります。WordPressのビジュアルエディタは、インラインスタイルでCSSを定義しないので、これをテーマ側のCSSでも定義してやらないと、管理画面では右寄せにしたはずの画像がそうなっていない等の不具合が発生します。

また、WordPressには、editor-styleといってビジュアルエディタにCSSを適用できる機能があります。

ビジュアルエディタの部分はiframeになっていて、そこのbodyタグは、
[html]
<body id=”tinymce” class=”mceContentBody content post-type-page wp-editor”>
[/html]
のような感じになっていますので、テーマの方でも、
[php]
<div class=”content”>
<?php the_content();?>
</div>
[/php]
としておくと、editor-styleをそのままテーマ側でも使ったりしやすいです。

デフォルトテーマの editor-style.cssが参考になります。というかほとんどそのままコピペしてもいいくらいです。

JavaScriptは、wp_enqueue_scriptを使って読み込む

before

[php title=”header.php”]
<?php wp_head();?>
<script src=”<?php bloginfo(“stylesheet_directory”);?>/js/jquery.js”></script>
<script src=”<?php bloginfo(“stylesheet_directory”);?>/js/hoge.js”></script>
[/php]
等と、書いてしまうと、WordPressのプラグインなどで、jQuery等を使っている場合(例えば Contact Form 7とか)、wp_headから出力されて、2重に呼ばれてしまいます。

after

[php title=”header.php”]
<?php
wp_enqueue_script(‘jquery’);
wp_enqueue_script(‘hoge’, get_stylesheet_directory_uri() . ‘/js/hoge.js’);
wp_head();
?>
[/php]
などをwp_headより前、もしくはfunctions.php等で、書くと、wp_headからscriptタグが出力されます。

また、wp_enqueue_scriptの第3引数に配列で、依存するライブラリを書いておくと、そのライブラリを先に呼んでから呼んでくれるようになります。
[php]
wp_enqueue_script( ’hoge’, get_stylesheet_directory_uri() . ‘/js/hoge.js’, array( ‘jquery’ ));
[/php]

WordPressに内蔵されているJavaScriptって結構たくさんあるようです。 backbone.jsとかunderscore.jsとかはよくお世話になりますね。
Default Scripts Included and Registered by WordPress

更新のあまりないページでも静的にせず、固定ページに

phpのincludeとかで、ヘッダー、フッターなどを管理して静的サイトを作ることも多いですが、それをそのまま持ち込むと、ヘッダーを2重管理したり、js周りの読み込みの管理が煩雑になりがちです。

page-hoge.php等のテンプレートで、各個別ページごとのテンプレートも作れるので、ちょっとがんばって突っ込んでおきたいです。
CMSの管理に乗るので、Google XML Sitemaps等のプラグイン等の恩恵が受けやすくなります。

WoedPress簡単だって言われておりますが、大まじめにやろうと思うと気をつけなきゃいけないコトは実は多いです。規模が大きくなるとプラグインも増えたり、WordPressの機能を使い倒す場面も多いのでテーマもちゃんと作っておくと不具合が出にくいです。