WordPress Plugin 「Theme My Login」でCannot read property ‘meter’ of undefinedエラー

WordPress, プラグイン, ブログ, 制作

nd  2020年4月13日

WordPressプラグインで簡単にユーザー登録画面などをフロント側に追加する「Theme My Login (Version 7.0.15:2020年4月11日時点最新)」で、ショートコードを利用し「登録画面」を呼び出した場合、パスワード入力で以下のエラーが発生した場合の解決方法です。

Cannot read property 'meter' of undefined

解決方法

方法は簡単です。必要なJavaScriptを読み込ませるだけ。
手順は以下の2ステップ

1.プラグインフォルダ直下に「theme-my-login-custom.php」を作成

これは、「Theme My Login」の公式で推奨されている「Theme My Login」の拡張方法です。
(基本を押えればfunctions.phpへ記述しても動作はします。)
詳細はこちらのリンクを確認してください。
https://docs.thememylogin.com/article/63-using-theme-my-login-custom-php

2.作成したtheme-my-login-custom.phpに以下のコードを貼り付け

function customize_tml_from( $form ) {
    if ( 'register' == $form ) {
        wp_enqueue_script('password-strength-meter');
    }
}
add_action( 'tml_registered_form', 'customize_tml_from' );

以上。

諸々解説

そもそもなぜこのエラーが発生しているのかというと、パスワード強度を判定するJSにWordPress本体のスクリプトを利用しており、管理画面で設定した登録画面用Slugを持つページでは自動的にそのスクリプトが読み込まれますが、ショートコードを利用して、別ページに登録フォームを表示させると、そのスクリプトが読み込まれないため、必要なオブジェクトが見つけられずにエラーとなります。

パスワード強度の判定に必要なスクリプトは「/wp-admin/js/password-strength-meter.min.js」です。

最初、ネット上で情報を探し、英語版フォーラムにどストライクの質問を見つて、プラグイン作者の回答も付いていたので期待したけど、何も解決されてませんでした。
該当スレッドはこちら
https://wordpress.org/support/topic/password-strength-meter-error/

仕方ないので、自分でデバッグ。
まず、エラー画面ではtheme-my-login.min.jsというスクリプトが「Cannot read property ‘meter’ of undefined」 というエラーをコンソールに吐いていますので、「theme-my-login.min.js」を確認。

中身はこんな感じです。

〜省略〜
function(e) {
    function s() {
        var s = e("#pass1").val()
          , a = e("#pass-strength-result");
        if (a.removeClass("short bad good strong"),
        s)
            switch (wp.passwordStrength.meter(s, wp.passwordStrength.userInputBlacklist(), s)) {
            case -1:
                a.addClass("bad").html(pwsL10n.unknown);
                break;
            case 2:
〜省略〜

エラーメッセージにも表示されている’meter’というプロパティが見つかります。
‘meter’自体は「wp」オブジェクトに含まれることが分かるので、コンソール画面で次のコマンドを実行し、wpオブジェクトの内容を確認します。

console.log(wp)

実行結果はこちら

先ほどの「theme-my-login.min.js」内ではwpオブジェクトの中に「passwordStrength」というオブジェクトがあり、そのプロパティとして’meter’を参照していましたが、そもそも「passwordStrength」オブジェクトがありません。

現時点で「passwordStrength」が何者か分かりませんので、今度は正常な画面(プラグインの設定画面で登録したユーザー登録画面のslugを持つページ)の方で先ほどと同じ「console.log(wp)」コマンドを実行します。
実行結果がこちら

今度は「passwordStrength」オブジェクトがあり、’meter’プロパティもあります。さらに「FunctionLocation」という情報を見ると、このオブジェクトが「/wp-admin/js/password-strength-meter.min.js」のものだという事も分かります。

ここまで来たら、あとは推測できます。
『ああ、必要なスクリプトが読み込まれていないだけだ』と言う事で、Theme My Loginに用意されているいくつかのフックの中で、今回は「tml_registered_form」フックを利用し、必要なスクリプトを読み込ませました。

もしプラグイン側にフックなどが準備されていない場合、最悪プラグインコアファイルを修正する必要がありますが、それをやっちゃうと、アップデートする度に同じ修正が必要なので、本来は避けるべき方法です。
(今回の様なスクリプト不足なら、プラグインとは関係なくテーマのfunctions.phpで各ページを条件判定しつつ必要なページにスクリプト読み込ませても大丈夫。)

ちなみに「Theme My Login」はGithubにコードを公開していたので、確認してみると7.0.11で以下のコメントがありました。

  • Fix password strength meter script loading on every request

恐らくこの修正で逆に必要なスクリプトが読み込まれなくなったのでしょう。
今後の為にもIssueとして投げようかな。


今回は「Theme My Login」のユーザー登録画面をショートコード呼び出した際のJSエラーの修正方法でした。

WordPressに素晴らしいプラグイン「Theme My Login」を提供してくれた開発者Jeff Farthingに感謝!!