Twenty Twelve を使い始める前に知っておきたいこと

Twenty Twelve は近々リリースされる WordPress 3.5 の新しい標準テーマで、3.5 のよりも一足先にリリースされています。 このブログもこの 11月より Twenty Twelve ベースのテーマに衣替えしました。 その中で気付いた点などまとめましたので、Twenty Twelve を使ってみようという方は是非ご一読ください。

Mobile-First Responsive Web Design

Twenty Twelve はレスポンシブ Web デザインを採用しており、更にモバイルファーストのコンセプトで実装されています。 具体的にどういうことかと言うと、CSS のメディアクエリを使ってブラウザのサイズによって表示内容を変えているのですが、スタイルシートファイル (style.css) の中で以下の順でスクリーン用スタイルが定義されています。

  1. 幅の狭いスクリーン用のスタイルをメディアクエリなしで定義
  2. min-width: 600px を指定して幅広いスクリーン用のスタイルを定義
  3. min-width: 960px を指定して更に幅広いスクリーン用のスタイルを定義。ここからは背景が広がるだけ。

つまり一番幅の狭いスクリーン (=モバイルデバイス) 用の定義を最初に行い、スクリーン幅の広いデバイスについては追加でスタイルを足すというやりかたです。 何故、このようにモバイルデバイスを優先するかというのは様々なところ (例えばここここ) で説明されているのでここでは繰り返しません。 注意したいのは PC 用のレイアウトを行うときはメディアクエリの条件式でくくられたスタイルに手を入れなければならないということです。

IE7/IE8 ユーザーは Twenty Twelve Version 1.0 だと悲しいことに

ここでピンと来た方もいらっしゃるかも知れませんが、Internet Explorer の 8 以下のバージョンはメディアクエリをサポートしていません。 なので、Twenty Twelve の Version 1.0 を使ったサイトを IE7/IE8 でブラウジングするとメニュー表示がモバイル用と同じになっちゃいます。 このあたりデモサイトではきちんと表示されるのですが、あれはどうやら手が入っているようです。 普通に Version 1.0 を入れると IE7/IE8 では下のような表示になります。 メニューに注目してください。 (それでも微妙な IE 個別対応はしているので 2カラムレイアウトにはなっています)

Twenty Twelve on IE7/IE8

Twenty Twelve 1.0 をリリースした時点では IE7/IE8 に関してはモバイルデバイスと同等のルックスを提供する方針だったようです。 しかし、私のサイトの場合、閲覧に使われているブラウザの中での IE8 以下バージョンの割合はサイトアクセス全体の 2割強で無視できない数字であり、きちんとしたメニューバーを表示したいところです。 これはグローバルで見ても同様だったようで、 最初の方針は不評を買い結局 IE8/IE7 のナビゲーションメニューがきちんとサポートされることになりました。 WordPress 3.5 公式リリースには反映されるはずですが、すぐに対応が必要な方は既に修正済みとなっている WordPress 3.5β2 の中の Twenty Twelve のみを取り出して使うと良いでしょう。 (3.5β2 そのものを使うことはお勧めしません。もっと言うと多分あなたがこの記事を見ている頃には 3.5 がリリースされているような気がしますw (注: 3.5 は 12/5 リリース予定))

IE6 はさらに悲しい

更にいまだに IE6 を使用されている方々もいます。 そこで手元の IE6 を使ってテストしたところ、Twenty Twelve テーマそのままではフォントの問題で日本語が表示されませんでした。

いまどき IE6 を使っている方々はきっとレイアウトなど気にしないのだろうと推測できますが、さすがに内容が見えるぐらいにはしておきたいところです。 「スターハック」という IE6 のみのスタイルを変える有名なテクニックを使ってフォント指定に ‘MS Pゴシック’ を追加します。 なお、Twenty Twelve のスタイルシートに直接手をいれるのではなく、まずは子テーマを作ってカスタマイズするのがお勧めです。

* html body {
  font-family:  "\FF2D\FF33\20\FF30\30B4\30B7\30C3\30AF", Osaka, Helvetica, Arial, sans-serif;
}

* html body.custom-font-enabled {
  font-family:  "\FF2D\FF33\20\FF30\30B4\30B7\30C3\30AF", Osaka, "Open Sans", Helvetica, Arial, sans-serif;
}

* html .entry-content code,
* html .comment-content code,
* html .entry-content pre,
* html .comment-content pre {
        font-family: "\FF2D\FF33\20\FF30\30B4\30B7\30C3\30AF", Osaka, Consolas, Monaco, Lucida Console, monospace;
}

ついでに Osaka フォントも加えて、(意味がないと思われる) 元のフォント指定も残していますが、この辺は詳しくないし、所詮 IE6 用スタイルということで深く考えないことにします。 また、style.css の先頭に念のため以下の行を入れておきました。

@charset "utf-8";

これで無事 IE6 でも日本語が表示されるようになりました。

フォントサイズ指定について

style.css の中を覗いてみるとフォントサイズの指定には rem が使われています。 これは CSS3 から追加された単位で、root + em すなわち root 要素のフォントサイズに対しての相対値になります。 最初に以下のように指定されているので、1rem = (16px * 87.5%) = 14px となります。 ここで 16px は (最近の主要な) ブラウザのデフォルトフォントサイズです。 このようにユーザー環境のフォントサイズを考慮して絶対値でなく相対値でサイズ指定するのが最近の標準的なやり方のようです。

html {
        font-size: 87.5%;
}

さて、これ以降実際のサイズ指定には 1つの要素に対して下のように px 指定と rem 指定の 2つの指定が行われています。

    font-size: 11px;
    font-size: 0.785714286rem;

このように指定方法の異なる 2行をこの順で書いておけば rem を認識しない古いブラウザは px 値、認識すれば rem 値でスタイリングされます。 rem 値が一瞬よくわからない小数値になっていますが、先の 1rem = 14px で計算した値となっています。 11/14 ということですね。 自分で手を入れるときもこのスタイルを踏襲しましょう。

幅の指定について

もう一つわけのわからない小数値に幅の指定があります。 こんな感じの記述です。

    width: 65.104166667%;

Twenty Twelve では 960px 以上になるとコンテンツの幅は広がらず背景が広がるようになっています。 レスポンシブであるために上のように width が%値で指定されていますが、これは 960px になったときのピクセル値を元に計算された値で、この例では最大表示で (960px x 0.65104166667 = 625px) ということです。

IE 対応

β2 での変更で HTML タグの記述は以下のように出力されます。

<!--[if IE 7]>
<html class="ie ie7" dir="ltr" lang="ja">
<![endif]-->
<!--[if IE 8]>
<html class="ie ie8" dir="ltr" lang="ja">
<![endif]-->
<!--[if !(IE 7) | !(IE 8)  ]><!-->
<html dir="ltr" lang="ja">
<!--<![endif]-->

ここで指定されている .ie/.ie7/.ie8 をセレクタとして使って実際のスタイリングは css/ie.css の中で行われています。 .ie は IE7 と IE8 の 2つに対してのみ適用したいスタイルを指定するときに使います。 先のスターハックと合わせれば IE6/IE7/IE8 向けの個別調整ができますね。 まあ、Mobile First Responsive Web Design の考え方からするとピクセル単位の配置にまでこだわる必要はないと思うので、ほどほどにして良いと思います。

その他

Twenty Twelve は HTML のソースも CSS ファイルも比較的読みやすいと思いますので、気に入ったら是非カスタマイズに挑戦してみてください。 それと、ページ編集画面からテンプレートとして ‘Front Page Template’ や ‘Full-width Page Template, No Sidebar’ が選べるようになっていますが、これらのソースを見ると Widget エリアの使い方などの参考になると思います。

さて、このブログのテーマも Twenty Twelve ベースのものに変えました。 しかし、広告を入れると元があっさりしすぎているのでもう少し線を濃くしたりする等の調整が必要なようです。 また、そもそも英語で見栄えが良くても日本語になっただけで印象が変わってしまう、というのもあります。 まだまだ調整は続く、という感じです。

また、さんざん Mobile First Responsive Web Design と強調した割りに、結局スマートフォン向けは WPtouch Pro の使用を継続しています。 Twenty Twelve のモバイル向け表示時のメニューボタンが気に入らないのと、モバイル回線でのレスポンスがどうなるか見えないのが理由ですが、折を見て一本化できるか検討してみようとは思っています。 ナビゲーションメニューのスタイリングの仕方を覚えねばということですかねぇ。

コマンドラインから WordPress 関連処理を実行する

FC2 ブログで行ってたつぶやきアーカイブを hetarena.com に移すために、コマンドラインで実行するための記事投稿用プログラムを書く方法を調べてみました。 wp-cron ではなく OS の crontab を使用したいので、単独の PHP プログラムファイルとして動かしたいのです。

結論からすると簡単で wp-load.php をプログラムの最初に読み込めば良いです。 参考にしたのはこちらの記事ですが、投稿を作成する程度であれば特に $_SERVER を設定しなくても動きました (→ マルチサイト化されていると $_SERVER を設定しなければ動きませんでした。追記参照)。 以下サンプルコードです。 コマンドラインから実行すると 7/7 付けの投稿が作成されます。 使用する場合はご自分の環境に合わせて修正してからお試しください。

#!/usr/bin/php
<?php

//require the WP bootstrap
require_once('/usr/share/wordpress-ja/wp-load.php');

class WP_Command_Line {

  public function __construct() {
    //nothing here
  }

  public function main() {

    $post = array (
      'post_content'   => 
        "<p>これはインポートされた記事です。</p>\n<p>よろしく!</p>",
      'post_type'      => 'post',
      'comment_status' => 'closed',
      'ping_status'    => 'closed',
      'post_status'    => 'publish',
      'post_author'    => 2,
      'post_title'     => 'テスト用記事',
      'post_date'      => '2012-07-07 00:00:00',
      'post_category'  => array(6)
    );
    $e = wp_insert_post($post, true);
    if (is_wp_error($e)) {
      print $e->get_error_message();
    }
    else {
      print "Post ID = " . $e . "\n";
    }
  }
}

$importer = new WP_Command_Line();
$importer->main();

wp_insert_post の Tips も簡単に紹介しておきます。

  • $post->post_date を設定しなければ実行時の時刻で記事が作成されます。
  • $post->post_author や $post->post_category は既に存在するユーザ/カテゴリーの ID を渡します。 カテゴリーは配列を渡します。
  • 記事 ID 指定で追加したい時は $post->import_id に ID をセットします。$post->ID は更新の時に使います。

詳しくは wp_insert_post のリファレンスをご確認ください。


2012.7.28 追記
マルチサイト化されていると $_SERVER の設定が必要です。以下の様な感じで動きました。

$_SERVER = array(
  "HTTP_HOST" => "hetarena.com",
  "SERVER_NAME" => "hetarena.com",
  "REQUEST_URI" => "/",
  "REQUEST_METHOD" => "GET"
                 );

内部リンクを壊さずに FC2 ブログの記事を WordPress にインポートする

内部リンク切れを起こさずに FC2 ブログを WordPress サイトに移行する際の手順です。 ブログ記事番号を合わせることで、FC2 ブログからの個別記事へのリダイレクトも可能なようにします。 ある程度プログラムや HTTP、HTML の知識がある人向けで、説明を端折っている部分もあります。 スクリプトプログラム等もダウンロードできるようにしていますが、環境に合わせて修正が必要となるので最終的には自己責任でご利用ください。 WordPress のバージョンは 3.3、3.4 で試していますが、Movable Type and TypePad Importer のバージョン (0.4) の方が重要です。 これ以降の説明はホスト名として実際に私が行った blogger323.blog83.fc2.com (FC2) と hetarena.com (WordPress) を使用します。

以下の条件で移行を行います。

  • http://blogger323.blog83.fc2.com/blog-entry-NNN.html を https://hetarena.com/archives/NNN に対応させます。(追記: 他のパーマリンク形式が良い人はコメント欄参照。)
  • FC2 にこれまでアップロードしたファイルは https://hetarena.com/oldimages/ の下に置きます。

手順の概要は以下の通りです。

  1. FC2 ブログでエクスポートした記事と sitemaps.xml を使用して、各記事に ID (先述の URL 内の NNN の部分) を付与したエクスポートデータを作成します。
  2. 記事中の内部リンクの変換を行います。
  3. Movable Type and TypePad Importer を一部変更し、ID を読むようにしてから記事をインポートします。
  4. 画像の引越し、FC2 のリダイレクトの設定を行います。

インポートするデータの作成

実際の手順では先の 1. 2 を合わせてプログラムで処理しました。 FC2 ブログの記事をエクスポートし、UTF-8 に変換して blogger323.txt として保存します。 続いて http://blogger323.blog83.fc2.com/sitemaps.xml をファイルとして保存します。 こちらの perl スクリプトをダウンロードし、先の 2つのファイルと同じディレクトリに置いて以下を実行します。

perl fc22wp.pl blogger323.txt > blogger323_wp.txt

これで「ID: 」の行が足され、更に内部リンクの変換が行われます。 perl のスクリプトについて簡単に説明すると以下の処理をしています。

  • blogger323.txt の「DATE:」行を sitemaps.xml の「<lastmod>」の日時とマッチさせ、記事番号の含まれる「ID:」行を挿入する。
  • blog-entry-NNN.html を archives/NNN に変換
  • blogger323.blog83.fc2.com を hetarena.com に変換
  • http://blog-imgs*.fc2.com/b/l/o/blogger323/ を /oldimages/ に変換

使い捨てで書いているので使用する際は「blogger323」、「hetarena.com」の含まれている行を適切に修正し、処理内容を確認してから使用してください。 まあ、短いプログラムなので見ていただければ perl を知らなくても何をしているか想像がつくと思います。

インポートの実行

WordPress に標準でついてくる「Movable Type and TypePad Importer」(Version 0.4) を使用しますが、そのままだと「ID:」行を読んでくれません。 そこで movabletype-importer.php に以下の修正を行います。 (wp-content/plugins/movabletype-importer/ の下にあるファイルにこのパッチファイルを当てても良いですが、WordPress 管理画面の「プラグイン編集」から修正するのがお手軽です)

--- movabletype-importer.php.orig       2011-01-15 09:53:03.000000000 +0900
+++ movabletype-importer.php    2011-08-02 20:22:59.000000000 +0900
@@ -388,6 +388,10 @@
                                $slug = trim( substr($line, strlen('BASENAME:')) );
                                if ( !empty( $slug ) )
                                        $post->post_name = $slug;
+                       } else if ( 0 === strpos($line, 'ID:') ) {
+                               $post_id = trim( substr($line, strlen('ID:')) );
+                               if ( !empty( $post_id ) )
+                                       $post->import_id = $post_id;
                        } else if ( 0 === strpos($line, 'STATUS:') ) {
                                $status = trim( strtolower( substr($line, strlen('STATUS:')) ) );
                                if ( empty($status) )

import_id はまともに公式解説されていないパラメータなのですが、更新のときは $post->ID に、新規のときは $post->import_id に記事 ID をセットして wp_insert_post を呼ぶと希望通りの ID で記事が更新/作成されます。

安全を期すならば blogger323_wp.txt をインポートする前に記事ID の大きなダミーデータを 1つ作成してインポートしておきます。 import_id で指定した番号の記事が存在すると既存最大 ID + 1 の番号が振られて記事が作成されてしまうのですが、こうしてダミーデータを入れておけば万が一既に記事が存在していたとしてもダミーデータの後ろの番号で作成され、続く記事のインポートに影響を与えません。

そのほかもろもろ

他にもいくつか実行しておくべきことがあります。

  • WordPress でパーマネントリンク設定を行って archives/NNN 形式を選んでおきます。
  • FC2 にアップロードされているファイルをダウンロードして WordPress ディレクトリの下の oldimages の中に置きます。 ダウンロードするファイルが多い場合は何かツールを使うなりしてダウンロードしましょう。 (私は HTML からリンクを取り出して wget を回すスクリプトを書いたような気がします)
  • RSSフィード読者向けに FC2 側に移転告知エントリを一つ書いておく必要があると思います。 FeedBurner を使っていれば、Original Feed URL を変更することで読者の手を煩わせることなく引き続きフィードを提供することができます。 しかし、この場合もリーダー上で既読情報等がリセットされるようなので告知をしておいた方が良いでしょう。
  • どこまでやるかという問題になるのですが、ここまでの手順で救えるのは個別記事 URL です。 カテゴリーやタグつき記事に対してのリンクが記事中に大量に埋め込まれている場合、それらへの手当ても必要かも知れません。 一つの手として Redirection プラグインを使う方法を紹介しておきます。 Redirection プラグインでは正規表現も使えるので、例えば「/\?tag=(.*)」→「/?s=$1」みたいなルールを作るとかつてタグで指定していた単語での検索結果を表示するようになります。
  • WordPress サイトの準備が整ったら FC2 テンプレートに meta refresh でリダイレクトする設定を入れます。 あと rel="canonical" の <link> タグも入れておいた方が良いでしょう。

最後の FC2 テンプレートの件については説明が必要ですね。 まずはリダイレクトは以下の記述を <head> セクションに追記します。 (実際は改行なしで書いています)

<meta <!--index_area--><!--/index_area--> http-equiv="refresh" 
content="0;URL=https://hetarena.com/<!--permanent_area-->
<!--topentry-->archives/<%topentry_no><!--/topentry--><!--/permanent_area-->" />

リダイレクトの設定についてはこちらの記事を参考とさせていただきました。 続いて <link> タグですが、以下の記述を同じく <head> セクションに追記します。

<!--permanent_area--><!--topentry-->
<link rel="canonical" href="https://hetarena.com/archives/<%topentry_no>" />
<!--/topentry--><!--/permanent_area-->

ところで

hetarena.com を立ち上げてからこれまでは FC2 ブログを Twitter のつぶやきアーカイブ用に使っていたのですが、最近、WordPress のカスタム投稿タイプを使えば hetarena.com 側でアーカイブしてもブログ記事と混ざらないことに気づき、FC2 ブログの方は閉鎖することにしました。 そんなこともあってこんな記事を書いてみたのでした。 ちなみにつぶやきアーカイブはこちらです。


コメントいただいたので、ちょっと追記

実行例を挙げておきます。 まずコマンドプロンプトを開きます。 アクセサリの下にありますが、スタートメニューで cmd.exe と入力してもコマンドプロンプトを実行できます。 まずディレクトリを作成します。まあ、ここはエクスプローラーで実行しても良いですが。

C:\Users>blogger323>mkdir c:\temp
C:\Users>blogger323>cd \temp
C:\temp>

強調部分が入力するところです。 ここまでで C:\temp フォルダができているので必要なファイルをそこに入れます。 そして perl コマンドを実行します。

C:\temp>perl fc22wp.pl blogger323.txt > blogger323_wp.txt

これで C:\temp フォルダの中に blogger323_wp.txt というファイルができます。

WordPress のカスタマイズを始める前に知っておくべきこと

はじめに

WordPress のカスタマイズを考えている方向けに以下の項目をまとめてみました。

  • 自分自身が WordPress でカスタマイズを始めた頃に、知っていたら作業が捗っただろうと思われること
  • WordPress サイト構築作業関連での私の個人的なお勧め

WordPress を導入しようと考えているぐらいなので、IT系のスキルがそれなりにある読者を前提としています。 また、ブログ用途として使おうと考えている方向けです。

CSS 中心のカスタマイズがお勧め

世の中には自作テーマに関するブログ記事が溢れていますが、まずは標準テーマの Twenty Ten や Twenty Eleven をベースに CSS で外観を変更するのがお勧めです。 ご存知のように Web ページの論理的構造は HTML、視覚的な構造は CSS という役割分担になっていますが、ブログの論理構造なんてたかが知れているわけで、特殊用途でない限り標準テーマをベースにすれば十分です。 もちろん、余裕があって興味のある人は一からテンプレートを作れば良いと思うのですが、その時も標準テーマの構成を理解しておくことが役に立つはずです。

一からのテーマ作成をお勧めしない理由はもう一つあります。 WordPress を使ったサイト構築に不可欠な各種プラグインは簡単に言ってしまえば、フック/コールバック関数の固まりなのですが、呼ぶべき関数を適切な場所で呼んでいないテンプレートではプラグインが動作しなくなってしまいます。 こんなマナーを覚えてフルスクラッチでテンプレートファイルをつくるよりは標準テーマの style.css の修正を集中してやった方が効率はずっと良いです。

CSS をいじろうとすると、どんな id、class が使われてマークアップされているかが重要ですね。 Twenty Ten でどうなっているかを別記事にまとめます (→ 追記: グズグズしていたら Twenty Twelve の時代になってしまったので企画倒れとなりました…)。 Twenty Eleven をベースとしたい場合は自分で調べてみてください。

ブログの外観は大事だと思うので、CSS のカスタマイズは気が済むまでやりましょう。 私の場合、スキルと時間が足りてないので、このあたりで妥協してしまっていますが…。

ちょっと断り書き

以下、公式情報へのリンクを記載していますが、残念ながら日本語化された公式情報は英語のものよりも古いことが多い (ひどい時は日本語版が存在しない) ので、英語版の方をリンクしておきます。 必要ならば、ページに表示されている「日本語」を辿って日本語版の方も確認してみてください。

テンプレート階層

それでも CSS で全て解決するわけではないので、テンプレートファイル (*.php) に手を入れる必要は出てきます。 広告入れたり、アクセス解析入れたり、みたいな時ですね。

で、この時にどこを直したら良いかを知るにはテンプレート階層とモジュール構成を理解しなければなりません。 表示されるページの種類によって使用されるテンプレートファイルが異なるのですが、このテンプレートファイルの選択は階層的に行われ、最低 index.php があればページの表示はできるという構造になっています。 まずすべきなのは公式情報を読み、この図の意味を理解することです。

Twenty Ten も Twenty Eleven もシングルポストなら single.php、固定ページなら page.php が使用されます。 ここで、例えば page.php ファイルを削除してしまうと、固定ページの表示には index.php が呼ばれることになります。 また、特定の固定ページのみ異なるテンプレートを使用したいのであれば、page-$slug.php か page-$id.php ($slug はスラッグ、$id はページ ID) を新たに作成すれば良いことがわかります。

モジュール化

しかし、標準テーマのディレクトリには、先の階層図には記載されていない名前のファイルが存在します。 これがどのように使用されるかを把握するには、テンプレートファイルのモジュール化についての理解が必要です。 テンプレートファイルはモジュール化されていて、例えば single.php でも page.php でもヘッダー表示には get_header() が呼ばれ header.php が使用されます。 (ここでいう「ヘッダー」は HTML の <head> + <body> の最初、すなわちページ上部までを指します)

なので、ページ上部に広告を表示したければ、header.php を編集するだけで、サイト全体に表示されるようになります。 このように get_* として使えるのは header/footer/sidebar があります。

ただし、標準テンプレートの構成を理解するには header/footer/sidebar だけでは不十分で更に get_template_part() を使った呼び出しを理解する必要があります。 例えば、Twenty Ten の loop-single.php は single.php 内のループ処理中で以下のように呼び出されています。

get_template_part( 'loop', 'single' );

同様に Twenty Eleven の single.php を見てみると、投稿表示部分では以下の形式で投稿のフォーマット (フォーマットについては後述) に従ったマークアップ用テンプレートファイルを呼び出しています。

get_template_part( 'content', get_post_format() );

このあたりの構造を理解してテーマディレクトリ内の各ファイルがどんな時に使用されるかを把握できれば、自ずと編集対象のファイルはわかるようになります。 他のファイルをインクルードする方法の詳細は公式サイトのこのページで解説されています。

メニューをカスタマイズしよう

メニューについても様々なプラグインを使いたくなってしまう人が多い様ですが、標準テーマそのままでもメニューを階層化してドロップダウンメニューを使用することができます。 メニュー設定を行っていない状態だと固定ページ一覧が表示されてしまうので、「使えない」と思っている人もいるのかも知れませんが、WordPress 管理ページの「外観 (Appearance)」-「メニュー (Menus)」からカスタムメニューを設定すれば簡単に階層化されたメニューを使い始めることができます。

階層化するには設定画面上のインデント配置で表します。 詳しい設定方法は WordPress.com に書かれていますが、操作は簡単です。

この hetarena.com も階層メニューを使用していますが、下図は「まとめ記事」-「DAW」-「Cubase」と3階層となっている例です。 この例の場合「まとめ記事」と「DAW」は「カスタムリンク」で「URL」を「#」に設定し、クリックしても何も起こらないようにしています (注: 記事執筆時の状況)。 あとは CSS で外見を整えれば十分ではないでしょうか。
階層化メニュー

子テーマの使用

あるテーマを元としてカスタマイズする場合、元テーマの子テーマとして作成し、変更を加えたいファイルのみを新テーマとして管理する方法があります。 標準テーマをベースにする場合は、もちろんこの子テーマ機能を使うことをお勧めします。 私も Twenty Ten の子テーマを作成して使っています。

ところで子テーマ作成時に1つ注意点があります。 大抵のファイル (style.css も含む) は親テーマのものが子テーマディレクトリ内に作成されたものに置き換わるのですが、functions.php については子テーマの functions.php がロードされてから親テーマの functions.php もロードされます。 ですので、差分のみを子テーマの functions.php に追加しなければなりません。

ついでに言うと functions.php に同じ名前で関数重複があると、管理画面含めて WordPress サイトの表示が真っ白になってしまいます! こんな時は焦らず functions.php を元に戻してアクセスし直せば復旧します。 ちょっと怖いですね。(はい、怖かったです)

子テーマ作成についても詳しくは公式情報ということで。 公式情報にも記載されていますが、style.css については以下のように親テーマの CSS ファイルを import した後、上書きしたい項目を列挙する形にしておくと、管理はしやすいと思います。

@import url("../twentyten/style.css");

HTML を直書きしたい

多分 Visual なエディタよりも HTML を直接書いて、改行も <BR> タグでコントロールしたい、という人はそれなりにいるんじゃないかと思います。 そんな人は HTML エディタに切り替えて記事を書くと思いますが、これだけでは改行箇所に <BR> が挿入されるのを防ぐことはできません。 functions.php に以下の記述が必要です。

<?php
function mywpautop( $pee ) {
  return wpautop($pee, 0);
}        

remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
add_filter   ( 'the_content', 'mywpautop' );    
add_filter   ( 'the_excerpt', 'mywpautop' );    
?>

詳しくは wpautop() の解説をご覧ください。

jQuery ファイルのインクルード

そして、JavaScript をいじりたくなり jQuery をインクルードするようなこともあると思いますが、注意してください。 WordPress のディレクトリには既に jQuery の .js ファイルが含まれていて、これを作法に従って呼び出す必要があります。 何故ならばプラグインが jQuery を使ったりしていてもインクルードするのを 1回にするためです。

.js ファイルをインクルードするには wp_enqueue_script() を呼び出します。 jQuery を使うには functions.php 内に以下を記述します。

wp_enqueue_script( 'jquery' );

WordPress に付属してくる jQuery ではなく、他の jQuery (例えば Google の CDN 版) を使用したいときの例は wp_enqueue_script() の解説ページで紹介されています。 (2013.3.23 追記: 最近内容が変わったようなので、CDN 版を利用したいときはこちらを参照してください)

ちなみに自作スクリプトをテーマファイルフォルダの下に置いて使うには以下のような呼び出し方ができます。 (pathto はテーマファイルが格納されるフォルダ配下のサブフォルダ名)

<script type="text/javascript" 
  src="<?php echo get_stylesheet_directory_uri(); ?>/pathto/yourscript.js"></script>

ちなみに get_template_directory_uri() だと親テーマのディレクトリ名を返してしまうので子テーマ作成の際は注意が必要です。 また、配布できるぐらいのテーマ作成を目指す人は自作スクリプトも wp_enqueue_script で呼び出すクセをつけておいた方が良いでしょう。

コンテンツ (投稿・ページ) の種類を増やしたい

このセクションの話は応用なので、今すぐには必要ないかも知れませんが、覚えておいて損はないと思います。 通常のブログ投稿と告知情報の扱いを分けたいとか、ただのテキスト記事とビデオ関連記事で見せ方を変えたい時などに使用できる機能として「カスタム投稿タイプ」「フォーマット」という2つの機能があります。 本来、この2つはそれぞれ異なる用途向けの機能なので、以下のように覚えておきましょう。

  • カスタム投稿タイプは通常の「投稿 (post)」以外のものをつくりたい時に使う機能です。(名前がミスリーディングですが)
  • フォーマットは「投稿」の種類を設定する機能です。 RSS フィードにそのコンテンツを載せたいのであれば、それはカスタム投稿タイプでなくフォーマット機能を使うべき状況だと思われます。

カスタム投稿タイプであれば、テンプレート階層で single-$posttype.php というファイルが使用されるので、種類に応じた扱いが可能です。 フォーマットであれば、先に紹介した Twenty Eleven の使用例が参考になります。 またフォーマットに関しては post_class() (= 投稿を囲む div に設定されるクラス) で返される CSS class の中にフォーマットを識別するものが含まれるので、新たな .php ファイルを作らずにフォーマット毎に CSS レベルで異なるスタイルを適用するという手もあります。

公式情報 (カスタム投稿タイプフォーマット) の他に、以下のリンクでもわかりやすく使用方法が解説されています。

最後にもう少し

  • WordPress プラグインはスマホアプリと同様、必要なものだけ導入することをお勧めしておきます。
  • SQL がわかる人はここら辺を見てデータベースを活用すると良いと思います。
  • スマホ対応はやっておいた方が良いでしょう。 無料の WPtouch を使う人も多いと思いますが、私はせっかく設定したカスタムメニューを使うために WPtouch Pro を購入してしまいました。
  • ガラケー対応はどうだろう…。 やるならば Ktai Style を使用することになると思いますが、そろそろ割り切っても良い頃のような気もします。

というわけで WordPress についてまとめてみました。 この記事が少しでもお役に立てれば幸いです。

滞在時間0のアクセスの本当のところが知りたい

このブログのように 1話完結でほとんどのトラフィックが検索エンジン経由というサイトは直帰が多いので、Google Analytics で見たとき滞在時間が0のアクセスばかりとなってしまいます。 この0は本当は0じゃない、と思いつつも、「じゃあ、本当のところはどれだけ記事が読まれているの?」というのは気になるところです。 というわけで、直帰の場合もページが開かれている時間が記録されるよう工夫してみました。 具体的には window.onbeforeunload を利用して、ページが閉じられるときに仮想ページにアクセスがあったものとして記録し、滞在時間を計測するのです。 この辺の記事を参考にしました。

以下手順です。

2つめのプロパティを準備する

この方法では仮想ページにアクセスがあったものとして計測するので、実際よりもページビュー数が多くなってしまいます。 そこで通常の計測も引き続き行うこととし、通常のものとは別に新たなプロパティ (トラッキング ID) を作成します。 以前のバージョンの Analytics では「ドメイン」と言っていたように思いますが、最近は「プロパティ」という用語が使用されていますね。 Analytics は「アカウント」-「プロパティ」-「プロファイル」という階層構造になっています。 プロファイルはいわゆるビューなので、複数の計測方法を使い分けるにはプロパティレベルで分けなければなりません。

トラッキングコードの変更

通常のトラッキングコードは、

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-1234567-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script');
    ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') 
      + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(ga, s);
  })();

となっていると思いますが、これを以下のように変更します。

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-1234567-1']);
  _gaq.push(['_trackPageview']);
  
  _gaq.push(['pageTrackerTime._setAccount', 'UA-1234567-2']);
  _gaq.push(['pageTrackerTime._trackPageview']);
  
  (function() {
    var ga = document.createElement('script');
    ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') 
      + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(ga, s);
  })();
  
  window.onbeforeunload = capturePageExit;
  function capturePageExit()
  {
    _gaq.push(['pageTrackerTime._trackPageview', '/page-exit?page=' 
      + document.location.pathname + document.location.search]);
  }

これで通常の計測方法に加えて、ページを閉じた際に仮想ページにアクセスしたものとして集計されたデータが収集されいます。

実際に計測してみて

自分の管理するブログでの例ですが、同じ期間で通常の計測では平均 2分弱の滞在時間だったものが、仮想ページアクセスを使った集計 (‘/page-exit*’ は除外) では 11分超の平均滞在時間が計測されました。 本当に記事を読まれているかはわからないので、この 11分超というのもあくまで目安でしかないのですが、思ったよりは読まれているのだと安心しました。

あくまで目安でしかないのですが、滞在時間が0なのが気になって仕方のない人はは試してみてもよいと思います。 ただ、ずっとやる必要はなくて、1カ月程度計測すれば十分でしょう。

DIV 要素を横に並べる、など

弱小ブログにとっては貼り付けるのに勇気がいる SNS系ボタン (Twitter、Facebook、はてな等) ですが、とりあえずつけてみました。 今回はそのあたりの話をします。

jQuery.socialbutton プラグイン

jQuery 環境でお手軽に SNS系ボタンを配置できる「jQuery.socialbutton プラグイン」というものが公開されており (ダウンロードページ)、これを利用すれば簡単に SNS系ボタンを用意することができます。 前回のエントリのために jQuery 導入済み (と言ってもインクルードしただけですが) というのも SNS系ボタンの導入を後押ししました。 作者の方に感謝です。

DIV 要素を横に並べる

ところで、サンプルページのソースを見ると以下のように DIV 要素が並んでいます。 socialbutton プラグインを紹介する多くのページでも DIV 要素が使われています。

<div id="hatena"></div>
<div id="twitter"></div>
<div id="facebook_like"></div>

ところが、ブラウザ表示上はボタンが綺麗に横に並んでいます。 「DIV 要素なのになんで横に並ぶんだー!?」と思い、検索すると「float 属性を指定しましょう」とのこと。 でもその場合は以下のようになるはずですが、スタイルを指定している気配はありません。

<div id="hatena" style="float: left;"></div>
<div id="twitter" style="float: left;"></div>
<div id="facebook_like" style="float: left;"></div>

種明かしをすると一つ上位の DIV 要素のクラス名を使って横並びの設定が行われているのでした。

<style>
.block div {
margin-right: 15px;
float: left;
}
</style>
<div class="block">
<div id="hatena"></div>
<div id="twitter"></div>
<div id="facebook_like"></div>
</div>

一つ上位の DIV を「block」クラスとして「block」クラスの子孫 DIV 要素には「float: left;」が適用されるようなスタイルを設定しているのです。 こうすれば個々の DIV に float 属性を設定しないで済みます。 「なるほど!」と思ったテクニックでした。

IE7 で動かない?

「これで横に並べて表示できる!」と喜んだのもつかの間、今度は IE7 で動かないという事象が発生しました。 「エラー: ‘}’がありません。」というエラーが出て、以下のように Twitter ボタンが表示されず、ただのリンクになってしまいます。 Facebook や Hatena は大丈夫です。
SNS ボタン

これも検索して調べたところ、FC2 ブログの文字コードは EUC なので Twitter 用 JS ファイル widgets.js をインクルードする際に「charset="UTF-8"」を設定しなければならないようです。 ところが、socialbutton.js の中で Twitter の widgets.js を読み込むところにこれを付けたり、socialbutton.js を読み込むところにも付けたりしてみましたが、改善されません。 結局どうしたかというと IE7 以下では socialbutton.js を読み込む前に widgets.js を読むようにしました。 具体的には以下のようにしました。

<!--[if lt IE 8]>
<script type="text/javascript" charset="utf-8" src="http://platform.twitter.com/widgets.js"></script>
<![endif]-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8" src="/oldimages/socialbutton.js"></script>

widgets.js を2度読むことになりそうなのですが、それでもきちんと動いたので良しとします。

あんまりハマりたくないけれど

JavaScript やら CSS やらをいじるのは何となく ad hoc な感じがしてあんまりハマりたくないのですが、最近の動向を考えるとそうも言っていられない状況です。 なので、昨年ぐらいに参考書として買った「現場のプロから学ぶXHTML+CSS」を読み返しながらブログテンプレートをいじったりしています。

ちょっと紹介するとこの本は「昔は HTML をいじっていたけど今はさっぱり」という私のような人にちょうど良い本です。 結局よく見返すのは1章の XHTML と2章の CSS だったりしますし、最新情報というには出てから間が空いていて、構成も初心者にはどうかという感じですが、この分野はなかなか「最新動向まで加味して体系だてた決定版!」というのが出にくい分野だと思いますので何かしら一冊手元に置いてやっていくのが良いように思います。

前からブログのデザインリニューアルをしたいとは思っているのですがなかなかできず、ちょっとした手直しを続けるようなことになりそうです。 socialbutton のカウンターについては気にし過ぎない、ということで。

FeedBurner.jp から Google へのアカウント移行はお早めに(?)

Google AdSense 公式ブログに「『フィード向け AdSense』でアカウント移行ツールをご利用いただけるようになりました」という記事がでています。 この手順に従うと FeedBurner.jp で管理していたフィードを Google 環境に移行して Google アカウントで管理できるようになります。

いま一つ公式な説明から読み取りづらいのですが、移行で何が起こるのかというと以下の通りです。

  • フィード管理用サイトが www.feedburner.jp から feedburner.google.com に変わる。 移行後 www.feedburner.jp にログインすると feedburner.google.com にリダイレクトされる。 ちなみに feedburner.google.com はデフォルト英語のサイトですが、「Languages」メニューより日本語表示に切り替えることができます。
  • フィード提供用 URL が feeds.feedburner.jp のものから、feeds2.feedburner.com (feedproxy.google.com) のものに変わる。 移行後 feeds.feedburner.jp へのアクセスは feeds2.feedburner.com (feedproxy.google.com) にリダイレクトされる。
  • 過去の統計データは移行される。

で、問題はここからです。 移行についての FAQ を良く読むと、

現在のところ、アカウントの移行期間は「2009年2月末」まで予定しておりますので、この期間までにアカウントの移行を完了していただきますようお願いいたします。

2008/02/28 までに移行を完了されていないお客様は「http://www.feedburner.jp」にログインできなくなる可能性がありますので、十分にご注意ください。また、お持ちのフィードも参照できなくなり、404 エラーを返すようになります。

なのだそうです。 あまり話題になっていないようなのですが、移行期限は来月末なのです。

フィード提供の URL が変わってしまうのですが、移行しないといずれは FeedBurner.jp の URL が使えなくなることが想定されるので迷っても仕方なさそうです。 ですので、このブログのフィードも Google 環境へ移行してしまいました。 移行手続きをすると1時間も経たないうちにメールが届いて新しい環境を利用できるようになります。

ちなみにフィード向け AdSense は移行手続きだけでは有効にならず、明示的に設定する必要があります。 ...はい、私も移行したついでに思わず有効化してしまいました。

Google Analytics で livedoor や BIGLOBE が集計できない件への対処法

_addOrganic() でカスタマイズしても Google Analytics は検索クエリが「q」で、サブドメインが「search」だと正常に検出してくれないという話があります。

確かに言われてみると livedoor や BIGLOBE はカウントされていません。 逆に search が妙に多くて「search.com ってそんなに一般的なのかなあ?」と訝しんでいたのでした。 ドメイン名の一部に search を含んでいるものが全て集約されているとすると合点が行きます。

実際に試してみると、livedoor は "live"、BIGLOBE は "search" でカウントされているようでした。 どうもデフォルトで登録済みのサーチエンジンが優先されるようで、参照元ホスト名を部分一致で判定しているようです。

そこで何とか livedoor や BIGLOBE からのトラフィックを判別できないかと調べたのですが、以下のようにすれば出来ました。

pageTracker._clearOrganic();
pageTracker._addOrganic("google", "q");
pageTracker._addOrganic("yahoo", "p");
pageTracker._addOrganic("goo", "MT");
pageTracker._addOrganic("nifty", "q");
pageTracker._addOrganic("infoseek", "qt");
pageTracker._addOrganic("msn", "q");
pageTracker._addOrganic("search.livedoor", "q");
pageTracker._addOrganic("search.biglobe", "q");
pageTracker._addOrganic("search.com", "q");
pageTracker._addOrganic("live.com", "q");
pageTracker._addOrganic("aol", "query");
pageTracker._addOrganic("ask", "q");
pageTracker._addOrganic("baidu", "wd");
pageTracker._addOrganic("excite", "search");
pageTracker._addOrganic("namaan", "query");
pageTracker._addOrganic("luna", "q");

そうです。_clearOrganic() という API を用いてデフォルトの登録を消去し、全てを自分で登録するのです。

部分一致だとすると Google と goo の扱いも気になるところですが、とりあえずこのコードの通りの呼び出し順で Google と goo のトラフィックもきちんと分離できています。 このテクニックを使えば Google のウェブ検索と画像検索のトラフィックを分けて集計したり、ということもできそうですね。

参考記事


2008.7.26 追記
Nifty が検索のリニューアルをしていて、検索文字列パラメータが "Text" から "q" に変更となっています。 これに合わせてコードを修正しました。

2008. 12. 5 追記
デフォルトの設定を消すことなく、分析したいサーチエンジンを追加登録したいという方は、こちらのブログ記事 をご覧下さい。 最後の方に改善されたコードが紹介されています。


2010.10.14 更に追記
現在は _addOrganic() の引数が増えて、追加する検索エンジンをデフォルトで登録されているものよりも優先させることができるようになっていて、第3引数を true にすれば _clearOrganic() を呼ぶ必要はありません。 詳しくはヘルプを参照ください。

FC2 ブログの CAPTCHA が日本語ユーザ専用仕様な件

このブログで利用している FC2 ブログですが、コメント投稿時の CAPTCHA 機能が2月に追加されました。 私の場合、今のところこの機能によってスパムコメントを完全に排除できています。 「環境設定の変更」より「コメントを投稿する際に確認画面を」「表示する(画像認証あり)」とするだけなので、まだ有効化していない方は試してみてはいかがでしょう?

ところで、この CAPTCHA 機能には一つ気になる点があります。 既に先のリンク先の記事のコメントでも指摘されていますが、「はち ぜろ ロク イチ」の様にひらがなやカタカナで出てくるので、日本語ユーザ専用なわけです

というわけで「英語ブログでグローバル展開」みたいなことをお考えの方はこの機能を有効化することはお勧めできません。 というか FC2 以外のブログを探す必要があるかも知れません。

似たような機能で FC2 ブログには英数字が一定の割合を超えているコメントはスパムと判断してはじく機能もあります。 ちょっとわかりづらかったのですが、この機能を OFF にしたいときは、「本文の『100』%以上が英数字のものをスパムと判定」と設定すれば英数字のみのコメントでも受け付けることができます。

文章からすると 100% 英数字のコメントははスパムと判定されそうですけれど、実際の動作は「以上」ではなく、英数字が 100% を「超える」場合はスパムと判定する、ということのようです。

Google Analytics で goo や百度からの検索をトラッキングする

昨年12月に Google Analytics のトラッキングコード ga.js がリニューアルされました。 以前のコード urchin.js も当分の間 (「少なくとも1年、恐らくもっと長く」だそうです) は使えるようですが、今後の機能追加は ga.js にしか対応しないようなのでこのブログは新しいトラッキングコードに切り替えました。 英語ですが新規導入用のガイドurchin.js からの移行用ガイドもリリースされています。

さて、ga.js の機能に個別のサーチエンジンを登録する機能があります。 デフォルトで Google Analytics に認識される検索エンジンのリストはこちらですが、このリストに存在しない goo や百度も明示的に指定すれば検索エンジンとして Google Analytics に認識させることができ、検索に用いられたキーワードを確認することができるようになります。この指定にはドメインの組織名を表す部分と検索キーワードのパラメータ名を使って _addOrganic を呼び出します。

例えば goo の検索結果からのアクセスであれば、

http://search.goo.ne.jp/web.jsp?from=query&MT=%BC%F1%CC%A3&DC=100

のような URL が参照元になるので、太字の部分を用いて _addOrganic を呼び出します。 その他含めていろいろ登録してみました。

pageTracker._addOrganic("goo", "MT");
pageTracker._addOrganic("nifty", "Text");
pageTracker._addOrganic("baidu", "wd");
pageTracker._addOrganic("excite", "search");
pageTracker._addOrganic("infoseek", "qt");
pageTracker._addOrganic("livedoor", "q");
pageTracker._addOrganic("biglobe", "q");
pageTracker._addOrganic("namaan", "query");

まあ、うちのブログでは Google と Yahoo 以外は誤差の範囲なのですが。


2008. 7. 28 追記
実は、この内容では BIGLOBE や livedoor の集計が出来ませんでした。 対処するためには以下の記事を参照ください。