wordpress管理画面にテーマのオプション設定ページを表示
テーマを作る時にそのテーマ独自のオプションを設定して使いたいときがあります。
設定によってサイトの表示や使用する機能を変更するとか、特にhtmlやcssをいじれない他の人用に作る場合など必要になることがあります。
そしてそのオプションの設定が管理画面でできれば誰にでも使えて便利です。
今回、そういうテーマを作成するにあたり以下のようにオプションを設定しました。合計11ケのオプションを設け、それらを連想配列にして一つ(hiros_options)にまとめ、wordpressのオプションに保存します。
wordpressには独自テーマやプラグインのための独自の設定データをwordpressデータベースに保存・更新・読出をする機能があります。
wordpress日本語版codexのプラグイン作成のページを見るとwordpress設定にアクセスするための必要な関数は以下の二つ。
オプションを設定するにはupdate_optionを使い、設定したオプションの値を取得するにはget_optionを使用するということでわかりやすいです。
引数の$option_name は作成または更新、取得したいオプションの名前。$newvalue は作成、更新する時のオプションの値。新規にオプションを設定する場合でもupdate_optionで大丈夫。尚、オプションの値として保存できるのは文字列(string)、配列(array)、もしくはPHPオブジェクト。
ということで実際にfunctions.phpに設定したオプションは以下のよう。ちなみにテーマの名称はhiros です。
*2023/2/27:オプションをチェックする関数を更新してあります。
まず、オプションを登録するためのデフォルト設定値の配列を作っています。
そして既にオプションが設定されているかを確認するために取得します。
既にオプションが設定されている場合、オプションを追加したり削除したりした時のために、登録用に設定している配列との個数を比較し、異なった場合はすでに設定されているオプション値を有効にするために新しいオプションの配列をいままでの配列でarray_merge によって配列の上書きをし、オプションが設定されていない時と同様に新規に登録します。
ちなみに、オプションを削除したなど、オプションの数が減っている場合はphp のarray_intersect_key関数を使って余分となった配列中のオプションを消去しています。
既に登録済みでその個数も変わらなければ、その設定値をextract関数で連想配列のkeyを変数名とした個々の変数に分けています。
注:ちょっと思う所があってwordpress の PHP Coding Standards に目を通してみたのですが、「Don't exract()」と題打ってextract()関数は terrrible function であるから使用しないようにとありました。
実を言うとこれを見る前のコードは上述のように最後に オプションの連想配列から extract() で個々の変数を作るということをやっていたのですが、改めて考えて見ると個別の変数にわざわざ分ける必要は全くないので、その点を修正しています。
実際にupdate_option が動くのは初めてテーマを読み込んだ時か、オプションの個数に変化があった時だけということになります。
functions.phpで得た各オプションの値をもつ変数は、index.php やpage.php 内ではそのまま使用でき、header.php やfooter.php ではglobal 宣言すれば使用できます。
例えば何か使い勝手の都合とかで、取得するオプションが複数あって、オプションチェックの行程を同じ条件式のなかで出来るとかの場合なら、関数よりもクラスを使ったほうが使い勝手が良いかもしれません。
ほとんどクラスは使ったことがないのですが、こんな感じでしょうか。
« add_theme_pageによる管理画面のメニュー登録 »
そして次なるはいよいよこのオプション値を管理画面で変更、更新できるようにすると。
まずは管理画面のメニューにオプション設定の項目を追加します。
今回はテーマのオプションなのでメニューの「外観」にサブメニューとして項目を追加します。その場合はadd_theme_page を使用すれば良いということです。
codexだと英語版ですがFunction Reference/add theme pageになります。
パラメータは以下の通り。
$page_title | 必須 | メニューをクリックした時に表示されるページのタイトル |
$menu_title | 必須 | メニューに表示されるタイトル |
$capability | 必須 | このメニューページを閲覧・使用するために最低限必要なユーザーレベル またはユーザーの種類と権限 |
$menu_slug | 必須 | このメニューページの識別子となる独特な名前 |
$function | 任意 | メニューページにコンテンツを表示する関数 |
このadd_theme_page を関数にして、アクションフックのadmin_menu で作った関数を登録するということです。
ユーザーレベルはadministrator にしています。
次に入力した値をオプションとして保存するために登録することが必要なのだと思います。
それにはregister_setting 関数を用い、アクションフックadmin_init にて登録するということのようです。
codex 設定ページの作成にある例では下記の通りです。登録するオプションが複数ある場合は例のようにregister_setting を複数登録するということです。
register_setting のパラメータは次のとおり。
$option_group | 必須 | オプションのグループ名 |
$option_name | 必須 | 登録するオプションそのものの名前 |
$sanitize_callback | 任意 | オプション値をサニタイズするためのコールバック関数 |
$option_group はadd_theme_page の第5パラメータにおいて指定した実際のページのhtml を出力する関数の中において使用する、settings_fields関数の引数として指定します。$option_name は実際に保存するオプションの名前で、出力されるhtml のinput 要素のname 属性に指定することで、フォームを送信した時にこのオプション名で保存されます。
「codex 設定ページの作成」のもっと下の方を見ると、add_theme_page とregister_setting を含む関数を登録するadmin_init のアクションフックは同じ関数に含め、アクションフックadmin_menu に登録しているので同じようにしました。
実際にfunctions.php に記述しているのはこれ以降のコードです。
そしてadd_theme_page の第5パラメータで指定した、実際のページのhtml を出力する関数hiros_page_output を作ります。
18、21~25、41行目はcodex において指定されているとおりの記述です。
23、24行目のsettings_fields関数とdo_settings_sections関数はお約束でこれによりwordpress がオプションページを上手に処理してくれるとのことです。尚、引数には前述したとおりregister_setting の第一引数$option_group で指定した名前を指定します。
5~16行目の連想配列は各オプションの説明を表示さるためのものなので必要の無い物です。このテーマの場合のオプションの設定値は0 か1 だけなので全てラジオボタンにしています。
保存するオプション値は個々のオプションを連想配列でまとめた値にしていますので、フォームから送信されるデータも同じ様に連想配列で送信されるようにしています。
実際に出力されたhtml は以下のとおり。
尚、見やすいように字下げと改行を入れてあり、途中を省略してあります。
5~8行目がsettings_fields関数によって出力された部分。nonce とrefererが出力されています。nonceに関してはこちら→「カスタムフィールドの投稿入力フォームへの表示«nonceに関して»」に書いています。
あれっ?となるとdo_settings_sections関数は何をしているのだろうかと?codex には「この関数は、フォームのマークアップ自体を面倒みてくれます。」と書いてあります。どうやら add_settings_field関数を使用する場合に有効なようなのですが・・・、説明がよくわからない。実際にこれを無くしてしまっても出力されるものは同じで、設定の保存も問題なく出来てしまう。この場合は必要無いようです。
« あとを汚したままにしないようにオプションの削除 »
この後、プラグインを作ったりしたのですが、プラグインを使用しなくなった時に、データベースに保存してあるオプション値を消去する処理も、いらない物を後に残さないためには必須な処理であったのですが、当然これはテーマであっても同じことです。
プラグインに関しての処理はここの→《コメントの編集機能、nonceで作り直してプラグイン》中段やや下のところに書いているのですが、テーマの場合はどうやればいいのか調べてみてもあまり出ていないというかよくわからない。探し方がへたくそなのかなぁ~?「delete_site_transient 」というのがあったもののなにやらよくわかりませんでした。唖然!
それではと、プラグインの処理がそのまま使えるかとやってみたものの、それはやはりダメですね。
どうしたものかと、テーマに関していそうなファイルの中身を全部調べて見れば何かわかるだろうと、結果、「/wp-includes/theme.php 」の中、677行目辺りにfunction switch_theme を見つけました。codex によれば「現在のテーマを、新しいテンプレートとスタイルシートに切り替えます。」という関数とのこと。
そして、この関数の最後にswitch_theme というアクションフックが用意されています。英語版codex によれば「switch_theme is triggered when the blog's theme is changed. Specifically, it fires after the theme has been switched but before the next request. Theme developers should use this hook to do things when their theme is deactivated. 」
なんとか、訳しますと、
「ブログのテーマが変更されたときswitch_themeが誘引されます。具体的に言えば、テーマが切り替わったあと、しかし次のリクエストの前に発火します。テーマ開発者はテーマが非アクティブ化されたときに処理することがあれば、このフックを使用するべきです。」と、いうことだと思います。
使用方法もいたってシンプルで、同じくcodex→ 《Plugin API/Action Reference/switch theme》によれば、
と、いうことです。
ただし、これはテーマを変更した時に動作するということなので、変更するたびにオプションは消されてしまう。ただ、ちょっと他のテーマを試してみたいだけというようなときは、オプションを残しておきたいときもあるのではないかと。
と、いうことで、この処理もオプションで選択できるようにして実際には以下のようにしてします。
これもプラグインの時と同様にクラスの中に入れてしまおうと、同じように色々やってみたのですが、どうもうまくいきませんでした。よって、クラスの外に普通に書いています。こんな具合で・・・。
Post : 2014/12/21 01:23
Talking
通りすがりさんのおかげで他にも色々とおかしなことになっていることに気が付きました。
さっそく直しています。
ほんとに感謝してます。
言葉が悪すぎでしたねf^_^;
迅速な対応でビックリしました笑
通りすがりさん、コメントありがとうございます。
ほんとに仰る通りでうざいですね。
うれいしいですね、このような的を射たアドバイスを下さって。
ちゃんと確認しなければいけませんね。
位置を変更したり色々やっているうちに、あまり必要の無いものと気づきました。
本当に貴重なご意見ありがとうございました。
すまほで追従するメニューがうざすぎ
Comments feed
Trackback URL : https://strix.main.jp/wp-trackback.php?p=49712