WordPressプラグインのページングデザインを変更する

WordPress

WordPressプラグインを開発する際、記事の一覧を表示するようなプラグインを開発する場合は、一覧を切り替えるためのページングがどうしても必須になってきます。
ページング(ページナビゲーション)とはページ送りのことで、一覧画面の次ページ・前ページ、といった機能の事です。


WordPressプラグインの標準機能で、「paginate_links」という機能を使えばページング自体は出力されるのですが、画面デザインについては自身でカスタマイズする必要があります。


今回は、WordPressプラグインのページングデザインを修正する方法を紹介します。


環境情報


  • WordPress 5.1.6

paginate_linksでのページング出力


WordPressプラグインでは、「paginate_links」を使用すればページングが出力されます。
記事一覧とページングを表示するサンプルプログラムは以下になります。


// 検索条件を設定
$paged = get_query_var('paged') ? get_query_var('paged') : 1 ;
$args = array(
    'post_type' => 'post',
    'posts_per_page' => 20,
    'paged' => $paged
);
// クエリを実行
$query = new WP_Query($args);

// クエリ結果を表示
if ( $query->have_posts() ) {
    echo '<table>';
    $lc = 1;
    while ( $query->have_posts() ) {
        $query->the_post();
        echo '<tr>';
        echo '<td>';
        echo $lc;
        echo '</td>';
        echo '<td>';
        echo the_title();
        echo '</td>';
        echo '</tr>';
        $lc++;
    }
    echo '</table>';

    echo '
';
    echo paginate_links(array(
        'base' => str_replace(
            $big, '%#%', esc_url(get_pagenum_link($big))),
        'show_all' => true,
        'type' => 'list',
        'format' => '?paged=%#%',
        'current' => max(2, get_query_var('paged')),
        'total' => $query->max_num_pages,
        'prev_text' => '前へ',
        'next_text' => '次へ',
    ));
    echo '</table>';
    echo '
';
} else {
    echo "no result.
";
}

上記のプログラムでページング自体は表示されますが、デザインは何も設定されていない状態になります。



このページング部分について、CSSでデザインを設定していきます。


CSSを作成する


ページング部分のHTMLは以下になります。
このHTMLを「paginate_links」が出力しています。


<ul class="page-numbers">
    <li><a class="prev page-numbers" href="URL">前へ</a></li>
    <li><a class="page-numbers" href="URL">1</a></li>
    <li><span aria-current="page" class="page-numbers current">2</span></li>
    <li><a class="page-numbers" href="URL">3</a></li>
    <li><a class="page-numbers" href="URL">4</a></li>
    <li><a class="page-numbers" href="URL">5</a></li>
    <li><a class="next page-numbers" href="URL">次へ</a></li>
</ul>

<ul><li>のリスト形式でページングが構成されていることがわかります。
リスト形式を縦並びではなく横並びにする方法で何通りかあるのですが、inline-block形式で横並びにする方法でデザインを変更していきます。


以下のCSSを適用します。


ul {
  list-style: none;
}

ul.page-numbers {
  width: 1000px;
  padding:0;
  font-size:0px;
}

ul.page-numbers li {
  padding-top:10px;
  margin-left:10px;
  width:50px;
  border:1px solid black;
  display: inline-block;
  text-align: center;
  font-size:15px;
  height:30px;
}

ul.page-numbers li .current {
  font-size:15px;
}

ul.page-numbers li a {
  display: block;
  font-weight:bold;
}

ul.page-numbers li .current {
  padding-top:50px;
}

このCSSを適用することで、ページングのデザインが整います。



よくあるページングデザインにしてみたつもりですが、デザインを変更したい場合は、上記のサンプルCSSを調整すればデザインは調整できます。


CSSをプラグインに適用


CSSを自作したWordPressプラグインに適用する場合、プラグインのプログラムにCSSの読み込み処理を実装する必要があります。
まず、自作したCSSをプラグインフォルダに格納します。
以下の例では、プラグインフォルダの下にCSSという名前のフォルダを作成し、その中に「style.css」というファイルを格納しておきます。



WordPressプラグイン側の実装は、以下になります。


/**
コンストラクタ
*/
function __construct() {
    if (is_admin() && is_user_logged_in()) {
        wp_register_style(
            'myplugin_css', plugins_url('css/style.css', __FILE__));
        wp_enqueue_style('myplugin_css');
    }
}

使用する機能は以下の2つになります。


  • wp_register_style

CSSスタイルファイルの登録。


  • wp_enqueue_style

画面ページに CSSファイルを追加。


上記の実装をWordPressプラグインに実装することで、WordPressページにデザインが適用されます。



WordPressプラグインの開発で発生し易いエラーと対処方法

WordPress

WordPressプラグインを開発していく中で、何かしらエラーが発生して悩んでしまう場合があるかと思います。
特にWordPressプラグインの開発を始めたばかりの人の場合、ハマって場合もあります。


そんな人むけに、WordPressプラグインの開発を始めたばかりの人がハマりやすいエラーについて、原因と対処方法を説明します。


環境情報


  • WordPress 5.4.1

文字化け


一番最初に陥り易いエラーです。


WordPressのダッシュボードで、開発しているプラグインの説明分が文字化けしてしまう場合があります。


WordPressプラグインの有効化の時に文字化け

文字化けしてしまう原因は文字コードです。
WordPressの文字コードは「UTF-8」なのですが、開発しているプラグインのPHPファイルが他の文字コードになっている事が原因です。


PHPファイルの文字コードを「UTF-8」に変更して保存すれば、文字化けは解消されます。


WordPressプラグインの有効化の時に文字化けの解消

プラグインの有効化中に”N”文字の予期しない出力が生成されました


プラグインの有効化をおこなうタイミングで発生するエラーになります。
これは、PHPプログラムの先頭、もしくは、末尾に、余計な改行や空白が存在する場合に発生します。


WordPressプラグインの余分な改行

PHPプログラムの先頭や末尾には、余分な改行や空白は不要になります。
以下のように、末尾位置と改行位置は一致する必要があります。


WordPressプラグインの先頭
WordPressプラグインの末尾

重大なエラーを引き起こしたため、プラグインを有効化できませんでした


プラグインの有効化をおこなったタイミングでPHPファイルに文法エラーが存在すると、有効化に失敗します。


WordPressプラグインの有効化時syntaxエラー

通常のPHPエラーがダッシュボードに表示されているだけなので、エラー内容を確認した上で対処すればよいです。


上記サンプルのエラーでは、「;」(セミコロン)の記載をおこなっていないので、PHPのパースに失敗しています。
通常のPHPと同様に、エラー発生箇所に対して「;」を記載して、再度プラグイン有効化すれば正常に有効化がおこなわれます。


WordPressプラグインの開発。コントローラを使って設定を保存する方法

WordPress

WordPressプラグインを開発する際、設定画面でさまざまコントローラを使う場面がでてきます。
テキストボックス・セレクトボックス・ラジオボタン、いろいろあります。


今回は、各コントローラを設定画面で使う場面を想定した際の実装方法について紹介します。


環境情報


  • WordPress 5.1.6

基本的なプログラム


WordPressプラグインを開発する場合、基本的なお作法があります。
今回の各コントローラを扱うプラグインプログラムについても、この部分は変わりません。


<?php
/*
  Plugin Name: ControlSample
  Plugin URI:https://sakusaku-techs.com/
  Description: 設定ウィンドウでのコントロールサンプル
  Version: 1.0.0
  Author: SakuSaku
  Author URI: https://sakusaku-techs.com/
  License: GPLv2
 */


/**
1:初期アクションの定義
*/
add_action('init', 'ControlSample::init');

class ControlSample {

    /**
    2:プラグイン定数の定義
    */
    const PLUGIN_ID         = 'control-sample';
    const SAMPLE_ACTION     = self::PLUGIN_ID . '-nonce-action';
    const SAMPLE_NAME       = self::PLUGIN_ID . '-nonce-key';
    const SAMPLE_DB_PREFIX  = self::PLUGIN_ID . '_';
    const SAMPLE_MENU_SLUG  = self::PLUGIN_ID . '-config';
    const COMPLETE_CONFIG  = 'update-date-complete';

    /**
    初期化処理
    */
    static function init() {
        return new self();
    }

    /**
    コンストラクタ
    */
    function __construct() {
        /**
        3:アクションの定義
        */
        if (is_admin() && is_user_logged_in()) {
            add_action('admin_menu', 
                [$this, 'set_controlSample_menu']);
            add_action('admin_menu', 
                [$this, 'set_controlSample_sub_menu']);
            add_action('admin_init', 
                [$this, 'save_config']);
        }
    }

    /**
    コントロールサンプルのメニュー追加
    */
    function set_controlSample_menu() {
        /**
        4:メニューの追加
        */
        add_menu_page(
            'コントロールサンプル',
            'コントロールサンプル',
            'manage_options', 
            'sample-index-slag',
            [$this, 'show_about_plugin'],
            'dashicons-format-gallery', 
            99
        );
    }

    /**
    コントロールサンプルのサブメニュー追加
    */
    function set_controlSample_sub_menu() {
        /**
        5:サブメニューの追加
        */
        add_submenu_page(
            'sample-index-slag', 
            '設定',
            '設定',
            'manage_options',
            'custom-index-banner-config',
            [$this, 'show_config_form']);
    }

    /**
    設定画面の項目データベースに保存する
    */
    function save_config() {
        if (isset($_POST[self::SAMPLE_NAME]) && 
            $_POST[self::SAMPLE_NAME]) {
            if (check_admin_referer(
                self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            /**
            6:データベースへの保存
            */
            }
        }
    }

    /**
    設定ウィンドウの表示
    */
    function show_config_form() {
        /**
        7:データベースからのデータ取得と画面表示
        */
    }
}
?>

1~5のプログラムは、WordPressプラグイン開発においては基本的な部分です。
各コントローラの表示と保存をおこなうために、6と7にプログラムとHTMLの記載をおこないます。


各コントローラのサンプルプログラム


WordPressプラグインの開発において、設定画面を設ける場合が多いかと思います。
その場合、何かしらの設定値を画面に入力して、WordPressのDBに保存する必要があります。


想定されるコントローラとして、以下のコントローラについてサンプルプログラムを紹介します。


  • テキストボックス
  • テキストエリア
  • セレクトボックス(プルダウン)
  • ラジオボタン
  • カラーピッカー

テキストボックス


テキストボックスは、全てのコントローラに対するプログラムの基本です。


保存メソッドである「save_config()」においてテキストボックスの内容をWordPressのDBに保存しています。
WordPressのDBに保存する際にキー値が必要となりますが、先頭にプレフィックスとして「self::SAMPLE_DB_PREFIX」を付加しているのがポイントです。
このプレフィックスの値が、本プラグインの値となります。


実際に「show_config_form()」において、このプレフィックスを使用してWordPressのDBから値を取得しています。



/**
設定画面の項目データベースに保存する
*/
function save_config() {
    if (isset($_POST[self::SAMPLE_NAME]) && 
        $_POST[self::SAMPLE_NAME]) {
        if (check_admin_referer(
            self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            update_option(self::SAMPLE_DB_PREFIX . 
                "_textbox", $_POST['prefix']);
            $completed_text = "設定の保存が完了しました。";
            set_transient(
                self::COMPLETE_CONFIG, $completed_text, 5);
            wp_safe_redirect(
                menu_page_url(self::SAMPLE_MENU_SLUG), false);
        }
    }
}

/**
設定ウィンドウの表示
*/
function show_config_form() {
    $textbox = 
        get_option(self::SAMPLE_DB_PREFIX . "_textbox");
?>
<div class="wrap">
  <h1>カスタムバナーの設定</h1>
  <form action="" method='post' id="my-submenu-form">
      <?php wp_nonce_field(
        self::SAMPLE_ACTION, self::SAMPLE_NAME) ?>
      
        <label for="prefix">テキストボックス:</label>
        <input type="text" name="prefix" value="<?= $textbox ?>"/>
      
      
        <input type='submit' value='保存' class='button button-primary button-large'>
      
  </form>
</div>
<?php
}

テキストエリア


テキストエリアは、テキストボックスとほぼ同等となります。

保存メソッドである「save_config()」にテキストエリアの値を保存し、表示メソッドである「show_config_form()」にテキストエリアの値の取得とHTMLへの表示をおこなっています。



/**
設定画面の項目データベースに保存する
*/
function save_config() {
    if (isset($_POST[self::SAMPLE_NAME]) && 
        $_POST[self::SAMPLE_NAME]) {
        if (check_admin_referer(
            self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            update_option(self::SAMPLE_DB_PREFIX . 
                "_textarea", $_POST['prefix_area']);
            $completed_text = "設定の保存が完了しました。";
            set_transient(
                self::COMPLETE_CONFIG, $completed_text, 5);
            wp_safe_redirect(
                menu_page_url(self::SAMPLE_MENU_SLUG), false);
        }
    }
}

/**
設定ウィンドウの表示
*/
function show_config_form() {
    $textbox = get_option(self::SAMPLE_DB_PREFIX . "_textbox");
?>
<div class="wrap">
  <h1>カスタムバナーの設定</h1>
  <form action="" method='post' id="my-submenu-form">
      <?php wp_nonce_field(
          self::SAMPLE_ACTION, self::SAMPLE_NAME) ?>
      
        <label for="prefix">テキストエリア:</label>
        <textarea rows="10" cols="60" name="prefix_area">
            <?= $textArea ?>
        </textarea>
      
      
<input type='submit' value='保存' class='button button-primary button-large'>
  </form>
</div>
<?php
}

セレクトボックス(プルダウン)


セレクトボックス(プルダウンメニュー)も、テキストボックスとテキストエリアとほぼ同一なのですが、HTMLの構成が異なりますので、おのずとプログラムも変わってきます。
セレクトボックスで選択された値についてのみ、WordPressのDBに保存をおこない、HTMLに反映をおこなっています。



/**
設定画面の項目データベースに保存する
*/
function save_config() {
    if (isset($_POST[self::SAMPLE_NAME]) && 
        $_POST[self::SAMPLE_NAME]) {
        if (check_admin_referer(
            self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            update_option(self::SAMPLE_DB_PREFIX . 
                "selectbox", $_POST['siteoption_select1']);
            $completed_text = "設定の保存が完了しました。";
            set_transient(
                self::COMPLETE_CONFIG, $completed_text, 5);
            wp_safe_redirect(
                menu_page_url(self::SAMPLE_MENU_SLUG), false);
        }
    }
}

/**
設定ウィンドウの表示
*/
function show_config_form() {
    $textbox = get_option(
        self::SAMPLE_DB_PREFIX . "_textbox");
?>
<div class="wrap">
  <h1>カスタムバナーの設定</h1>
  <form action="" method='post' id="my-submenu-form">
      <?php wp_nonce_field(
          self::SAMPLE_ACTION, self::SAMPLE_NAME) ?>
      
        <label for="prefix">セレクトボックス:</label>
          <select name="siteoption_select1" id="siteoption_select1">
              <option value="0" <?php selected(0, 
                get_option(self::SAMPLE_DB_PREFIX . "selectbox"));
              ?> >
                値0:デフォルト
              </option>
              <option value="1" <?php selected(1, 
                get_option(self::SAMPLE_DB_PREFIX . "selectbox"));
              ?> >
                値1
                </option>
              <option value="2" <?php selected(2, 
                get_option(self::SAMPLE_DB_PREFIX . "selectbox"));
              ?> >
                値2
                </option>
              <option value="3" <?php selected(3, 
                get_option(self::SAMPLE_DB_PREFIX . "selectbox" ));
              ?> >
                値3
                </option>
          </select>
      
      
<input type='submit' value='保存' class='button button-primary button-large'>
  </form>
</div>
<?php
}

ラジオボタン


ラジオボタンは、セレクトボックスとほぼ同等となります。


保存メソッドである「save_config()」にラジオボタンで選択されたの値を保存し、表示メソッドである「show_config_form()」において選択内容の反映をおこなっています。



/**
設定画面の項目データベースに保存する
*/
function save_config() {
    if (isset($_POST[self::SAMPLE_NAME]) && 
        $_POST[self::SAMPLE_NAME]) {
        if (check_admin_referer(
            self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            update_option(self::SAMPLE_DB_PREFIX . 
                "option", $_POST['siteoption_radio1']);
            $completed_text = "設定の保存が完了しました。";
            set_transient(
                self::COMPLETE_CONFIG, $completed_text, 5);
            wp_safe_redirect(
                menu_page_url(self::SAMPLE_MENU_SLUG), false);
        }
    }
}

/**
設定ウィンドウの表示
*/
function show_config_form() {
    $textbox = get_option(
        self::SAMPLE_DB_PREFIX . "_textbox");
?>
<div class="wrap">
  <h1>カスタムバナーの設定</h1>
  <form action="" method='post' id="my-submenu-form">
      <?php wp_nonce_field(
        self::SAMPLE_ACTION, self::SAMPLE_NAME) ?>
      
        <label for="prefix">ラジオボタン:</label>
          <label>
            <input name="siteoption_radio1" type="radio" value="0" 
                <?php checked(0, get_option(
                    self::SAMPLE_DB_PREFIX . "option")); ?> />
                    値1</label>
          <label>
            <input name="siteoption_radio1" type="radio" value="1" 
                <?php checked(1, get_option(
                    self::SAMPLE_DB_PREFIX . "option")); ?> />
                    値2</label>
          <label>
            <input name="siteoption_radio1" type="radio" value="2" 
                <?php checked(2, get_option(
                    self::SAMPLE_DB_PREFIX . "option")); ?> />
                    値3</label>
          <label>
            <input name="siteoption_radio1" type="radio" value="3" 
                <?php checked(3, get_option(
                    self::SAMPLE_DB_PREFIX . "option")); ?> />
                    値4</label>
      
      
<input type='submit' value='保存' class='button button-primary button-large'>
  </form>
</div>
<?php
    }

カラーピッカー


カラーピッカーは、他コントローラとちょっと異なります。
色選択ウィンドウを表示する必要があるので、クライアント側の作りこみが必要があります。


色選択ウィンドウは、JQueryUIの「wpColorPicker」を使用します。
「wpColorPicker」を制御するJavaScriptを準備して、サーバ上のプラグインフォルダに保存しておきます。


plguinfolder --- control-sample.php
             |
             --- js
                 |
                 --- date.js

PHPでは、プラグインフォルダに保存しておいたJavaScriptを読み込むプログラムを実装しておきます。



JavaScript

(function( $ ) {
    var options = {
        defaultColor: false,
        change: function(event, ui){},
        clear: function() {},
        hide: true,
        palettes: true
    };
    $('.color-picker').wpColorPicker(options);
})( jQuery );

PHP

add_action( 'wp_enqueue_scripts', 'load_javascript_func' );

class ControlSample {

/**
設定画面の項目データベースに保存する
*/
function save_config() {
    if (isset($_POST[self::SAMPLE_NAME]) && 
        $_POST[self::SAMPLE_NAME]) {
        if (check_admin_referer(
            self::SAMPLE_ACTION, self::SAMPLE_NAME)) {
            update_option(
                self::SAMPLE_DB_PREFIX . "_color", $_POST['color']);
            $completed_text = "設定の保存が完了しました。";
            set_transient(
                self::COMPLETE_CONFIG, $completed_text, 5);
            wp_safe_redirect(
                menu_page_url(self::SAMPLE_MENU_SLUG), false);
        }
    }
}

/**
JavaScriptの読み込み
*/
function load_javascript_func() {
     wp_enqueue_script( "jQuery", includes_url().'/js/date.js' );
}

/**
設定ウィンドウの表示
*/
function show_config_form() {
?>
<div class="wrap">
  <h1>カスタムバナーの設定</h1>
  <form action="" method='post' id="my-submenu-form">
      <?php wp_nonce_field(
          self::SAMPLE_ACTION, self::SAMPLE_NAME) ?>
      
          <label for="prefix">カラーピッカー:</label>
          <input type="text" name="color" 
            class="color-picker" value="<?= $color ?>" >
      
      
        <input type='submit' value='保存' class='button button-primary button-large'>
      
  </form>
</div>
<?php
    }
}
?>

カラーピッカーに関わらず、JavaScriptでクライアント側の制御をおこないたい場合は、上記の方法で機能を実現することが通常の方法になります。