PC 用に作成した WordPress のテーマを jQuery Mobile を使ってスマートフォン対応にする際のメモ。
PC とタブレット端末には、すでに作成してあるテーマを使用し、ユーザーエージェントによりテーマを切り替えるプラグインを利用して、スマートフォン用に jQuery Mobile を使ってテーマを作成。
以下は参考にした主なサイト。
以下のサイトを参考に「ThemeRoller」を利用してテーマに合う配色や角丸の値をカスタマイズ。
テーマローラーの概要(jQuery Mobile 1.0.1 日本語リファレンス)
Your theme was successfully downloaded. You can use this page as a reference for how to link it up! <link rel="stylesheet" href="themes/wpsm.min.css" /> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile.structure-1.3.2.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
既存のテーマ(PC用)をコピーして、「wp-content/themes」に配置する。この際「screenshot.png」と「style.css」は新しいものを作成し、「style.css」の冒頭の「Theme Name」を最低限記述する。
/* Theme Name: smartphone Description: smartphone Template */
.ui-icon-alt .ui-icon-searchfield:after { background-image: url(images/icons-18-black.png); background-repeat: no-repeat; }
img { max-width: 100%; height: auto; }
WordPress のスマートフォン用のテーマのhead 要素内に jQuery Mobile のファイルを読み込む。
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Mobileテーマ</title> <link rel="stylesheet" href="<?php echo get_stylesheet_uri(); ?>" type="text/css" /> //style.css の読み込み <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile.structure-1.3.2.min.css" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script> <?php wp_head(); ?> </head> <body <?php body_class(); ?>>
スマートフォンでどのように見えるかは実機で確認するのが一番良いが、簡単な方法として以下のようなツールを使用。
jQuery Mobile ではカスタムデータ属性「data-role=”page”」を持つ div 要素が1ページになり、各ページ内のレイアウトも div 要素にカスタムデータ属性を指定して定義する。
jQuery Mobileのページ構成は、ページ(<div data-role=”page”>~</div>)の中に
で構成する。
data-role 属性の値に、”header” や ”content” など、用意されている「UIタイプ」を指定することにより、そのUIタイプとして表示されるようになる。
header.php と footer.php を修正して、data-role 属性の値に”page”、”header” 、 ”content” などを指定してページ、ヘッダー、コンテンツ、フッターを作成。”page”は一番外側の div 要素に指定する。以下の例では、既存の<div id=”container”>に data-role=”page” data-theme=”a” を指定してページを作成。また、以下は 1ファイル、1ページで作成する場合の例。
//header.php <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> ・・・省略・・・ </head> <body <?php body_class(); ?>> <div data-role="page" data-theme="a" id="container"> //page 要素 <div data-role="header" data-theme="z"> //header 要素 <div id="header"> //既存の要素をそのまま残してある(上の要素とまとめることも可能) <a href="<?php echo is_front_page() ? '#' : home_url(); ?>"><h1 id="toptitle">Title</h1> <p id="language"><a data-role="button" class="ui-btn-right" href="<?php echo get_site_url(1); ?><?php echo $is_jp || $is_root ? '/en' : '/jp'; ?>" data-mini="true" data-theme="a"><?php echo $is_jp || $is_root ? 'English' : 'Japanese'; ?></a></p> //button 要素(言語切換え用) </div><!-- end of #header --> </div><!-- end of #data-role="header" --> <div data-role="content"> //content 要素
以下は「footer.php」
//footer.php </div><!-- end of #data-role="content" --> //content 要素終了 <div data-role="footer" id="footer"> //footer 要素 <small>Copyright © Mysite. All rights reserved. </small> </div><!-- end of #footer (data-role="footer") --> </div><!-- end of #container (data-role="page") --> <?php wp_footer(); ?> </body> </html>
メニューの部分を、data-role=”navbar”とし、ナビゲーションバーとして表示。
<div data-role="navbar" data-iconpos="right" id="sidebar"> //navbar 要素 <ul> <li><a data-icon="home" href="<?php echo home_url(); ?>">Home</a></li> <li><a data-icon="back" data-rel="back" href="<?php echo home_url(); ?>">Back</a></li> </ul> <ul> <li><a href="<?php echo home_url(); ?>/news/">What's New</a></li> ・・・省略・・・ <li><a href="<?php echo home_url(); ?>/contact/">Contact</a></li> </ul> </div><!-- end of #sidebar -->
スマートフォン用のテーマは PC 用のテーマのテンプレートをコピーして作成したので、それらを修正する。
jQuery Mobile では、Ajax によって各ページが読み込まれてコンテンツが DOM に追加されるため、DOM の ready ハンドラはサイトの最初のページを開いた時にしか呼ばれないので注意が必要。以下は参考にしたサイト。
独自の jQuery の記述は「jquery-1.9.1.min.js」と「jquery.mobile-1.3.2.min.js」の間に記述する。
<link rel="stylesheet" href="<?php echo get_stylesheet_uri(); ?>" type="text/css" /> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile.structure-1.3.2.min.css" /> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="<?php echo get_template_directory_uri(); ?>/js/base.js"></script> //外部ファイル <script> 必要なスクリプトの追加 $(document).bind("mobileinit", function(){ $.mobile.ajaxEnabled = false; }); $(document).on('click', 'p.show_map a', function(){ $('div#map_container').slideDown(500); var address = $('p.address', $(this).closest('div')).text(); if($('p.web1').text() !== '') {var url = $('p.web1 a', $(this).closest('div')).attr('href');} showMap(address, $('p.venue').text(), url); return false; }); ・・・ $(document).on('swipeleft', "#single_news_content", function(){ if($('div.postlink p.fLeft a').attr('href')) { window.location = $('div.postlink p.fLeft a').attr('href'); } }); ・・・ </script> <script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script> <?php wp_head(); ?> </head>
$(document).bind("mobileinit", function(){ $.mobile.ajaxEnabled = false; });
<div id="attachment_409" class="wp-caption alignleft" style="width: 310px">
caption ショートコードの出力を img_caption_shortcode フィルタで変更し style の指定を削除。
function my_img_caption_shortcode($output, $attr, $content){ extract(shortcode_atts(array( 'id' => '', 'align' => 'alignnone', 'width' => '', 'caption' => '' ), $attr)); if ( 1 > (int) $width || empty($caption) ) return $content; if ( $id ) $id = 'id="' . esc_attr($id) . '" '; return '<div ' . $id . 'class="wp-caption ' . esc_attr($align) . '">' . do_shortcode( $content ) . '<p class="wp-caption-text">' . $caption . '</p>'. '</div>'; } add_filter('img_caption_shortcode', 'my_img_caption_shortcode', 10, 3);
$('div.blog_content a').filter(function() { if($(this).attr('href').search(/wp-content\/uploads/) != -1) { return true; }else{ return false; } }).css('cursor', 'default').click(function() { return false; });
previous_post_link() や pagenavi()などで「次へ」や「前へ」のリンクがあるページでスワイプするとページが遷移するようにするために、以下を記述。
previous_post_link(), next_post_link() の場合、その部分は以下のようにマークアップしてある。
<div class="postlink news"> <p class="fLeft"> <?php previous_post_link('%link', __('« Previous')); ?> </p> <p class="fRight"> <?php next_post_link('%link ', __('Next »')); ?> </p> </div>
リンク先は「’div.postlink p.fLeft a’」等に入っているのでそれを利用してページ遷移するようにする。
$(document).on('swipeleft', "#single_news_content", function(){ if($('div.postlink p.fLeft a').attr('href')) { window.location = $('div.postlink p.fLeft a').attr('href'); } }); $(document).on('swiperight', "#single_news_content", function(){ if($('div.postlink p.fRight a').attr('href')) { window.location = $('div.postlink p.fRight a').attr('href'); } });
pagenavi() の場合は出力されるマークアップを見ると以下のようになっている。
<div class="pagenavi"> <span class="page-numbers current">1</span> <a class="page-numbers ui-link" href="http://xxxx/xxxx/page/2/">2</a> <a class="next page-numbers ui-link" href="http://xxxx/xxxx/page/2/">次へ »</a> </div>
リンク先は「a class=”next page-numbers ui-link”」等に入っているのでそれを利用してページ遷移するようにする。
$(document).on('swipeleft', "#news_content", function(){ if($('div.pagenavi a.prev').attr('href')) { window.location = $('div.pagenavi a.prev').attr('href') } }); $(document).on('swiperight', "#news_content", function(){ if($('div.pagenavi a.next').attr('href')) { window.location = $('div.pagenavi a.next').attr('href'); } });
ユーザーエージェントによりテーマを自動で切り替えてくれるプラグインは以下のようなものがある。
長い期間アップデートされていないプラグインもあり、今回は「Multi Device Switcher」を使用。