web-dev-qa-db-ja.com

オブジェクト/ JSONをwp_localize_scriptに渡す

オブジェクトリテラルを含む実用的なjavascriptを持っています。しかし、それをローカライズする必要があり、wp_localize_script()で取得して正しいフォーマットを出力できるように書き直す方法を探しています。

ローカライズされていない(動的ではない)バージョンは次のようになります。

var layoyt_config = {
    'header'        : 1 
,   'footer'        : 1
,   'ls'            : {'sb1':1}
,   'rs'            : {'sb1':1,'sb2':1}
,   'align'         : 'center'
};  

さて、(いくつかのwp_settingsに基づいて)phpによって生成されたそれらの値を持つために、私はwp_localize_scriptを使いたいので、そこからそれを取ることができます:

var layoyt_config = my_localized_data.layoyt_config;

そして、そのデータをそのオブジェクトプロパティに取り込むために、私はこれを行うことができると考えましたが、明らかにそうではありません:

$data = array(
    'layout_config' => {
        'header' : 1
    ,   'footer' : 1
    ,   'ls' : {'sb1': 1}
    ,    'rs' : {'sb1': 1,'sb2': 1}
    ,    'align' : 'center'
    }
);
wp_localize_script('my-script-handle', 'my_localized_data', $data);

Wp_localize_scriptがそれをオブジェクト表記に変換するので、これはPHP解析エラーを引き起こすのでjsonを配列構文に書き換えようとしましたが、これも私にはうまくいきません:

$data = array(
    'layout_config' => array(
        'header' => 1
    ,   'footer' => 1
    ,   'ls' => array('sb1'=>1)
    ,    'rs' => array('sb1'=>1,'sb2'=>1)
    ,    'align' => 'center'
    )
);
wp_localize_script('my-script-handle', 'my_localized_data', $data);

そしてこれはphpパーサーを通してスムーズに実行されますが、my_localized_data.layout_configが文字列 "Array"になるので、私は私のページソースに期待された出力を得ません、これが出力です:

<script type='text/javascript'>
    /* <![CDATA[ */
    var wpkit_localized_data = {
    layout_config: "Array"
    };
    /* ]]> */
</script>

だから..どうすればこれを行うことができますか(または私は私のオブジェクトを以下のような離散的なvarに '平坦化'しなければならないことを受け入れなければなりません:

lc_header = '1';
ls_ls_sb1 = '1';
etc...
14
mikkelbreum

実際、 wp_localize_script()は単純です 、値を引用符で囲んで内容をエスケープするだけで、すべてが文字列であることを期待します。

ただし、配列のl10n_print_afterキーがあり、これはまったく干渉することなく印刷されます。文字列が渡された後に任意のコードを実行するために使用することができます。追加のデータを渡すためにそれを使うことができます。

$data = array(
    'layout_config' => {
      'ls' : {'sb1': 1}
    }
);
$reshuffled_data = array(
    'l10n_print_after' => 'my_localized_data = ' . json_encode( $data ) . ';'
);
wp_localize_script('my-script-handle', 'my_localized_data', $reshuffled_data);

あなたはこのようなコードで終わるでしょう:

var my_localized_data = {}; // What is left of your array
my_localized_data = {'layout_config': {'ls': {'sb1': 1}}}; // From l10n_print_after
14
Jan Fabry

免責事項 - 私はここのJSセキュリティのことについての私の深さからは抜けています。

まず、あなたの望みの出力に合わせるために、あなたはネストレベルによってオフになっています。オブジェクト名は(配列キーの代わりに)ローカライズ呼び出しでパラメータとして渡されます。

$data = array(
        'header' => 1
    ,   'footer' => 1
    ,   'ls' => array('sb1'=>1)
    ,    'rs' => array('sb1'=>1,'sb2'=>1)
    ,    'align' => 'center'
);
wp_localize_script('my-script-handle', 'layout_config', $data);

しかし、lsrsはまだ壊れています。変数が配列の場合、WP_Scripts->print_scripts_l10n()メソッドは大文字と小文字を区別しないからです。

私が思いつくことができる最良の方法は次のフィルタを修正することです(上記のように - 実運用でそれを使用することがどれほど安全かはわからないが、一般的な考えを与えるために)

add_filter('js_escape','js_escape_nested', 10, 2);

function js_escape_nested($safe_text, $text) {

     if(is_array($text) )
         return str_replace( '"', "'", json_encode ($text) );

     return $safe_text;
}
1
Rarst