LIQUID DESIGN Tech Blog

Bootstrap対応のWordPressテーマ作成が簡単じゃなかった件

こんにちは。

この記事は WordPress Advent Calendar 2015に参加したかった人達の Advent Calendar 2015 15日目の記事です。

Bootstrap対応のWordPressテーマを作成したときの黙示録です。

これからテーマを作成される方に少しでも参考になれば幸いです。

テーマ作成について

WordPressテーマを配布する目的でゼロから作成します。

Bootstrapのフォーマットに対応します。

  • WordPress 4.2+
  • 使用ライブラリ:jQuery、Bootstrap 4 alpha

Bootstrap class名の指定(前編)

Grid

グリッドレイアウトなど、テーマのテンプレートで自由に作成できる部分は簡単です。

問題は下記のように、WordPressが生成する部分のカスタマイズです。

Navbar

カスタムメニュー wp_nav_menu で、
ul の class は、テンプレートタグオプションで指定できますが、li の class は指定できません。
functions.php で nav_menu_css_class をフックして class を指定します。
function my_special_nav_class( $classes, $item ) {
$classes[] = 'nav-item';
return $classes;
}
add_filter( 'nav_menu_css_class', 'my_special_nav_class', 10, 2 );

Forms

コメントフォーム

comment_form は、デフォルトでは class が全く指定されていません。

フォーム要素を上書きして、ひとつずつ class を指定します。以下抜粋。
<?php comment_form( $args, $post_id ); ?>

$args = array(<br /> &#8216;id_form&#8217; => &#8216;commentform&#8217;,<br /> &#8216;id_submit&#8217; => &#8216;submit&#8217;,<br /> &#8216;comment_field&#8217; => &#8216;</p> <p class="comment-form-comment"><label for="comment">&#8216; . _x( &#8216;Comment&#8217;, &#8216;noun&#8217; ) .<br /> &#8216;</label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true" class="form-control">&#8216; .<br /> &#8216;</textarea></p> <p>&#8216;,<br /> &#8216;fields&#8217; => apply_filters( &#8216;comment_form_default_fields&#8217;, array(<br /> &#8216;email&#8217; =><br /> &#8216;</p> <p class="comment-form-email"><label for="email">&#8216; . __( &#8216;Email&#8217;, &#8216;domainreference&#8217; ) . &#8216;</label> &#8216; .<br /> ( $req ? &#8216;<span class="required">*</span>&#8216; : &#8221; ) .<br /> &#8216;<input id="email" name="email" type="text" value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' class="form-control" /></p> <p>&#8216;<br /> )<br /> ),<br /> );

検索フォーム

検索フォームは、functions.php で get_search_form をフックします。

function my_search_form( $form ) {<br /> $form = &#8216;</p> <form role="search" method="get" id="searchform" class="searchform" action="' . home_url( '/' ) . '" > <div><label class="screen-reader-text" for="s">&#8216; . __( &#8216;Search for:&#8217; ) . &#8216;</label><br /> <input type="text" value="' . get_search_query() . '" name="s" id="s" class="form-control" /><br /> <input type="submit" id="searchsubmit" value="'. esc_attr__( 'Search' ) .'" class="form-control" /> </div> </form> <p>&#8216;;<br /> return $form;<br /> }<br /> add_filter( &#8216;get_search_form&#8217;, &#8216;my_search_form&#8217; );

パンくずリスト

パンくずリスト(breadcrumb)のテンプレートタグ get_category_parents もクセモノです。

下記のような Bootstrap フォーマットに整形したいのですが、まず li にできません。

</p> <ul class="breadcrumb"> <li><a href="">Hoge</a></li> <li><a href="">Category</a></li> <li class="active">Page title</li> </ul> <p>
区切る文字列に </li><li> と指定することで、なんとか li にできますが、最後の li が余分です。

最後の li を Page title の開始タグに利用するにしても、active class を指定できなくなります。
<ul class="breadcrumb">
<li><?php echo get_category_parents($cat[0]->term_id,TRUE,'</li><li>'); ?>
Page title</li>
</ul>

結局、php で無理やり最後の li を除去しました。

Bootstrap class名の指定(中編)

上記のようにフックすると、影響範囲が広いため問題が発生します。
例えば、カスタムメニューで、ヘッダーメニューだけドロップダウンにしたい場合。
nav_menu_css_class をフックしてドロップダウンの class をつけると、全てのカスタムメニューに反映されるため、
ウィジェットとしてサイドバーやフッターに配置したときも全てドロップダウンになってしまいます。

フックするときに条件分岐はできないので、
ウィジェットの .widget_nav_menu に対して css で調整します。
.widget_nav_menu .dropdown-item {
ドロップダウンを打ち消すstyleを指定
}

Bootstrap class名の指定(後編)

最後に、プラグインのBootstrap対応をどうするかという問題があります。
テーマ側の作業範囲ではないのですが、例えばプラグインのお問い合せフォームだけBootstrap非対応でデザインも違うのはちょっと残念です。

例えば、プラグイン「Contact Form 7」の場合、要素毎にclassを設定することができますが、
ユーザーに設定を強いるのは現実的ではありません。

テーマ側で対応するには、jQueryでclassを後付けするしかありません。
$('.wpcf7-form input[type="submit"]').addClass("btn btn-primary");

まとめ

色々フックしたり、プラグイン対応まで考えると簡単ではないと感じました。
また、WordPressやプラグインの仕様変更によって正常に表示されなくなるリスクもあります。

引き続き効率の良い方法を検討していきたいと思います。

作成したテーマは配布していますのでよろしければ使ってみてください。

以上です!

明日は @mimosafa さんです。よろしくお願いします!


リンク:Bootstrap 4 先取り対応 WordPressテーマ

この記事を書いた人
LIQUID DESIGN のサービスに関するデザインや技術情報を発信します。
SNSでフォローする