How to pass a php variable to js within a template?

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.

Topic wp-query Wordpress

Category Web


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

<script>
   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;?>
</script>

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.


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(); ?>
                    <?php
                    $properties = array(
                        'title' => get_the_title(),
                        'link' => get_the_permalink()
                    );
                    $my_posts[] = $properties; ?>
            <?php endwhile; wp_reset_query(); ?>

    <script>
                var posts = <?php echo json_encode($my_posts); ?>; 
               console.log(posts);
</script>

Of course this might not be the best idea securitywise.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.