【WPテーマ作り】コンテンツ並び替える仕組み:CSS&PHP編

【WPテーマ作り】コンテンツ並び替える仕組み:ファイル構築編にて コンテンツを並び替える仕組み用に使うファイルを構築しました。

やっとこさコンテンツ並び替えの本番です。

とりあえずCSSでサイドバーとメインコンテンツ部分を入れ替えるCSSを組みましょう。

そしてその後、現在の状態によってテーマのCSSを自動的に変更できるようにすれば 設定画面からコンテンツの入れ替えが可能になるという寸法です。

それではまずはCSSからやっていきます。

Flexboxは少しずつ慣れていこう

カラムを作るためのCSSとしては

  • float
  • flexbox
  • grid

という大きく分けて3パターン存在しています。

floatは平成初期、flexboxは平成中期、gridは平成終期

そんな立ち位置です。

floatは古いやり方なので、未だに結構使われてたりするのですが だいぶ沙汰されてきた感じがします。

gridはその名の通りCSSでグリッドを直感的に組めるCSSになっていますが、 対応していないブラウザがあったり普及率はまだまだですね。 だいぶ対応してるやつが増えてますがマイナーCSSとなってます。

現在の主流はflexboxとなっています。 flexboxは現行のブラウザではほぼ対応されてるので、 問題なく使用できます。

なので今回は主流に則ってflexboxでやっていきましょう。

簡単にflexboxの説明からflex-directionでの入れ替えまで説明します。

すでに知ってる人はphp構築の部分まで飛ばしてください。

一旦わかりやすいように今回用の例としてシンプルなHTMLで表現します。

htmlとheadタグは省略します。

<body>
  <div class="wrap">
    <div class="main">
      <h1>記事タイトル</h1>
      <p>記事本文</p>
    </div>
    <div class="sub">
      <h1>プロフィール</h1>
      <p>プロフィール文</p>
    </div>
  </div>
</body>

flexboxを使うための最低限のhtml構成になります。

頭の中で記事枠が左、プロフィール枠が右想像してください。

wrapのdivが親、その中にあるmainが子1とsubが子2という表現をします。

wrapにflexbox

flexboxの設定自体は基本的に親にすべて設定します。

.wrap {
  display:flex;
  flex-wrap: wrap;
}

基本形はこれだけです。

子は横幅を指定

子を横並びにするには横幅を指定する必要があります。

わかりやすいように子1は70%、子2は28%としましょう。

.main {
  width:70%;
}

.sub {
  width:28%;
}

subが30%ではなく28%なのはボックスの間に隙間を作りたいからです。 枠同士の隙間に関してはmarginでもpaddingで作っても構いません。

好きなやり方でOKです。

並び替えはflex-directionを使う

本題に入りましょう。

現状特に並びの指定をしていないので、上にあるやつが左から右に設置されます。

メインが左、サブが右になりますね。

今回はコレを入れ替えてサブを左、メインを右にしたいわけです。

ココで登場するのが「flex-direction」というflexbox用のCSSプロパティです。

詳しい使い方はCSSリファレンスで調べてもらうか、flexboxをまとめてくれてる人がいるので それを見てもらったほうがいいでしょう。

ここでは左右の入れ替えに着目していきます。

.wrap {
  display:flex;
  flex-wrap: wrap;
  justify-content:space-between;
}

.content--reverse {
  flex-direction:row-reverse;
}

wrapクラスが付与されてるdivにもう1つクラス「content-reverse」クラスを作りました。

このクラスは例えばWordpressのオリジナル設定で 「カラムを入れ替える」がONという設定になっている場合、 wrapクラスのdivタグに「content-reverse」を付与するようにすれば オプションで切り替えることができますね。

flex-directionに着目すると、「flex-direction」の「row-reverse」は flexboxとして指定されている子の並びを右から左にする。

という命令になります。

これでHTMLの順序としてはメインの方が先にあるので、 メインが右になってサブが左になるという仕組みです。

めっちゃ簡単ですね!

なぜ入れ替わるのかって?それはそういう風に私達には 普段見えない部分の深い所でプログラミングされてるから。

ただそれだけです(笑)

cssでの入れ替えはここまでになります。

しれっと「justify-content」のプロパティが出てきてますが、 軽く説明すると余白をどこに置いてレイアウトするかの設定です。

「space-between」はボックス同士の間に均等に設定するので ボックスが2つの場合、右のボックスは一番右に。左のボックスは一番左に設置されます。

文字でいうと

「子2  子1」こんな感じに。

justify-contentを設定してないと

「  子2子1」

と、右開始になるので右寄せになってしまいます。

70%と30%だと余白が0なので「justify-content」を設定する意味がなくなります。

今回70%と28%にしたのはこの違いが判るようにするためでした。

ボックスが2つ以上ある場合、均等に余白をボックスの間に割り当てます。

3つボックスがあった場合

「子1  子2  子3」

ときれいに間を設定してくれます。

と、CSSの解説はここまでになります。

flexboxについては色々設定できることがあるので、各自調べてみてください。

テーマ用コンフィグにカラム入替項目を作る

長かったですがやっと本番の本番です(笑)

【WPテーマ作り】オリジナルの値を保存できるページを作る」で作った仕組みを利用します。

まずはわかりやすいように改変しましょう。

変更した関数だけ載せておきます。

//-----------------------------------------------------
// 便利関数
//-----------------------------------------------------

// サニタイズ関数
function sanitizeMythemeOptions( $options ) {

  // 返す用の空配列を作成
  $new_options = array();

  // 文字列設定値のサニタイズ
  if ( isset( $options['sel_col_type'] ) ) {
    $new_options['sel_col_type'] = sanitize_text_field( $options['sel_col_type'] );
  }
  // サニタイズ処理を行った文字列か、元々問題の無い文字列が入った配列を返す
  return $new_options;
}

//-----------------------------------------------------
// テーマコンフィグのView
//-----------------------------------------------------
// themeOptionメニューの内容を描写する
function themeOptionPageView() { ?>

  <div class="admin--page--wrap">

    <h1>テーマ設定</h1>

    <?php /* 設定用のフォーム */ ?>
    <form method="post" action="options.php">

      <style>
        .table-themes--columnselect {
          width: 90%;
          border-bottom: 1px solid #dddddd;
        }
        .admin--themes--columnselect {
          display:flex;
          flex-wrap: wrap;
        }
        .admin--themes--columnselect li {
          width:200px;
          text-align:center;
        }
        .admin--themes--columnselect li img {
          opacity:1;
          transition:opacity 0.3s ease;
        }
        .admin--themes--columnselect li:hover img {
          opacity:0.6;
        }

        .admin--themes--columnselect dd {
          margin:0;
          padding:5px 0;
        }

      </style>

      <?php /* 設定値のグループを指定して設定値を取得 */ ?>
      <?php settings_fields( 'mytheme_options_group' ); ?>
      <?php do_settings_sections( 'mytheme_options_group' ); ?>

      <?php $options = get_option( 'mytheme_options' ); ?>

      <?php /* 設定値を表示。 */ ?>
      <?php $columnsType = is_numeric($options['sel_col_type']) ? esc_attr( $options['sel_col_type'] ) : '0' ?>
      <table class="form-table table-themes--columnselect">
        <tr valign="top">
          <th scope="row">カラムタイプ選択</th>
          <td>
            <ul class="admin--themes--columnselect">
              <li>
                <label for="two-l-s"><dl>
                  <dt><img src="/wp-content/themes/wp_theme_dev_001/assets/images/admin/themesoptions/column-type-0.png" width="112" height="140" alt="左スタート2カラム"></dt>
                  <dd><input id="two-l-s" name="mytheme_options[sel_col_type]" type="radio" value="0" <?php $columnsType == '0' ? print "checked" : ''; ?>>2カラム左スタート</dd>
                </dl></label>
              </li>
              <li>
                <label for="two-r-s"><dl>
                  <dt><img src="/wp-content/themes/wp_theme_dev_001/assets/images/admin/themesoptions/column-type-1.png" width="112" height="140" alt="右スタート2カラム"></dt>
                  <dd><input id="two-r-s" name="mytheme_options[sel_col_type]" type="radio" value="1" <?php $columnsType == '1' ? print "checked" : ''; ?>>2カラム右スタート</dd>
                  </dl></label>
                </li>
              <li>
                <label for="one-s-on"><dl>
                  <dt><img src="/wp-content/themes/wp_theme_dev_001/assets/images/admin/themesoptions/column-type-2.png" width="112" height="140" alt="1カラムサイド有効"></dt>
                  <dd><input id="one-s-on" name="mytheme_options[sel_col_type]" type="radio" value="2" <?php $columnsType == '2' ? print "checked" : ''; ?>>1カラムサイド有効</dd>
                </dl></label>
              </li>
              <li>
                <label for="one-s-off"><dl>
                  <dt><img src="/wp-content/themes/wp_theme_dev_001/assets/images/admin/themesoptions/column-type-3.png" width="112" height="140" alt="1カラムサイド有効"></dt>
                  <dd><input id="one-s-off" name="mytheme_options[sel_col_type]" type="radio" value="3" <?php $columnsType == '3' ? print "checked" : ''; ?>>1カラムサイド有効</dd>
                </dl></label>
              </li>
            </ul>
          </td>
        </tr>
      </table>

      <?php submit_button(); ?>

    </form>
  </div><!-- .admin--page--wrap -->

<?php }

サニタイズ関数をinputのnameのブラケットの中と同じに変更しました。

画像は各自用意してもらうこととして、やっていることは画像をクリックしたら ラジオボタンが変更されるようにラベルタグで囲んでidとforを対応させています。

ラジオボタンはチェックボックスと違ってチェックされるのは1つだけになるので、 nameをすべて同じにしておく必要があるのに気をつけてください。

後はチェックした値をsubmitで保存して飛ばして保存するのは変わらずですね。

後はレイアウト用のCSSをstyleタグで記述していることと、 読み込んだ直後のinputタグに現在選択されている状態にしたいです。

なのでカラム選択のラジオボタンに「checked」を付与するため、 タグの中に三項演算子を使って保存されてる値と自分の値が合致していれば checkedを出力するという条件にしています。

三項演算子はechoを使わずにprintを使おう

ここで無駄に時間使ってしまったのが、phpはhtml側に文字を表示させたいときは echo関数を使って表示するのですが、三項演算子はなぜかもう1つの表示関数である 「print」じゃないとphpエラーが発生するようです。

1回間違えたのでもう間違えないですね(笑)

後はサニタイズ側の文字列を変更してなくてなぜ保存されない!って無駄に悩んでました。

疲れてくると視界が狭くなってきてダメですね……

問題なく保存と再読み込みでcheckedが変わっていたらOKです。

リテラルは基本使わないようにしよう

現状わかりやすいようにfunctions.phpに記述していることと、 関数の処理に直接文字列を記述している箇所、つまりリテラルが多いですが 本来は関数内部にリテラルはあまり使わないほうが良いです。

後々メンテとかするようなコードの場合はちゃんと変数として切り分けて 1箇所で文字列関係を管理できるようにしておいたほうが後の自分にも優しいですし 変更忘れとか出てくるので、可変になりやすいような場所は必ず変数にしておきましょう。

これでWordpressのテーマ作りの基本的な部分は終わりました。

後はコンテンツの部分やサイドバーの部分のレイアウトを増やしてから それらの順番を入れ替えたりできるようにする仕組みに変更していく感じになります。

後は記事を書くときのエディタを改造ですかね。

実はWordpressのちゃんと作られたテーマって使ったこと無いんですよね……

なのでどういうのがブロガーに好まれるのかっていうのが まだまだわかっていないので(一応私もブロガーではありますが)リサーチでもしようかなと思ってます。

それまではブログに使えるレイアウトを増やしていってオリジナルテーマの厚みを増やしていこうと思います。

ここまで構築できたのであれば、後は自分で調べて必要な関数を調べて うめこんでいったりすればオリジナルテーマの完成です。

時間に余裕があるときはテーマ作りに使えそうなテクニックなどを記事にしていこうと思います。

それでは。