• twitter
  • Facebook
  • はてなブックマーク
2012年06月07日(木)

[wordpress] WordPressでスマートフォンへ対応する際の覚書き

WordPressを使ってiPhone(スマートフォン)に対応する際のメモです。IETesterでこのブログをチェックしてみたら目も当てられない状態だったため取り急ぎ修正してみました。メディアクエリーを廃止して、ユーザーエージェントによる振り分けをする事にしました。(結果的にメディアクエリーとの違いはあまりないです)

ロードするテンプレートの切り替え

MediaQueryを使用したデバイス幅によるスタイルシートの切り替え方法でも、閲覧に支障ない程度にスマートフォンへの対応が可能ですが、メディアクエリーに反応しないブラウザだとちょっと不安です。IETester自体がjavascriptロードに関して怪しいのですが、とりあえずGoogleで配布されている「css3-mediaqueries.js」を読み込むよりも、wordpressが判定してくれるUserAgentによる分岐処理を行った方が時間的にも短縮できると思います。方法としては、最初からheader.phpやサイドバーなどもスマートフォン向けに作り直してしてしまい、データだけ共有する形にしていきます。

すでにテーマファイルが沢山ある場合

テーマディレクトリ

「category.php」や「category-slug.php」などのテーマファイルが沢山あって、自動でテーマロードさせる方法でWordPressを使っている場合は、locate_template関数を書き変えてしまいます。WordPressの内部関数なので、バージョンアップ時に上書きされるかもしれません。PHPに不安がある場合はやめた方がいいかと思いますが、楽にスマートフォン用テーマを読み込ませる事が出来ます。

locate_template関数は、wp-includesディレクトリの「theme.php」の1075行目付近に定義してあります。フィルターやアクションフックで処理した方がスマートな方法だと思いますが、よさげなフィルターが見当たらなかったので、とりあえず直接書き変えてみました。(マルチサイトや子テーマなどの方法もあるかもしれません。いい方法があれば教えてくださいm(_ _)m)

2012年06月11日追記

WordPressプラグイン「iPhone theme switcher」プラグインを使ってテーマの分岐を行う方法がありました。PC用テーマとiPhone用テーマを振り分けてロードしてくれるみたいです。
  1. // theme.php 1045行目付近。青文字が追記した箇所です。
  2. function locate_template($template_names, $load = false, $require_once = true ) {
  3. global $is_iphone;
  4. $located = '';
  5. foreach ( (array) $template_names as $template_name ) {
  6. if ( !$template_name )
  7. continue;
  8. if($is_iphone){
  9. $template_name = "sp-".$template_name;
  10. }
  11. if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
  12. $located = STYLESHEETPATH . '/' . $template_name;
  13. break;
  14. } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
  15. $located = TEMPLATEPATH . '/' . $template_name;
  16. break;
  17. }
  18. }
  19. if ( $load && '' != $located )
  20. load_template( $located, $require_once );
  21. return $located;
  22. }

ちなみに、この方法を使った場合でも「functions.php」は普通にロードされます。テーマに関するファイルのみ、sp-というプレフィックス付きのテーマファイルをロードしようとします。

index.phpで分岐する

is_●●●関数を使って、テーマファイルをほとんどindex.php内だけで処理している場合は、こっちの方が簡単です。$is_iphoneグローバル変数を使って、次のような方法で分岐していきます。

  1. global $is_iphone;
  2. if($is_iphone){ get_header("sp"); }else{ get_header(); }

この場合get_header関数は、iphoneやandroid端末でアクセスした場合「header-sp.php」をロードしようとします(プレフィックスではなくサフィックス)。その他のデバイスからであれば、「header.php」をロードします。

データベースの中身をiPhone向けに書き換え

一度書いてしまった記事や、これから書く記事に対してもですが、データベースに登録した1つのデータを使ってスマートフォンでも閲覧可能にするのはちょっと大変な作業です。投稿記事に埋め込んだHTMLタグが、スマートフォンでもスタイリングしやすいコーディングになっていれば問題ないと思いますが、そうでないケースも多々あります。また、data属性値などの記述がないため、jQuery系のフレームワークでテーマを適用しようとしても記事の箇所だけそのまま出力されてしまいます。こちらも苦肉の策ですが、とりあえずpreg関数で置き換え処理をして、テーブルタグだけでもリストのような出力をしてみます。とても雑なのであんまり参考にしないで下さい。kses関数を使うなり、スタイルシートで対応するなりのほうがいいかもしれません。後からjavascriptで変更する方法もあるかと思います。

  1. // functions.phpに記述(tableタグをリストビューで出力)
  2. <?php
  3. global $is_iphone;
  4. if($is_iphone) :
  5. function tabletag_to_list($content){
  6. $newtag = preg_replace("/\/table/", "/ul", $content);
  7. $newtag = preg_replace("/\<table/", "<ul data-role='listview'", $newtag);
  8. $newtag = preg_replace("/\<caption\>(.+)\<\/caption\>/", "<li>$1</li>", $newtag);
  9. $newtag = preg_replace(array("/tr/", "/th/", "/td/"), array("li", "b", "p"), $newtag);
  10. $newtag = force_balance_tags($newtag); //強制バランス
  11. return $newtag;
  12. }
  13. add_filter('the_content','tabletag_to_list');
  14. endif;
  15. ?>

画像のサイズについて

記事本文のimgタグは、viewportを指定していてもwidth属性値(height属性値)で指定したサイズで表示されます。背景画像も同じです。こちらは、スタイルシートで画像表示サイズを100%にしてしまうか、背景画像ならbackground-sizeまたはbackground-positionによって中寄せ表示するなどの方法になるかと思います。ただし、100%にした場合、iPhone端末の横幅(320px)以下の画像は拡大されて出力されてしまうので、こちらも注意が必要です。適用する画像に対してclass属性値を設定するか、1つ1つ個別に対応します。もしくは、画像をラッパー要素で囲んで、overflow:scrollで対応するなどもありだと思います。

  1. /* コンテンツエリアの画像のみ幅を変更 */
  2. #main img {
  3. width:100% !important;
  4. }
  5. #foo {
  6. background-size:contain;
  7. }

background-sizeについてはとほほのwww入門さんの記事がわかりやすいです。

関連投稿記事

Comment: