I’m trying to pass a variable from the template to js, but with no luck.

I’ve tried using wp_localize_script, and it seems to be working fine when attached to wp_enqueue_scripts action, but it doesn’t work when called from within template. Do my only resort is to use HTML & data- for handling this?

It would be that great though, since I’m passing the whole wp_query there.

My function is basically a wrapper on a custom WP_Query that allows load more functionality on multiple loops.

function load_more_scripts() {
     wp_register_script( 'loadmore', get_stylesheet_directory_uri() . '/assets/js/myloadmore.js', array( 'jquery' ) );
     wp_enqueue_script( 'my_loadmore' );
 add_action( 'wp_enqueue_scripts', 'load_more_scripts' );

 // this function is later called in the template
function get_list($query_args) {
    if ( is_array( $query_args ) ) {
        $the_query = new WP_Query( $query_args ); 

    //...some more code

    $instance = wp_generate_uuid4();
    wp_localize_script( 'loadmore', 'loadmore_params_' . $instance , array(
            'ajaxurl'      => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
            'posts'        => json_encode( $the_query->query_vars ), // everything about your loop is here
            'current_page' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
            'max_page'     => $the_query->max_num_pages
        ) );

Update It seems the issue can be in localizing multiple scripts. If you register the script to load in the footer, version without adding an $instance to load_more_params seems to work.

  • You can only call wp_localize_script once for a script, so instead of doing it inside get_list, collect all query instances in a single object and call it just once before the script is output in the footer.
    – Milo
    Jan 8, 2018 at 16:16
  • @Milo do you mean you can only call it once from the front-end? Because it seems to work with wp_enqeue_scripts as far as object name is unique.
    – Runnick
    Jan 8, 2018 at 17:13
  • I mean you can only localize a script handle once, calling it multiple times on the same handle will overwrite the previous.
    – Milo
    Jan 8, 2018 at 17:23
  • 1
    This article states that wp localize scripts must be called before wp_head. Maybe that was your issue.
    – D. Dan
    Jan 11, 2018 at 8:44

2 Answers 2


If you would want to pass the whole wp query you could pack it up in arrays, then json encode it and just write it out in a tag.

<?php my_posts = array();
              while ( have_posts() ) : the_post(); ?>
                    $properties = array(
                        'title' => get_the_title(),
                        'link' => get_the_permalink()
                    $my_posts[] = $properties; ?>
            <?php endwhile; wp_reset_query(); ?>

                var posts = <?php echo json_encode($my_posts); ?>; 

Of course this might not be the best idea securitywise.

  • Thanks, I was thinking about it but wondered if there is a cleaner way though.
    – Runnick
    Jan 8, 2018 at 17:11

The purpose of wp_localize_script is to print javascript variable where the spesific javascript file is loaded, if you want to print in php template and because its specific area, I think you not need to use wp_localize_script, just print it, like

   var posts = <?php echo json_encode($my_posts); ?>; 
   var current_page = <?php echo get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;?>;
var max_page = <?php echo $the_query->max_num_pages;?>

not need to print ajaxurl, because in updated wordpress it automatically printed.

and for sure, you call dependent script in specific template, you can use

function specific_enqueue() {
  if ( is_page( 'your template' ) ) {
    wp_enqueue_script( 'my_loadmore' );
add_action( 'wp_enqueue_scripts', 'specific_enqueue' );

No security problem I think, because wp_localize_script like echo, the function printed the var in html, and everybody can look at inspect.

  • you can use is_page_template('example-template.php'); if is_page( 'your template' ) not working
    – Manyang
    Mar 4, 2020 at 5:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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