メニュー
CREATE ACCORD PURPOSE

WPプラグインを自作!制作まとめ

WordPressプラグインを自作。制作方法まとめ

どうしても欲しかった機能があり、WordPressプラグインを自作。せっかく作るなら、WordPressプラグインディレクトリに登録してみたいと思ったので、今回は自分が調べた情報を全公開します!
ずっと前にもどき(?)を作ったことならあるのですが、改めて調べながら作ってみると、スムーズに行かなかったので、つまずいてしまったポイントもフォローできれば嬉しいなと思います。

その後、二度目のプラグイン制作を行ったので、新しい情報なども反映、古い情報は修正しました。(2025年8月2日追記)

クリエイトアコードの記事かどうかは問わず、技術的な投稿を見るときは最終更新日をご確認いただくことを強く推奨しております。
最終更新日より1年以上経過している場合は非推奨なやり方または関数を利用している可能性がありますので、掲載情報を扱うときは必ず最新の情報をご確認いただいた上でご利用ください。
不安な方は、クリエイトアコードのSNSのDMまたはお問い合わせよりお問い合わせください。

目次

WordPressの自作プラグインの作り方(手順)

人生初(だと思う)レビュー時に色々と教えてもらったことも含めてまとめているので、ある程度手順化して書いています。
その後、二度目のプラグイン制作を行ったので、新しい情報なども反映、古い情報は修正しました。(2025年8月2日追記)

(1)自作プラグインの本体となるPHPファイルにコメントで必要な情報を書きます

ファイル名もプラグインの名前に準拠し、「プラグインのスラッグが機械的に判断される」ため、ご注意ください。
プラグインのドメインの指定が最初の頃は、いまいち理解できず、レビューで指摘された上で改めて調べ直してやっと理解できたのに二度目のプラグイン制作では失念および理解がしきれていなかったことが発覚した(前回は奇跡的に一致していた)ので、改めてまとめ直しました。なお、自身のプラグインデータは現在ライブラリで公開しているプラグインはすべて修正済みです。

とにかく「プラグインの名前(英訳・ハイフンなし・大文字小文字使用)」「プラグインの本体のPHPファイル名(英訳・ハイフンあり・小文字のみ使用)」「テキストドメイン(プラグインの本体のPHPファイル名と完全一致)」はすべて一致する必要があると覚えておけば大丈夫です。

/*
* Plugin Name: プラグインの名前
* Plugin URI: 配布元のサイト、ページURL。プラグインの情報があるページがベスト。
* Description: プラグインの説明
* Version: プラグインのバージョン
* Author: プラグイン開発者
* Author URI: プラグイン開発者のサイトURL
* License: ライセンス
* License URI: ライセンス情報の記載があるページ
* Text Domain: プラグインのドメイン。これは翻訳時にも使用する
*/

前まであったコメント
「Domain Path: 翻訳言語のフォルダを指定(/languages)」
Domain Pathは「プラグインを国際化するための翻訳ファイルのパス」ということであり、公式ライブラリを介してプラグインを配信していれば読み込むことはないので不要でした。

(2)セキュリティ対策を行う

外部から不正にアクセスされ処理を実行されるのを防ぐためのコードを記述します。「ABSPATH」はWordPressのインストール先のディレクトリ(wp-config.phpが置かれたディレクトリ)のパスを示す定数なので、定義されていなければスクリプトが実行できずに終わるので、『WordPressを起動している本体のみPHP処理の実行を可能にする』ことができるようになります。

if (
    !defined('ABSPATH')
) exit;

(3)パフォーマンス対応

もし、サイトオプションを新規に作るのなら、プラグインをアインストールしたときに削除しておきます。ゴミとなるデータは残したくないしね!
「register_uninstall_hook」は、プラグインのアインストール字に呼び出される関数を登録する関数です。

(本音)テストのためにインストール・アインストールを繰り返していたのですが、その度にデータが復活してしまったのが気になったのとデータベース上で直接消さないと消えなかったから、ちゃんと消しておきたいなと思いました。

register_uninstall_hook(__FILE__, '呼び出す関数');
function 呼び出される関数名()
{
    delete_option('サイトオプションのキー');
}

【現在は不要】(4)翻訳ファイルの読み込み

プラグイン(テーマもだけど)は基本英語なので、翻訳ファイルが必要となるため、翻訳ファイルがあれば読み込むように設定する必要がありました。
WordPressの本来のバージョン更新に伴い、翻訳ファイルの仕様が変わったため、WordPressの古いバージョンをまだサポートする場合や公式ディレクトリで公開しない場合は必要だけど「最新のWordPressのバージョンしかサポートしないよ」としている場合はいらないよ、とのことでした。
(当方が翻訳の権限を付与してもらって翻訳文章を登録しているのもあるんだと思います)

add_action('init', function () {
    load_plugin_textdomain('プラグインのドメイン');
});

日本人固有で必要な機能というわけじゃないなら、後で翻訳すればいいので、使用用語自体は英語で統一した方がいいと思う。

プラグインの翻訳フォルダ「languages」の中には、下記のファイル「readme.txt」を入れます。

Translations have moved to
https://translate.wordpress.org/projects/wp-plugins/プラグインのURL

Thank you for your contribution.

他の人のプラグインにあった記述を参考に書いています。
この前に翻訳ファイルを試行錯誤して作っていた名残ですが……。
後ほど出てきますが、「WordPressの翻訳側で翻訳しているのでファイルはないよ。引っ越したよ」というようなことを書いていました。現在はありません。(2025年8月2日)

(5)ここから自作プラグインの本体の制作に入ります。最初にメニュー登録をします

プラグインのメニュー登録をします。設定画面を用意するなら、必要になります。

設定画面や説明画面等のないプラグインも中にはありますが、「これをするだけ!」のように一言で説明できるプラグインじゃないなら、用意してあげた方が親切かなと個人的には思います。既にあるメニュー「設定」や「ツール」に含めるやり方もあるはずですが、探していませんでした。改めて今思うと、プラグイン追加した後に「設定画面どこー?」ってなりやすいので、独自メニューがあった方が自分にとっては有り難いですね……。

色々試行錯誤したのだけれど、結果的に「メインページ表示呼び出し用」は「サブページ表示呼び出し用」と同じものを指定して、登録しておいた方がいいと思う。

必要な権限の設定は、管理者で指定しておけばいいかなと思っていますが、プラグインの用途で選ぼう。また、メニューが表示される位置のインデックスはサンプルコードでは「0」としていますが、クリエイトアコードが作ったときは「81」で指定しました。そんな重要な設定じゃないなら、下に配置するのが良さそう。

add_action('admin_menu', function () {
    // メイン設定
    add_menu_page(
        '', // ページのタイトル
        '', // 左メニューテキスト
        'manage_options', // 必要な権限の設定
        '', // 左メニューのスラッグ名
        '(以下のメニューの「サブページ表示呼び出し用」で使う関数名を登録)', // メインページ表示呼び出し用(サブメニューを使う場合は空)
        '', // メニューアイコン https://developer.wordpress.org/resource/dashicons/#awards
        0 // メニューが表示される位置のインデックス(0が先頭)
    );
    // サブメニュー(親メニュー)
    add_submenu_page(
        '', // 親メニューのスラッグ
        __('(英語訳。ページのタイトル名)', '(プラグインのドメイン)'), // ページのタイトル
        __('(英語訳。ページのタイトルと同じものを指定)', '(プラグインのドメイン)'), // 左メニュー(サブメニュー)テキスト
        'manage_options', // 必要な権限の設定
        '(親の「左メニューテキスト」を指定)', // サブメニューのスラッグ名(親と同じにすると親メニューもサブメニューに連動)
        '(メインページ表示呼び出し用とおなじものを指定)', // サブページ表示呼び出し用(任意)
        0
    );
    // サブメニュー「(サブメニュー名)」(事実上の子メニュー)
    add_submenu_page(
        '', // 親メニューのスラッグ
        __('(英語訳。ページのタイトル)', '(プラグインのドメイン)'), // ページのタイトル
        __('(英語訳。ページのタイトルと同じものを指定)', '(プラグインのドメイン)'), // 左メニュー(サブメニュー)テキスト
        'manage_options', // 必要な権限の設定
        '', // サブメニューのスラッグ名
        '(サブページ表示呼び出し用の関数名を指定)', // サブページ表示呼び出し用(任意)
        81
    );

(増やしたかったら、【サブメニュー「(サブメニュー名)」(事実上の子メニュー)】をコピペして中身を変えて使ってください)

});

もう一つ、プラグインの親子メニューで詰まったときに見ていたページ、サイトごとなくなってた!
引っ越したのかなと思って記事名で探しても見つからず……。
数ヶ月でサイトが消えるって……とこれを書いていて知ったときは衝撃を受けました。

(6)自作プラグインの本体の制作の続きです。実際に画面を作ったり実行する処理を書いたりします

メニューがあるなら表示する画面を用意しましょう。
表示や設定処理については、それぞれ作る内容が異なると思うので、サンプルソース内では記載をしていません。

function メニューで登録したメイン設定の関数名()
{
    // アクセスしたときに権限があるか確認
    if (!current_user_can('manage_options')) {
        // エラー文章
        wp_die(__('英語訳。「権限がないよ」という内容を記述', 'プラグインのドメイン'));
    }

    // 表示
?>
(表示部分や設定処理を記述します)
<?php
}

自分が作ったプラグインの処理をさらっと書くと「get_optionで既に保存してある値があれば取得する」「POSTされたデータがあれば取得し、サニタイズして、サニタイズしたデータを保存する更新時の処理を書く」「表示用の関数に入れて、画面に更新したことを示すメッセージを表示する」「フォームを作り、同じPHPファイルにデータをPOSTする」「wp_headまたはwp_body_openのアクションフックを使って、保存してある値を使ったコードを生成する」です。正直に言うと、プラグインの中のコードを見た方が早いと思います。

レビューでツッコミが入るポイント

脆弱性を防ぐため、本当にこれだけでもいいから守っておくと良いでしょう。

なお、2作目のプラグイン開発時にプレフィックスの文字数と「共通のプレフィックス」の文字についてツッコミが入ったですが、関数名などの頭に「(プレフィックス)_」と入れているのですが、こちらはすべて統一する必要がありますので、ご留意ください。
(前回、何で指摘されなかったのか気になって確認してみたら、無意識に共通のものを使用していたことが発覚しました。当初はプレフィックスのつもりがなかったため、完全に偶然の産物です。変更しても問題がないことが分かったので、現在は、きちんと合わせて対応しています)

(1)とにかく、サニタイズ・エスケープ!

echoで書き出す変数はサニタイズが必須なので、事実上HTMLコードやJavaScriptコードは変数に代入できません(しても動作しません)ので、PHPを一旦区切って、HTMLコードやJavaScriptコードを書き、変数が必要なところだけechoでサニタイズして書き出します(サニタイズは「esc_attr」など色々種類があるので調べてみましょう)

HTMLを整形する前、変数に代入するときにもサニタイズしているけれど、HTMLに整形するとき、表示させるときはエスケープが必要です(サニタイズ関数とエスケープ関数は違うよ)ので、ご留意ください。

(2)プラグインやアップロードディレクトリなどの場所のパスを取得したいときなど、WordPressの専用の関数が用意されているものは、WordPressの専用の関数で取得する!

また、プラグインやアップロードディレクトリ(メディアライブラリ)の場所は専用の関数で取得するようにしましょう。URLだけじゃなくパスでも取得できるので、関数のマニュアルを参照してくださいね!

(3)プラグインをチェック用のプラグインでチェックするのを忘れないようにしよう!

あとは手順通りに作っておけば、よっぽどプラグインに問題がなければ大丈夫だと思います(そう信じたい……)

なお、前回の制作時では、テスト用のプラグイン「Plugin Check」を使った記憶がないので、今回の制作時では使用しました。このテスト用のプラグインで指摘されたものをできる限りなくした状態でレビューに出すようにしましょう。
(1作目のプラグインでは、どうしても生成されるURLに支障が生じてしまったため、ワーニングが1件だけ出ています……)

翻訳対象文章の記載方法

翻訳対象文章は次のように記述します。
当方がよく使うのは「esc_html__」です。

 __('(英語訳)', '(プラグインのドメイン)')

心が折れた人向け

動作は保証しませんし、今の記述ルールに合っているかの保証もしませんが、「Simple Code Minify」というすっごくシンプルなプラグインファイルを事業用サイトで公開しています。
ダウンロードしてご活用ください。

詳細は事業用サイトのプラグインページをご確認ください。

WordPressの自作プラグインの登録の仕方(手順)

自作プラグインができたら、WordPressプラグインディレクトリに登録するための準備をします。

(1)プラグイン・テーマを登録するなら、wordpress.orgの登録は必須なので、予め登録しておく。

日本語版があるの、有り難いよね。

(2)プラグインの申請をするために「readme.txt」を用意します。

=== Hide GTM code ===
Contributors: 作成者名(WordPress.orgのアカウント名になります。複数人のときはカンマ区切りで記述)
Tags: プラグインのカテゴリ的なタグ。検索のため。カンマ区切りで記述
Requires at least: 動作するWordPressの最低バージョン(当方は更新時点での最新Verを指定)。マイナーバージョンは不要。
Tested up to: 検証した最新のWordPressのバージョン。マイナーバージョンは不要。
Stable tag: プラグインのバージョン
License: ライセンスの種類
License URI: ライセンス情報の記載があるページ
Requires PHP: 必要なPHPのバージョン。基本的には、WordPress本体の推奨PHPバージョンに合わせています。
ここに「Donate link」という寄付用のリンクを書くこともできる。
(日本は寄付制度あんまり受け入れられていないから、自分は書いていない)

プラグインの検索したときの画面やプラグイン一覧で表示される説明文(英語訳で記述)


== Description ==


プラグインの説明文(英語訳で記述)


== Installation ==


プラグインのインストール方法(英語訳で記述)


== Frequently asked questions ==


よくある質問・FAQ(英語訳で記述)


== Screenshots ==

スクリーンショットの説明(英語訳で記述)


== Changelog ==


更新履歴(英語)
最初はリリースとかそんな感じになると思う。
「readme.txt」の文字数が長くなりすぎたから最新数件だけを残して以降は自前のページのリンクを設置した。
内部でHTML(リンク)が使えるので、
"<a href="(URLを記載)">Update History Page</a>".
って書いたら反映された。

== Upgrade notice ==


アップグレード履歴(英語)
リリース後のバージョンアップから記載。
「readme.txt」の文字数が長くなりすぎたから書かなくなった。


== Arbitrary section ==

他に説明があれば記載(英語)

できたら、検証用ツールで問題がないか調べます。

後に、前作のプラグインのデータを改めてチェックしたとき、「readme.txtが制限300文字を超えている」とワーニングが表示されたので見直した際に「『Upgrade notice』は何だっけ……?」と再度調べたときに見たページも共有しておきます。

(3)問題がなければ、ZIPファイルに圧縮して申請します。

プラグインのチェックは終わりましたか?
問題はありませんか?
問題がなければ、ZIPファイルに圧縮して申請してみましょう。

WordPressプラグインディレクトリトップページの下部に「プラグインを追加」「プラグインを作成」の項目があり、プラグインを掲載する方法のところにリンクがあるので、そこからでもたどり着けます。

レビューは英語なので、Google翻訳等をなんとかうまく使って対応してみてください。
個人的なコツは、日本語で文章を作成して英語に翻訳して更に日本語に翻訳する、複数回翻訳をしながら、どちらでも不自然にならないように文章を整えることです。(参考に見ていたページでも書いてましたね)

(4)SVNを使ってコミットする

WordPressのレビューチームから承認されるとシステムのアップロード(チェックイン)の仕方などが案内されますが、英語。
コマンドラインで対応したことはないし、「TortoiseSVN」というソフトは随分と昔に使ったことはあるけど、記憶が曖昧なので、改めて調べました。

【インストール方法】

  1. TortoiseSVNの公式サイトのダウンロードから最新版の32bitまたは64bitを選んでダウンロードする(Windowsの場合はシステムのバージョン情報、システムの種類で確認できる)
  2. インストールは画面に従って進めていく。パソコンの再起動が必要になる
  3. 再びダウンロードページから日本語化のためのファイルをダウンロード(setup)する
  4. インストールは画面に従って進めていく(最後はチェックを入れて「完了」する。忘れた場合は、TortoiseSVNの設定から変更できる)

【チェックアウト方法】

  1. アップロード・ダウンロードするためのフォルダをPC上につくる。あまり移動しないで分かりやすい場所に作るのがオススメ(Cドライブ直下にフォルダを作りました)
  2. 1で作ったフォルダに右クリックで「チェックアウト(取り出し操作)」を選ぶ。リポジトリのURL(保管場所のURL)には、メールに記載のある「プラグインのSVN URL」のURLを指定する。チェックアウト先のディレクトリは1のディレクトリへのパスと同じならOK

【チェックイン(コミット)方法】

  1. 「assets」フォルダにプラグインのヘッダ画像やスクリーンショット、アイコン画像を入れる(スクリーンショットは翻訳ができてから追加した)
  2. 「tags」フォルダにバージョン名のフォルダ(例:1.0)を作る
  3. 「trunk」フォルダの中にプラグインのファイルを入れる(中身は「languages」フォルダとプラグイン本体のPHPファイルとreadme.txtを入れました)
  4. チェックアウトしたフォルダの適当なところで右クリックして、「SVNコミット」をクリック
  5. コメントは適当に入れておく(念のため、英語にしています)
  6. ファイルのすべてにチェックが入っている状態になっていることを確認して「OK」をクリック
  7. WordPress.orgのユーザー名とパスワードを入れて「OK」をクリックでアップロードする

バナーは「772×250」「banner-772×250-rtl(右から左に読む言語用の画像)」「banner-1544×500」「banner-1544×500-rtl(右から左に読む言語用の画像)」の4種類用意(あ。右から左に読む言語用の画像って意識してないで作っ……被るからって文字入ってないや。よかったー!)

スクリーンショットは「screenshot-1」あとは2、3、4…と数字を変えたものを用意

アイコンは「icon-128×128」と「icon-256×256」を用意(SVGも使えるらしいけど用意しなかった)

いずれも、pngまたはjpgの拡張子であれば登録できます。

(5)「GlotPress」で翻訳

プラグイン作成者と翻訳編集者は別なので、プラグイン作成者が日本語訳を登録しようと思った場合、翻訳編集者になる必要があります。
または「Poedit」ツールを使って翻訳用ファイルを作るやり方もありますが、今は「GlotPress」という便利なものがあるから、こっちを使っていこうよと思うので、やり方は載せません。クリエイトアコードも最初は調べながら「Poedit」ツールを使うやり方で対応したので、調べたら情報が出てくると思うよ!

「GlotPress」で翻訳するやり方に変更するときに、「GlotPress」のやり方を調べても最新の情報が載っていなかったのってなんでだろうね……。
参考ページのリンクを貼ろうとしたけど、かえって分かりづらいかな……画面のスクリーンショットもあるから良いかなーとは思いつつ……。

参考ページを見ながらPTEリクエストするやり方で対応したのですが、投稿があるのかないのか分からずに何度も投稿しちゃったり、Slackでも「該当チャンネルどこー?」と探すなど、かなり手間取ってしまったため、最初から日本語のSlackで申請した方が早いし混乱なく対応できるかと思います。
後から続く皆、SlackメンバーになってSlackから申請しようね!
(もし、PTEリクエストで対応したい場合は、英語でも公式ヘルプページの方が画像付きで説明されているので分かりやすいよ)

翻訳するためには、Slackのメンバーになる必要があります。

リンクをクリックした後、左側はユーザー名(アットマークは不要です)を入力して送信するとリンクが届くので、ユーザー登録をしてください(英語版と日本語版の両方登録します)

【翻訳完了までの手順】

  1. 翻訳編集者になる必要があるので、翻訳編集者の申請をするため、WordPress.orgにログインしている状態で、自分のプラグインページの「翻訳を手伝いませんか。」をクリックする
  2. 日本語のSlackメンバーになる
  3. 申請用のチャンネルはデフォルトのチャンネルに含まれていないので、「+」をクリックして、チャンネル一覧から「requests」を選ぶ
  4. 大体、みんな同じような感じで申請しているので、申請する(みんなボランティアで対応してくれているので、急がないで待つ)
  5. 無事に申請が完了したら、WordPress.orgにログインしている状態で、自分のプラグインページの「翻訳を手伝いませんか。」をクリックする
  6. リストの中の「Japanese」の「0%」になっているところをクリックする。「Stable」と「Stable Readme」を編集しておくと良さそう(自分は「Development」「Development」で登録してました。多分どっちか片方入れればどっちも反映される)
  7. 「Details」をクリックして表示される画面の左側の入力欄に日本語を入れて「Save」で保存する
  8. しばらく待っていると反映されます(クリエイトアコードは、この後、日本語訳に反映された画面をスクリーンショット撮影して、スクリーンショットを登録しました。現在はその手間がしんどくなってしまったのでスクリーンショット自体の掲載をやめています)

なお、翻訳時の留意点ですが、
英語で説明文を書いて日本語に翻訳するとき、予め日本語に翻訳するときに不自然にならないようにするためにGoogle翻訳を使って文章を書いた後、日本語に翻訳する際、翻訳スタイルガイドに合わせた翻訳のために調整がおそらくは必要になるはずです。
翻訳の前には、翻訳スタイルガイドを一読しましょう。

見出し「翻訳編集者になる!」以降のコンテンツはPTEリクエストするやり方のため、閲覧をオススメしません。

(6)プラグインのバージョンアップ、更新のときの備忘録

プラグインの更新の間隔が空いたことで、更新と翻訳に手間取ってしまい、コミット回数が増えてしまったので、再発防止も兼ねて備忘録を作成しました。

  • プラグイン本体のファイルのバージョンを変更することを忘れない
  • Readmeテキストファイルのバージョンを変更することを忘れない
  • 動作確認バージョンの更新はReadmeテキストファイルのみ。WordPress本体のバージョンアップと同時期に動作確認バージョンを合わせて変更することを忘れない(動作確認していない場合は更新しない)
  • バージョンアップしたときは「Changelog」「Upgrade notice」の2箇所に追記することを忘れない(ただ、長くなってきたら、潔く自前のサイトにプラグインのページを作って誘導した方が良いと思う)

余談:クリエイトアコードの場合は自分で使っているプラグインなので、必然と動作確認はできる

(7)フォーラムの投稿通知の設定をする

ガイドライン違反で掲載停止されることを防ぐためにも、フォーラムへの投稿を確認するようにしましょう。
きちんと確認していても、なかなか難しいと思いますし、即座に掲載停止されるのではなく、フォーラムで投稿してくれると思うので、気づかずに対策しないで掲載停止されないように設定しておきましょう。

【設定方法】

  1. WordPress.orgにログインしている状態で、自身のプラグインページの「サポート」リンクをクリックする
  2. 移動した先に「Subscribe to this plugin」というボタンがあるのでクリックする
  3. 自身のプラグインページの下部にある開発者のリンクをクリックする
  4. 「Edit Nontification Settings」をクリックする
  5. ここで通知設定したいキーワードと、その通知名を設定して「Add new notification」をクリックする

【おまけ1】クリエイトアコードのプラグイン開発中に見ていた参考ページ

最初に。クリエイトアコードが開発したプラグインは、「ページ表示速度の低下を招くことなくGoogleタグマネージャーのコードを埋め込む」「ログイン中にGoogleタグマネージャーのコードを出力させない(自分を計測させない)」という2つの機能を持ったプラグインです。
現在は、Cookie規制の影響を考慮してGA4のみの登録もできるようにしています。

検証の結果、「wp_headの関数を呼び出す前、上の部分に出力するとページ表示速度が低下する」ことが分かっています。
そのため、wp_headで出力させたかった。そして、日々改修作業をしているため、ログイン中も計測すると自分以外のアクセス数が分からなくなるのも嫌で除外したかったので、どちらも取り入れたプラグインが欲しかったのです。

独自の検証中、少なくとも「wp_head」の関数を呼び出すときの位置、デフォルト「10」の位置では遅くなることはありませんでした。
逆に、出力位置の都合で早く実行している考えられる場合は、ページ表示速度が遅くなってしまったのを確認しました。
既にある程度最適化かつ元々が遅くなかったサイトだからこそ、顕著に結果として表れたのだろうか?と今では考えています。

IP等で自分を除外して計測しないようにする設定やオプトアウトアドオンもありますが、IPは変動しますし、WordPressログインで判断するならIP関係なく判別できると考えまして……。とはいえ、逆にログインする手間が発生するのが若干面倒ではありますが……。

【おまけ2】「タグマネージャーのコードは埋め込んでいる。アナリティクスは問題なく計測できているのに、サーチコンソールの所有者の確認ができない」ときに見ていた参考ページ

サーチコンコールで「タグマネージャーのコードは埋め込んでいるのに認識されない」問題が発生。なお、アナリティクスは問題がない。サーチコンコールだけ。

メッセージは「サイトの Google タグ マネージャー スニペットが、ページ上の正しい場所に配置されていません。」と表示されます。
本当なら、勝手に出力するSVGタグよりも前に出力しないといけないのだが、SVGタグよりも下に出ていたので駄目だった模様。でも、最初は問題なく所有権の確認ができたはずなんだけど、いつの間にか切れており……。この件、どうして「最初は問題なかったのか」は未だに分かっていません。
「そもそも、何でSVGタグがあるのか?」については参考ページに記載の通り、WordPressの機能「デュオトーン(duotone)」を実現するために追加されたものです。

デュオトーンとは2色を混合させて表現するデザインのことで、Web上ではCSSのfilterプロパティとSVGフィルターを組み合わせて表現できます。

https://webtech.fukushimaku.jp/kiji/delete-wordpress-svg-tag.html

そのときは、body開始直後にどうやって出すのか分からなかったので調べたところ、「wp_body_open」の存在を知ったので、設定したことで無事に解決に至りました。

「head内の出力は分かるけど、body開始直後にどうやって出力するの?」と思って、フックを探していたら見つけました。
後述の再発に繋がりますが、ここで優先順位「0」と記載がありましたね……。当時は「優先順位は必要なときにつけるもの」として、スルーしちゃってました……。

その後、再発したことが最近(2023年6月29日)になって判明。
今度は優先順位の問題で、最優先でSVGタグが出力されるようになっていた模様。
何が原因で最優先で出力されるようになったのかは未だに分かっておらず。

原因が判明するまでに時間がかかったことといい、修正できたと思ったら優先順位の都合で修正できていなかったことといい、何度、SVGタグを消してやろうかと思ったけど、必要な人には必要なので消すわけにもいかず……思わぬところで苦戦してしまいました。

改めて優先順位について調べたときに見たページです。

これで無事に解決…に至ったのですが、他サイトでは別のテーマを使っていたことで、解決していないことが判明。
同じやり方で何故解決していないのかが分からなかったので、テーマのテンプレートファイルのbodyタグ付近のコードを確認してみることに。

<body <?php body_class(); ?>>
<!-- ここに何らかのコードがある -->
<?php
if ( function_exists( 'wp_body_open' ) ) {
	wp_body_open();
} else {
	do_action( 'wp_body_open' );
}
?>

え……。ちょっと待って。
フックなしに直でこの位置にコードが入っているの……?

このように直で埋め込まれていて、フック等もない場合は、子テーマの対応が不可避になります。
または、テーマ制作者側に「位置をwp_body_openの下にしてください」とお願いするかです。
「wp_body_open」の用途を考えるなら、bodyタグの直下に記述した方が良いと思いますので。
とはいえ、必要な機能で、意図して設置しているものを「位置変更してください」と伝えて変更できるとは限らないので、子テーマ側で対応するしかないのですが、あまり推奨したくない。なにより初心者に優しくないですし。
そして、所有者の確認をアナリティクスで対応しようにも、「サイト内で Google タグ マネージャー スニペットが検出されました。Google アナリティクス スニペットはそこで管理されている可能性があります。サイトの所有権は、ホームページの セクションに配置された Google アナリティクス非同期コードで確認できます。」というようなエラーメッセージが表示されてしまうのでできません。

あれこれ考えた結果、「サーチコンコールの設置はコードじゃ無理」と潔く諦めて、HTMLタグまたはHTMLファイルを設置した上で所有権を確認するのが良さそうに思えたので、HTMLタグを埋め込むための機能を改めてプラグインに追加しました。

「Hide GTM code」は、さすがに「wp_head()」と「wp_body_open()」がないテーマには使えないですので、何卒ご容赦願います。

どこに出力したら良いのか分からないし、ページ表示速度の問題も出てくる可能性もあるので、ここまではフォロー無理です……。
テーマ制作者に相談いただくか、別なテーマを使うか、リニューアルするかでご対応ください。
正直、当方制作のプラグインを使わずとも、テーマの機能や別のプラグインを使って対応する方が良いんじゃないかな、とも思います。

自分以外にも使ってくれると思って、これからもしっかりとメンテナンスしていきたい

自分で使うだけなら、ある程度妥協していたかもしれませんが、WordPressプラグインディレクトリに登録した、自分以外も使ってくれているかもしれないプラグイン。だからこそ、これからもしっかりとメンテナンスしていきたいと思っています。

自作プラグインで、初回データ登録時にコードの表示が消えてしまう(コードが表示されない)ので表示されるようにする修正を行ったのですが、今後、特に新規プラグインの動作テストするときは新規サイトにもプラグインを入れてテストすることを徹底したい所存。

【おまけ3】サニタイズ等、エラーやワーニングの対策で困ったときに見ていた参考ページ

情報が古いものもあるかもしれないけど、こういうのから関数ページを見に行ったり、最初のヒントとしては大活躍でして……。
特にWordPressでフォームを作成するならNonceを入れるというのは知らなかった(基本的にプラグイン任せだったし、当時は数年前で情報があったと思われても自分の方で検知できていなかった)ので、本当に助かりました……。

英語を頑張って日本語訳に直して読むのとか、英語の情報を探すのとか、英語の成績が「2」を取ったことのあるぼくからすると、結構な無理ゲー……。

二作目プラグイン「CSVDataImport CustomPost」ですが、CSVをアップロードする必要があったのですが、何をどうしてもサニタイズのところで困ってしまったので、安全に対応するためには…と考えた結果、メディアライブラリにCSVファイルをアップロードする方法以外の方法が当方には取れませんでした……。

ただ、そのままじゃ使えなくて、ドメイン部分以降のパスの情報だけが欲しかったので、以下、参考にしました。

二作目プラグイン「CSVDataImport CustomPost」のときに、YouTubeとGoogle Mapをどうしても実装したかったんだけど、YouTubeはWordPressの標準の関数でどうにかなっても、Google Mapはどうにもできず……。最終的にURLだけ入力させて、自前で埋め込むという形で対応しました……。
そのときに参考にしたページです。

【おまけ4】二作目プラグイン「CSVDataImport CustomPost」のときに参考にしたページ

CSVファイルから、カスタム投稿(カスタム投稿自体は別のプラグイン等を利用して作成する必要があり)とカスタムフィールドを生成することができるプラグイン「CSVDataImport CustomPost」を制作しました。

なお、当方が作成したプラグインは、当方が使いたい機能を追加しているので、表示をサポートするショートコードも提供しています。よろしければ、ご活用ください。

フルサイト編集対応のブロックテーマ(特に公式の開発チームが制作したテーマ)でショートコードを使ってエディターでデザインしようとしても使えない可能性があります。元々、スニペットプラグイン等を使って自前で表示ページ(部分)を作ることを前提としたプラグインなので、潔く自前で表示ページ(部分)を作成してください。

これらの参考ページがなければ、作ることはできなかったか、作ったとしても、公開はできなかったと思います。本当に有難い限りです……!

【おまけ5】二作目プラグイン「CSVDataImport CustomPost」を使って「サイト内検索」を実装したときに参考にしたページ

サイト内検索のプラグインが良いものがなかったため、最終的には自作しました。
正直に言うと、WordPressの検索機能はあまり好きじゃないです……。

今後もサイト内検索で困ることがあるかもしれないと思ったのでまとめておきます。

記載の関数「mysql_real_escape_string」は使用できないため、「esc_sql」を使用する必要がある。

初歩的なミスしやすい箇所:DBの接頭辞を変更したなら、コード内も変更する必要がある!

データベースの接頭辞が変わっても動作するようにするために参考にした。

カスタムフィールドのセレクトボックスとカスタムフィールドの検索が併用できなかったため、併用するために参考にした。

コードは最終的に下記のようになりました。

if (!empty($wp_query->query['s'])) {
		$search .= " AND " . $wpdb->posts . ".post_title LIKE '%" . esc_sql($wp_query->query['s']) . "%'";
		foreach (['clinic-list_cspost_field_3'] as $_key) {
			if (!empty($_REQUEST[$_key])) {
				$search .= " OR (" . $wpdb->postmeta . ".meta_key = '$_key'";
				$search .= " AND " . $wpdb->postmeta . ".meta_value LIKE '%" . esc_sql($wp_query->query['s']) . "%')";
			}
		}
}

サイト運営者

クリエイトアコード

ホームページ(改善・改修)・SEO対策・Web集客のお手伝い屋さん【Web技術サポーター・Webコンテンツサポーター、Webサイト制作者】

ソフトウェア&ゲーム開発会社でプランナーとして従事しながら、ディレクション・マネージメント、資料作成の知識を実践形式で学ぶ。その後はリサイクルショップのWebサイト担当者として従事しつつ、SEOやWordPressの実践形式での研究を深めた。転職をした会社や兼業(副業)としての活動でも今までに学んだ知識と技術を活用しながらも更なる向上に努めていたが、様々な人のお悩み解決をしていきたいという思いが強くなったため、転職から二年後に独立。2022年5月10日に開業して個人事業主になった。
現在は、今までに得た知識や技術(SEO・WordPress・Webマーケティング・Web集客)を活かしながら「人と人を調和し、創造を支援する」「自分で色々動きたいので技術面をサポートしてほしい人や自分も考えたいが技術面については知見がないのでフォローしてもらいたい人を応援する」ことを目的に「訪問者に届けるコンテンツを作る」お手伝いをするための活動をしている。

事業の他、ソフトウェア&ゲーム開発会社時代に無理をした働き方をしたために自律神経のバランスが乱れやすいことや精神的にもダメージを負ったことから「抑うつ状態」と診断されて数年かけて寛解した経験から、同じような人が苦しまずに働くことができるように自身を実験台に「スキルを活用した生活に困らないかつ無理をしない働き方」の確立を目指している。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次