ローカライズ済みのスクリプトをインターセプトする方法


10

プラグインがスクリプトを使用している場合(有名な例:jQuery UI Datepicker)、スクリプトが出力をレンダリングする方法に不満がある場合は、2つの可能性があります。

1.スクリプトの登録を解除する>独自のバージョンを追加する

だから、最初に、あなたは(優先順位やフックを見つけ、その後、ハンドルをチェックする必要があると思いwp_enqueue_scriptslogin_enqueue_scripts...あなたはドリルを知っているなど、)。

2. jQueryプラグインパラメータを変更する

通常-プラグインががらくたでない場合-それを使用して、PHPからJSにパラメーターをプッシュします。

wp_localize_script( $handle, $object_name, array( 
    // data
) );

これはJSスクリプトにデータを追加するスマートな方法です、デフォルトではフィルターできません。どちらWP_ScriptsWP_Dependencies申し出任意のフィルタユーザーが後で利用することができます

質問: PHPからJavaScriptに移動された引数/パラメーターをどのようにフィルタリングできwp_localize_scriptますか?

回答:


9

wp_localize_script()localize()グローバル変数のメソッドを呼び出します$wp_scripts。この変数を、次のクラスのインスタンスに設定できますWP_Scripts

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'wp_loaded', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

テーマカスタマイザはそれを使用せず、の個別のインスタンスを作成しますWP_Scripts(を参照wp-admin/customize.php)。それを置き換えることも可能かもしれません:

add_action( 'customize_controls_init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
    $GLOBALS['wp_scripts']->registered = $GLOBALS['registered'];
});

これはテストされておらず、単なるアイデアです。


$ l10nを指定していただけませんか?ハンドルとオブジェクトを渡すことは理解できますが、$ l10nは理解できません。ありがとう。
Eric Leroy、

1
@EricLeroyそれの第三のパラメータであるwp_localize_script()単一または多次元アレイ
fuxia

この実装は非常に役に立ちましたが、私の管理スクリプトを大いに台無しにしたことを警告したいと思います。上記の解決策のためにJavaScriptが印刷されなかったため、ACFが機能しなくなりました。まだ修正方法はありませんが、今探しています。
Ogier Schelvis、2017年

4

@toscho素晴らしい実装。テスト済みで真。これは少し変更されたバージョンで、$ handleと$ object_nameも渡されるため、必要な場合にのみフィルタリングできます。

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

add_filter('script_l10n', 'se108362_example_filter', 10 , 3);

// Example
function se108362_example_filter($l10n, $handle, $object_name ) {
    if('js-handle' == $handle && 'jsVariable' == $object_name) {
       return 'Something Else';
    }
    return $l10n;
}

1

受け入れられた答えは素晴らしいです!しかし、JavaScriptエラーのために、高度なカスタムフィールドがバックエンドで機能しなくなるという問題に遭遇しました。数時間掘り下げた後、ACFプラグインによって登録されたjavascriptファイルがFilterable_Scriptsオブジェクトにないという結論に達しました。なぜこれが行われたのかは正確にはわかりませんが、同じ問題が発生した場合に適切な解決策を見つけました。

$GLOBALS['wp_scripts']幸いなことに、まだ適切なスクリプトを含んでいました。だから私は次のことをしましたadd_action

add_action( 'wp_loaded', function() {
    $fscripts = new Filterable_Scripts();

    $missing_scripts = array_diff_key( $GLOBALS['wp_scripts']->registered, $fscripts->registered);
    foreach($missing_scripts as $mscript){
        $fscripts->registered[$mscript->handle] = $mscript;
    }

    $GLOBALS['wp_scripts'] = $fscripts;
});

オブジェクトにはすべての登録済みスクリプトの配列が含まれ、ハンドルも配列キーであるため、array_diff_keyを使用して、拡張オブジェクトから欠落しているスクリプトを特定し、それらを再度追加できます。私はこれをしました

$fscripts->registered = $GLOBALS['wp_scripts']->registered;

拡張オブジェクトによって行われた変更を上書きしたくなかったためです。


1
これを行う別の方法がありました。つまり、2つのacfスクリプトタグ$acf_field_group = $GLOBALS['wp_scripts']->registered['acf-field-group'];(もacf-input)を追加してから、それらを拡張WP_Scriptsタグのインスタンスに再度追加しました。それから、$GLOBALS['wp_scripts']->registered['acf-field-group'] = $acf_field_groupACFがAdmin内のスクリプトのみを使用していることに気付きました。l10n前面のみなので、アクションとフィルターをラップして!is_adminテストします。
MikeiLL 2018年

良い点は、パフォーマンスの面でソリューションがうまく機能することです。また、このコードの個人用バージョンにis_adminチェックを追加しています。私のアプローチについて今でも気に入っているのは、スクリプトのIDが将来変更される場合、またはACFプラグイン(または他のプラグイン)の新しいバージョンで新しいスクリプトが欠落している場合、変更する必要がないことです。コード。
Ogier Schelvis、2018年

はい、それは私にとっても理にかなっています。フロントエンドでのみアクションを実行している場合は、どれが必要かわかりません。
MikeiLL 2018年

うーん。最初の問題が本当に何であったかを忘れてしまうほどの完璧な解決策を見つけるのに、時々私は夢中になっていると思います。ただし、管理者での必要性が変わる可能性がある場合は、すでに計算を行っています;-)
Ogier Schelvis

ここでも同じですが、それはすべて学習に関することではありませんか?
MikeiLL 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.