Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've got a working piece of javascript that contains an object literal. But I need to localize it, and I'm ytrying to figure out how to rewrite it so that I can get wp_localize_script() to accet it, and output the correct format.

The non-localized (non dynamic) version looks like this:

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

Now, to have those values generated by php (based on some wp_settings) I want to use wp_localize_script, so I can take it from there:

var layoyt_config = my_localized_data.layoyt_config;

And to get that data in to that object property I 'thought' I could do this, but obviously not:

$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);

As this will cause PHP parse error I've tried to rewrite the json to array syntax, as wp_localize_script will convert that back to object notation, but this also does not work for me:

$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);

And while this runs smoothly trhough the php parser, I do not get the expected output in my page source, as my_localized_data.layout_config becomes a String "Array", here is the output:

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

So.. How can I do this (or do I just have to accept that I must 'flatten' my object into discrete vars like:

lc_header = '1';
ls_ls_sb1 = '1';
etc...
share|improve this question
add comment

2 Answers 2

up vote 11 down vote accepted

Indeed, wp_localize_script() is simple, it just adds quotes around the values and escapes the content, expecting all of them to be strings.

However, there is the l10n_print_after key of the array, which will be printed without any interference at all. It can be used to execute arbitrary code after the strings are passed. You can use it to pass your extra data.

$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);

You will end up with code like this:

var my_localized_data = {}; // What is left of your array
my_localized_data = {'layout_config': {'ls': {'sb1': 1}}}; // From l10n_print_after
share|improve this answer
    
thanks that was very useful! –  mikkelbreum Feb 9 '11 at 9:04
    
Very useful, although I think you meant a semi-colon after json_encode, not a comma, am I correct? –  kovshenin Apr 29 '11 at 17:07
1  
@kovshenin: Good catch! I corrected it, but if you would have proposed it as an edit you would have gotten +2 rep for it. –  Jan Fabry Apr 30 '11 at 11:31
    
Don't mean to hijack this question, but was given this question/answer as a reference to look at for wordpress.stackexchange.com/questions/53842 (in-case anyone has any pointers here). Thanks! –  Zach May 31 '12 at 15:51
add comment

Disclaimer - I am out of my depth on JS security stuff here.

First, to match your desired output you are off by nesting level. Object name goes as parameter in localize call (instead of array key):

$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);

But ls and rs are still broken because WP_Scripts->print_scripts_l10n() method doesn't handle the case when variable is array.

Best I could come up with to fix that is following filter (as above - not sure how safe would be to use it in production, but to give general idea):

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;
}
share|improve this answer
    
I understand that the main object name goes in as the 2dn parameter in the call to wp_localize_script,but, I already do that , my localized object name is supposed to be 'my_localized_data', that object will have a variety of properties most of them having plain string values, but I need one of these properties to be a multi-dimensional object. –  mikkelbreum Feb 6 '11 at 15:08
    
This seems to be out of the scope of wp_localize_script without modification. It can't handle multidimensional arrays. I have now come up with a different method, where I store my localazed multi-dimensional obejct as a html data-* value. This works fine, but leave additional questions: wordpress.stackexchange.com/questions/8684 –  mikkelbreum Feb 6 '11 at 15:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.