ワードプレスの管理画面に自作の設定画面を追加したり、
プラグインを自作する上で設定画面を作る方法を簡単に分かりやすく、
でも詳しくも知りたい!

ということで、初心者でも分かる(つまり私でも分かる笑)ように、
1つ1つ順を追って設定のサンプルを作ってみたいと思います。

ここでいう初心者とは、本職のプログラマーのようにどんどんコードが書けてしまう、というのではなく、HTML, CSS, PHP が多少分かっていて、あっち行きこっち行き試行錯誤しながら(調べながら)やれば、多少のことはできる、といったレベル感を指してます。

複雑に見える設定画面の作り方も1つ1つ順を追っていけばなんとかなる!

では早速行ってみましょう。

※)テスト環境は必ず用意しておこう。
ワードプレスのブログをパソコン上で動かす!XAMPPのインストール方法を解説
※)functions.php に直接書くより別ファイルにすると後々楽
WordPressでfunctions.phpを別ファイルに分ける方法!簡単な記述で管理をグンと楽にする

⇒「Settings APIの使い方まとめ」に戻る

作りたい設定画面

設定画面のサンプルとして、今回以下のような設定画面を作ってみます。

  • ①:管理画面の「設定メニュー」の下に「JINテスト用設定」を追加
  • ②:「JINテスト用設定」では「ブログ情報」や「管理者情報」が設定ができる
    (設定項目には1行テキスト入力、複数行入力、ラジオボタン、複数チェクボックスがある)

こうした設定が1つでも作成できると、あとは必要に応じてアレンジすれば、
いつでもどこでも(笑)自分の好みの設定が作れちゃいますね。

では以下の順で1つ1つ作っていきましょう

  • 1)メニューの追加:
    ワードプレスの管理画面「設定」メニューの中に新たなメニュー「JINテスト用設定」を追加してみる
  • 2)単純化した設定画面の作成:
    この「JINテスト用設定」メニューでは、
    まず試しに設定項目を1つだけにしてシンプルな設定画面の作成をしてみる(まずURLだけ入力できるなど)
  • 3)最終的な設定画面の作成:
    2)で作った単純な設定画面に残りの設定項目追加して最終系の完成!

参考にするのは、ワードプレス公式サイトにある以下のドキュメント。

これを読むと何やら入り組んでいてめまいがしてきますが(笑)
情報のソースを確認する場合には参照してみてくださいね。

では1)「メニューの追加」(をしてみる)から順に進めてみましょう。

1)メニューの追加

まずはワードプレスの管理画面のメニューに、新たなメニュー項目を追加してみます。

実際のコードから見ていくと以下のとおり。

このソース中にあるように手順は1から3とあり、
いきなり頭がくらくらしそうですが、これは型にはめるだけ。

テンプレ的に必要な箇所を必要に応じて変えればOK、ととらえるのが良いです。

上のコードは何をしているのか、手順1から1つ1つ見ていきます。

このコードを実行するとどうなる?

このコードを実行すると何がどうなるかを見ておくと、
「テーマのための関数」(functions.php)に貼り付けて実行してみた結果が以下。

①では、「設定メニュー」の中に「JINテスト用設定」が追加され、
それをクリックすると、②の設定画面が表示されました。

まだ「JINのテスト用設定画面なのだ」と設定画面のタイトルが表示されただけ。他の中身は今後順を追って作成していきます。

手順1から手順3の関係

最初に「ここが分かりづらい」といった、
上の手順1から手順3の関係から見ておくと...

こんな感じで関数を指定し、ホイホイと上から下へとパスしていく、みたいなイメージになってますね。

補足)順番を逆に考えると分かりやすいかも

考える順番というか、作る順番というか、
設定画面では「これが入力出来て」、「これはラジオボタンで選択で」...と
設定画面自体から考える場合(私がそうですが笑)、
以下のように手順を逆順に見れば分かりやすいかも。

  • 手順3:設定画面を表示する関数Aを作る:
    ここでは 関数A:jin_test_setting_func()
  • 手順2:具体的メニュー情報を定義する関数Bを作る:
    ここでは関数B:jin_test()。
    メニュー項目名の指定や、設定画面を表示する関数(関数A)を指定する。
  • 手順1:ワードプレスへ追加するメニュー情報として関数Bを指定

では手順1から具体的に見ていきましょう。

手順1)「メニュー情報」の関数名を指定

手順1ではこのコードで、
”ワードプレスに「追加したいメニュー情報の関数」はこれだよ!”
と以下の形で指定します。

”admin_menu”は、
「管理画面メニューの基本構造が配置された後に(関数名を)実行してね!」
とタイミングを指定するアクションフックと呼ばれるもの。

参考)アクションフック一覧(ワードプレス公式)

つまり、ワードプレスが管理画面のメニューを表示する時に、
ここで指定している「関数名」の関数(関数B:jin_test() )を実行してね、
ということになりますね。

手順2)「メニュー情報」の関数の内容

手順1)で指定した「メニュー情報の関数」(関数B)の具体的内容を記述。
(①~⑤の5項目)

ここで使っている「add_option_page」は、
”ワードプレスの管理画面のメニュー「設定」”の下に新たにメニューを追加する関数。

関数リファレンス:add_option_page(ワードプレス公式)

この「add_option_page」関数で何を指定しているか図にしてみると、
以下のような感じです。

上段にある④のメニューのスラッグ(slug)は今後いろいろな箇所で同じ値を設定するので、こんがらがらないような文字列にしておくと良いです。
(ここでは例として、明らかに分かるように「... -slug」という文字列にしてます)

「add_option_page」の補足)「設定」メニュー以外でメニューを追加するには

「設定メニュー」以外の場所、たとえば「投稿」メニュー下に追加するなら「add_posts_page()」を使ったりします。

参考)管理メニューの追加(ワードプレス公式)

ただ、そもそも設定内容を変更するのは最初だけ、みたいな感じで、めったやたら触るものではないし、ある時「この設定を変えたい」と思った場合にまず探すのは「設定」メニューの下になると思います。

ということから、メニュー追加は基本はこの「設定」の下にしておくのが良いと思います。

①の補足)「ページタイトル」って設定画面には表示されないの?

「ページタイトル」は、作成する設定画面上にタイトルとして表示されると思ってましたが、HTML的には「<title>ページタイトル</title>」で設定されるもの。

HTMLのソースを見ると、以下のように設定されてます。

何か「記事のタイトル」と勘違いしそうですが、
通常、記事の新規作成画面の一番上で入れるタイトルは、<h1>(または<h2>)タグで囲まれて記事上にも表示されると同時に、ワードプレスが自動的に<title>~<title>にも入れてくれてます。

ここで作成している設定画面では<title>~</title>に入れてくれるだけで記事に表示されるタイトル(<h1>や<h2>タグ)までには自動でセットしてくれない。

ということから、次の手順3で(設定画面表示用の関数Aで)、設定画面のタイトルは自分で設定する(記述する)必要がある、ということになりますね。

更に補足)「記事のタイトル」と「SEOタイトル」

ちょっと話が飛びますが、記事を作成する時、作成画面の下の欄外に「SEOタイトル」とか入力欄のある場合がありますが、ここには検索エンジンにインデックスしてほしい記事のタイトル(つまり検索結果に表示してほしいタイトル)を入れます。

そうすることでHTMLのソース的には以下のようになりますね。

<title>SEOタイトル<title>
<h1>記事のタイトル</h1>

検索結果やブラウザのタブには「SEOタイトル」が表示され、
実際の記事の先頭には「記事のタイトル」が表示される、ってことになります。

③の補足)ユーザー権限:manage_options を詳しく

③のメニューが表示される「ユーザー権限」が非常に分かりづらいですが、ワードプレスには「管理者」「編集者」「投稿者」「寄稿者」「購読者」といった権限があり(ほんとはもう1つ更に「特権管理者」がある)、その権限によって、ワードプレス内の機能がどこまで使えるか(どこまで見えるか)、が決まってます。

※)一人で運営するサイトやブログの場合、自分が「管理者」になっていると思います。
(ワードプレスログイン後「ユーザー」メニューから確認ができる)

設定系の基本は「管理者のみが操作ができる」ことになると思いますので、ここでは「manage_options」を指定して、管理者のみが「設定」メニュー以下のメニューにアクセスできる、としています。

※)「manage_options」は「設定メニュー以下にアクセスできる」といった権限で、その権限が有効になるのは「管理者」のみ。つまり「manage_options」を指定すると自動的に「管理者のみがその設定にアクセスできる」ということになりますね。

参考)ユーザーの種類と権限(ワードプレス公式)
⇒ 中段あたりの「権限・権限グループテーブル」を見ると分かりやすい

個人で運営するブログやサイトでは、運営者は「管理者」となっていると思いますので、あまり深く考えずに「manage_options」を指定しておけばOK。

④の補足)スラッグとは

スラッグ(slug)とは、英語で「ナメクジ」とか、そこから派生したのか「動きが遅い人」といった意味から「(細長く丸い)金属の塊」、「短いフレーズ/見出し/タイトル」といった意味があるようです。

ワードプレスでは(というかネットでは)、「短いフレーズ」とか「見出し」の意味として使われていることになりそうですが、urlの最後に付く部分(そのページや記事固有の文字列)を指します。

例)htttps://example.com/test-title
例)htttps://example.com/category/test-title

この2つの例いずれも最後の「test-title」がスラッグ。

2)単純化した設定画面の作成(手順3)

では具体的に設定画面を作っていきましょう!

手順3の「設定画面を表示する関数A」を作りますが、
いきなり複雑な設定画面を作るのではなく、
以下のような非常にシンプルな設定画面をまず作ってみます。

  • 「設定項目が1つだけ(URL)と「変更を保存」ボタン」のみ

※)いきなり複雑なものを作ると、上手く動作しない場合に大変。
どこが悪いかチェックしようとしても、ソースが長く何がどうなってるか頭の中がパンクして
時間ばかりかかる(半泣き状態)といったことにもなりますので。

設定画面の基本

具体的に上のシンプルな設定画面を作りますが、
そのためにはワードプレスで作る設定画面の基本の作法や、設定画面を作るための関数群「Settings API」を使います。

設定画面を作る上で「ここはしっかり理解しておきたい」というのが
「セクション」「フィールド」
(慣れないと絶対こんがらがる。私がそうでした笑)

  • セクションとは、フィールドの集まり(設定項目のグループ)(②)
  • フィールドとは、1つ1つの設定項目(③)

つまり、設定画面には「セクション」があり、そのセクションの中に具体的な設定項目として「フィールド」がある。

ワードプレスの基本的な作法を使うと、こうした形で設定画面を作る、
ということになりますね。

「セクション」と「フィールド」がどっちがどっちか分からなくなる場合

「セクション」(ある一部)、フィールド(領域)と、英語の意味合いとしては近いこともあったりして、慣れないとどっちがどっちか頭の中で大混乱してしまう場合もあると思います。
(あれ?これは私だけ?笑)

私も同じ!という場合には、慣れない内は、

  • セクション:硬い感じの響きがあるので「塊」
  • フィールド:伸ばす感じの表現なので「横長の項目」
    (つまり文字入力など1つ1つの設定項目)

みたいに捉えれば覚えやすいかも。

まずは「セクション」とは何か、「フィールド」とは何かをしっかり押さえた上で、
最初は基本形から。

このコードを基本形として、変更が必要となるのは以下3点。

  • 1)7行目:設定画面に表示するタイトルを適宜修正
  • 2)10行目:「field-group」を適宜修正
    (あとで変数を「1つのグループに属するもの」みたいに登録しますが、ここでそのグループ名を適当な名前(かつ分かりやすい名前)を考えて付けて設定)
  • 3)11行目:「page-slug」は、手順2(add_options_page)で決めた「④ メニューのスラッグ」にする

ワードプレス公式サイトのドキュメントに記載されている形ですが、
あまり深く考えずテンプレートとして使うのが良いですね。

補足)action='options.php' を詳しく(3行目)

formタグ内には「変更を保存」ボタンなど設定したデータの送信ボタンがあり、そのボタンを押して送信されるデータの送信先を action =" 送信先 " によって指定する。

ワードプレスで既に用意されている「options.php」を指定すると、この「options.php」がデータを受け取り、権限チェックやらデータの保存などをやってくれる、といった非常に便利なもの。
(ということで何も考えずにこれを設定!)

補足)settings_fields('field-group') を詳しく(5行目)

「settings_fields('field-group')」関数ではグループ(ここでは field-group)を指定しますが、そのグループに属するフィールド(設定項目)に対して、ノンス(セキュリティ用途で使われるランダムな文字列:この文字列をデータに付けることで、正しく入力されたデータか判断するのだ)や貧弱性に対する攻撃対策のための非表示フィールドを自動で付けてくれるもの。

実際このsettings_fields('field-group')を付けて設定画面を表示させてみると、そのHTMLには以下のように隠しフィールド(①)(type="hidden"が付いたもの)やノンス(②)が自動で設定されているのが分かります。

プログラムをバリバリやる人なら自分でそうしたところまで記述するのかもしれませんが、ワードプレスでは自動でやってくれる関数が用意されているので、一種の「おまじない」だと思ってとりあえず付ける!

設定する値:設定項目のグループ名
(このグループ名は変数登録時に使うので、何気にそれと分かる名前にしておけばOK)

参考)関数リファレンス:settings_fields (ワードプレス公式)

補足)do_settings_sections( 'page-slug') を詳しく(6行目)

「page-slug」で指定したページのセクションをすべて表示する。

セクションで設定されているタイトルを<h2>タグで表示してくれて、セクションに属するフィールド(各設定項目)をテーブルで表示してくれる。

参考)関数リファレンス/do settings sections(ワードプレス公式)

補足)submit_button() を詳しく(7行目)

これをform内に書いとけば「変更を保存」とかの文字列の送信ボタンを自動で出してくれる優れもの。(何も考えずに付けておく!)

「submit_button()」のようにカッコ内になにも入れない場合は、
「変更を保存」といった文字列の送信ボタンが表示される。

この文字列を変えたい場合には、
以下のようにカッコ内に表示したい文字列を設定すればOK。

参考)関数リファレンス/submit button(ワードプレス公式)

この基本形コードに対して、以下のように修正を入れる。

  • 1)5行目:設定画面に表示するタイトル
    ⇒「JINのテスト用設定画面なのだ」に変更
  • 2)8行目:「field-group」
    ⇒ フィールドのグループと分かりやすく(長くなりますが)
    「jin-test-setting-field-group」に変更
  • 3)9行目:「page-slug」
    ⇒すでに上の方で決めている「jin-test-setting-slug」に変更

ここまでのコードの全体像は以下。

このコードを実行するとどうなる?

実際にテーマのための関数(functions.php)に貼り付けて動作を確認してみると...

設定画面のタイトルは、実際記述したように(見た目では分かりませんが)<h1>タグで表示され、「変更を保存」といった送信ボタンが表示されました。

まだセクション(フィールド(設定項目)の集まり)やフィールド(設定項目)自体を作ってないので、ここではこの表示だけ。

この時点で「変更を保存」ボタンをクリックすると、
何も動作しない、ではなく、以下のようなエラーが出ますね。

URLを見ると <form>タグの中でデータ送信先として「action = "..."」で指定した 「options.php」が働き、あれ?ということでエラーを表示しているようです。

エラー内容を見ると、

「jin-test-setting-field-group」がないよ!

ということですが、これはちょっと上でまとめた「ここまでのコードの全体像」の23行目、settings_fields( 'jin-test-setting-field-group' ) で指定しているもの。

options.php は、そうしたところまで見ている、ということになるでしょうか。

ではセクションやフィールドを作ってみましょう。

セクションを追加する

全体の形ができたところで、続いてはセクションの作成。

セクションはフィールド(設定項目)の集まり。
フィールド(設定項目)をどこに表示するかといった箱になるものです。

このセクションを作る実際のコードから見ていくと以下。

このコードもテンプレ的に使えばOK。

セクション自体は7行目から13行目にある add_settings_section関数でつくりますが、関数を作って(ここでは「jin_test_setting_section_init()」)その中に記述します。

  • 5行目:関数名(他と被らなければなんでもOKの文字列)
  • 7行目~13行目:セクションを作る本体(add_settings_section)
  • 16行目:この関数を admin_init フックを使って実行
    (admin_initフックを使うと、どのフックよりも優先して実行される)
  • 19行目:add_settings_sectionが実行されるときに呼び出される関数
    (11行目で指定されている関数)

セクションがないと設定項目(フィールド)も表示できないことから、
admin_init フックを使ってまず最初にセクションを作ります。
(セクションを作る過程で、何かしたいことがあれば関数(コールバック関数)を実行する、という形)

add_settings_section を詳しく

7行目~13行目のadd_settings_sectionは、以下の形で使います。

参考)関数リファレンス/add settings section(ワードプレス公式)

どのページでどういった表示がされるセクションなの?
という感じで中身を埋める。

  • ① $id:セクション固有のID(任意の文字列)
    (フィールド(設定項目)はどのセクションで表示するか、セクションを特定する(指定する)必要があり、この「どのセクションか」を特定するためのセクション固有のID(文字列)を設定)
  • ② $title:設定画面上、セクションのタイトルとして表示される
    ( <h2>$title</h2>で表示される)
  • ③ $calback:このadd_settings_sectionが呼ばれた時に実行される関数を指定
    (何か特別に関数を実行させる必要がなければ、関数だけ作って中身はなしにしておけばOK)
  • ④ $page:設定画面のスラッグ
    (どのページにこのセクションを表示するか、という指定で、そのページのスラッグを設定)

③のコールバック関数とは、ある関数が呼ばれた時に実行される関数の事。

ある関数が呼ばれ、その中から呼び返す形でその関数が呼ばれることから、コールバック関数、なんて表現されるんですね。

慣れないうちは意味が取りづらいですが、呼ばれた関数の中で「これを実行してね」と指定されている関数、と思ってもらえればOK。

今回のサンプル設定画面に当てはめると以下のようになりますね。

  • ① $id:
    明らかにセクションと分かるように「seciton」の文字を入れ、
    また最終的にはセクションは複数(2つ)持つことを想定しているので、「jin_test_setting_section_id1」と最後に番号を付けておいた。
  • ② $title:
    セクションのタイトルは「ブログ情報」を指定
  • ③ $calback:
    何に使うのか分からないけど
    「jin_test_setting_section1_callback」としておいた
  • ④ $page:
    どのページに表示するセクションか、ということで、
    今回最初に設定しているスラッグ(jin-test-setting-slug)を設定

コールバック関数について

何に使うかよく分からないコールバック関数(上の③)は、何もしないとして中身無しでも良いですが、試しに「設定の補足を表示する」ぐらいにしておきます。

コールバック関数としては、「ブログの情報を入力してね」と
補足の文字列を単に表示するだけにしておきました。(20行目)

ここまでのコードの全体像と実行結果はこちら

33行目から53行目にセクションを作るためのコードを追加。
コールバック関数には、単に補足の文字列を表示するようにしている。

実際に実行してみると以下のように表示されます。

フィールドを追加する

フィールド(設定項目)を表示する領域(セクション)ができたので、
実際に入力ができるフィールド(設定項目)を具体的に作りましょう。

まず1つだけ、URLが設定できる項目(フィールド)を作りますが、
実際のコードから。

このコードも上で作ったセクション同様、テンプレ的に使えばOK。

フィールド自体は7行目から14行目にある add_settings_field関数でつくりますが
(セクションを作った時と同じように)関数を作ってその中に記述します。

  • 5行目:関数名
    (他と被らなければなんでもOKの文字列)
  • 7行目~14行目:フィールドを作る本体
    (add_settings_field)
  • 16行目:この関数を admin_init フックを使って実行
    (セクション同様、admin_initを使って、どのフックよりも優先して実行)
  • 21行目:add_settings_fieldが実行されるときに呼び出される関数
    (10行目で指定した関数)

add_settings_field を詳しく

add_settings_field は以下の形で使います。

参考)関数リファレンス/add settings field(ワードプレス公式)

設定する内容が多いのでなんですが、
どのページの、どのセクションで、どういった内容を表示するの?
ということを設定します。

  • ① $id:フィールドの固有のIDを設定(任意の文字列)
    公式の関数リファレンスを見ると、inputタグ内の id属性 にもこのIDと同じ文字列を設定する、となっているけど、実は同じでなくても動作するようだ。
    詳しくは以下で調べた結果をまとめてます。
    add_settings_fieldのidはinput要素のid属性と同じにする必要はない?
  • ② $title:設定画面上に表示される、項目のタイトル(ラベル名)
  • ③ $calback:実際に<input ~ >を表示する関数を指定
    テキスト入力ボックスやラジオボタンなどを表示
  • ④ $page:これまでも色々と利用している設定画面のスラッグ
    最初のadd_options_pageで指定しているもの
  • ⑤ $section:表示させたいセクションのIDを設定
    ここでは先ほど上で作ったセクションに表示させるのでそのIDを設定
  • ⑥ $args:(省略可)コールバック関数に引数を渡したり'label_for'を指定
    配列指定:'label_for'を指定して①のidを入れると項目名をlabelタグで囲んでくれる。③のコールバック関数に渡す引数も設定できる

ここでは、まずはURLの入力ボックスが1つだけの設定画面を作る、ということで、
それに当てはめると以下のようになりますね。

  • ① $id:
    明らかにフィールドと分かるように「field」の文字を入れ、URLの設定項目と分かるように最後に「_url」を付けた。
  • ② $title:
    URL入力の項目名なので「URL」を設定
  • ③ $calback:
    URL項目の表示関数と分かるよう最後に「_url」を付けて「jin_test_setting_field_callback_url 」としておいた
  • ④ $page:
    どのページに表示するフィールドか、ということで、セクション同様、今回最初に設定しているスラッグ(jin-test-setting-slug)を設定
  • ⑤ $section:
    どのセクション内に表示するか、ということで、セクション1のIDを設定
  • ⑥ $args:
    項目名(URL)を
    <label for="id"><input .... ></label>
    としてもらえるように「'label_for' => 'field_id_url '」を指定。
    ('field_id_url' は①で指定しているこのフィールドのID)

コールバック関数を作る

フィールドのコールバック関数(③)では、input要素を記述するコードを書きます。

このコールバック関数名は、
すでにフィールドを作った時に名前を決めているので(③)それを使う。

URLの入力なので1行テキストの入力ボックス。

  • name属性:
    変数名。
    この後に変数の登録をするけど、この name で指定した文字列を変数名として使う。ここでは item_url としておいた。
  • id属性:
    フィールドのidを設定(上の方の①で設定したもの)
  • type属性:
    URL入力なので、type="url" を使っておく
  • maxlength属性:(最大入力文字数)
    ブラウザによって挙動が違ったりするのでなんですが、一応制限を付けておく、ということで200文字としておく
  • value属性:
    入力された値をセット。
    get_option関数でデータベースから呼び出す。
    値の呼び出しではesc_url関数で無害化(サニタイズ)しておく。
    (無害化については、次の「設定値と初期値を登録する」を参照)
補足)フィールドのid と inputタグ中の id との関係メモ

add_settings_fieldの関数リファレンスをみると、add_settings_field で設定したフィールドの $id文字列は、inputタグ中のid属性と同じにする旨の記載がされてますが、実際には同じにしなくても正しく動作するようです。

(WordPress 5.8.2で確認している限りはそのようになっている)
(だからというか、なんでこうなるんだ?みたいに物凄く悩んだところ)

詳しくは以下の記事で調べてますが、add_settings_field で label_for を指定する場合には idを同じにする必要があるし、そうでなければそろえなくても良さそうです。

add_settings_fieldのidはinput要素のid属性と同じにする必要はない?

ここまでのコード全体像と実行結果はこちら

67行目から78行目にフィールド(設定項目)を表示するためのコードを追加。
85行目~88行目のコールバック関数で、実際にURLの1行入力ボックスを表示している。

実際にこの実行してみると以下のように表示されます。

うぉぉぉ、遂に入力欄が表示されたぞ!

喜び勇んでこの時点で「変更を保存」ボタンを押してみると...

エラーが表示されますね。

ここまでで、URLの入力まではできましたが、
その入力された文字列(設定値)の登録がまだできてないから。

設定値と初期値を登録する

最後は、設定する文字列などをSettings APIで送受信できるよう、
「使う変数はこれだよ」と設定値の登録というのをします。
(あわせて初期値の設定もする)

まずは実際のコードから。

初期値を決めておく

初期値の登録は、実際には19行目から26行目の register_setting で行いますが、ここではちょっと見やすくなるように、まずは初期値はこれ、と11行目で書いておく。

URL入力なので、初期値は空文字としておく。

設定値の登録

設定値をSettings APIで認識してもらうために設定値の登録、というのをしますが、Settings APIで用意されている「register_setting」関数を使うだけ。

  • 3行目:グループ名
    「設定画面の基本」のところの「settings_fields」で指定した文字列を設定
  • 4行目:設定項目名
    input要素のname属性で指定した文字列を指定
  • 6行目:サニタイズ(無害化)のための関数を指定
    URL入力の変数登録なので、サニタイズはワードプレスで既に用意されている esc_url関数を指定。
    (送信ボタンを押してデータ送信時(データベースに登録時)、このサニタイズ関数を通過する)
  • 7行目:初期値の設定。先ほど設定した初期値用の変数を指定。

参考)関数リファレンス/register_setting(ワードプレス公式)
参考)関数リファレンス/esc url(ワードプレス公式)

初期値の設定はデータベースへのデータ登録とは違う

実際にデータベースを見てみると、このregister_settingで設定する変数名(ここでは「item_url」)や初期値は、データベースに登録されるわけではないようだ。

つまり get_option でデータ取得しようとする時、データベースにまだそのデータ項目がない場合、取得される値を設定しているだけ。

実際にはフォームの送信ボタンが押されて初めてデータベースに項目名とその値が登録される。

何かしらの理由から初期状態でもデータベース上に項目名や値といった実体が必要な場合には、update_option() や add_option() を使って初期値の設定をするのが良さそう。

関数リファレンス:add_opttion(英語)
関数リファレンス:update_opttion(英語)

無害化とデータ送受信について詳しく

「無害化」または「サニタイズ(sanitize)」とは、データベースに値を保存する時やデータベースからデータを取得する時に、セキュリティ的に問題のない文字に加工すること。

参考:データ検証(ワードプレス公式)

文字の中にはそれ自体に意味が含まれる特殊なものがある。
(たとえば「<」「>」など)

そうした文字をそのままデータベースに入れると、データベースが意味ある文字として解釈してしまい(データベースはものすごくデリケートで真面目なのだ)予期せぬ動作をしてしまう(データベースが破壊されてしまう)ことにもなる。

またデータベースに保存されているデータも同様で、そのデータを取得しそのままブラウザ(やアプリなど)で表示しようとしたときに、やはり予期せぬ動作をしてしまう(勝手にコードとして実行されてしまう)場合がある。

そうした意図しない動作にならないよう、特殊な文字は単なる文字として扱うよう変換したり取り除いたりする。つまり、有害の恐れのある物を取り除き無害にする、ということで無害化(英語で言えばサニタイズ(sanitize))と表現される。

実際上のコードをワードプレスで実行してみてデータベースの値を直接確認したところ、このregister_settingで指定されたサニタイズの関数はデータ送信時(データベースにデータを書き込む時)に毎回通過するようだ。

でも get_option でデータを取得するタイミングのサニタイズ(無害化)はここを通過しないので、get_optionでデータ取得の場合には改めてサニタイズが必要になる。

esc_url()はURL文字列を無害化する関数で、URLに適さない文字や危険な文字が含まれていればデータベースに害が及ばないURLの文字列になるようにするもの。

input要素中、type属性で「url」を指定しているので、それで十分では?という気もするけど、input要素はブラウザでの対応であり、ブラウザによって対応がどのようになっているのか分からないし、データベースからの値も信用するものではない、ということから念のため esc_url を指定している。

初期値の工夫

ちょっとテスト的に、URL入力の初期値にひと工夫してみましょう。

何も入力されてなかったり、文字列が全て削除された場合、
ガイド的に「http://」とだけ表示する、というのはどうでしょう。

14行目から16行目で初期値を設定するように修正した例。

  • 1) get_option() で設定値の中身を取得して(それをesc_urlで無害化して)、
  • 2) falseの場合(空の文字列やNULLなどそもそも何も設定されてない場合)
  • 3) update_option() で「'http://'」で上書きする(初期値に設定する)

参考)register_setting関数と初期値の設定の詳しくはこちら
関数リファレンス:update_opttion(英語)

14行目から16行目で初期値を設定するので、
最初に初期値を設定した11行目はコメントアウト。

これに関連して register_setting 内の配列でサニタイズ関数と初期値を設定していた配列の箇所をサニタイズだけにした(27行目)。

こうなると、先ほど作ったinput要素のtype属性も
"url" から普通に "text" とかにしておくのが良さそうです。(type属性が url の場合「http://」だけの入力だと「URLを入力してね」なんてブラウザがエラーのポップアップを出してしまって先に進めない、設定の保存ができない~、なんてなってしまうので)

ということで3行目のinput要素では、type属性を text に変更。

コード全体像と実行結果はこちら

いよいよここまでたどり着けました。

URL項目の入力が1つだけ、といったシンプルな設定ですが、
ここまでのコード全体像は以下になりますね。

このコードを実際にテーマのための関数(functions.php)に貼り付けて実行してみると、以下のように動作しているようです。

①では初期値が表示され(①)、②の「変更を保存」でデータも保存されます。

URLに使えない文字( '>' '<' など)を入れると、サニタイズ関数として指定したesc_url() が働いて、そうした文字を削除する、ということも確認ができますね。

また label_for を指定したので、項目名「URL」をクリックすると、1行入力ボックスをクリックしたのと同じ動作をするのも確認ができます。

全ての設定項目を入れて完成形へ

何かワードプレスの動作が非常にモッサリと遅くなって、
これ以上書くのが辛くなりましたので、完成形は別記事で行いましょう。

⇒「Settings APIの使い方まとめ」に戻る

早期退職して海外で奮闘する JIN のメールマガジン

時間や場所に縛られず稼いだJINが教える

~ 最短で月収10万円稼げるようになる方法 ~

お名前(全角文字)

隣のあの人にも、思わず教えたくなる秘密

配信停止は、いつでもできます

迷惑メールは一切配信されませんので、ご安心くださいね

自らの手で未来を変える力を手に入れる!