Calling wp_localize_script after the page was loaded
-
[Moderator note: Please use the CODE button to delimit code when pasting… you guessed it… code.]
[Josef: You should have waited: I was correcting the format. I will leave the version I corrected. See above]
[Josef: Sorry for that, I just saw how to edit topics]
- This topic was modified 6 years, 4 months ago by Steven Stern (sterndata).
- This topic was modified 6 years, 4 months ago by jmeile.
- This topic was modified 6 years, 4 months ago by jmeile.
-
Sorry, I didn’t see how to edit my post in order to fix the code format (Now I now :-(), so, here goes again with the proper formatting:
I’m using wp_localize_script to inject php variables into my javascript. Currently, I created a shortcode to embed jquery ui accordions into WordPress. In order to make this understandable, I will only put the relevant parts of my code.
The Shortcode looks like:
//First accordion [jm-accordion-group active=2 height_style=”content”] [jm-accordion title=”Test1″] Content 1 [/jm-accordion] [jm-accordion title=”Test2″] Content 2 [/jm-accordion] [/jm-accordion-group] //Second accordion with default settings // for active and height_style [jm-accordion-group] [jm-accordion title=”Test3″] Content 4 [/jm-accordion] [jm-accordion title=”Test4″] Content 4 [/jm-accordion] [/jm-accordion-group]
The idea is that I can put as many “jm-accordion-group” in my post as I want. This is so far working. This is how I’m doing it: first I enqueue the scripts:
function allow_jquery_ui_accordion() { if ( !is_admin() ) { wp_enqueue_script(‘jquery-ui-accordion’); wp_register_script(‘jm-accordion_script’, get_stylesheet_directory_uri() . ‘/js/accordion.js’); } } add_action(‘wp_enqueue_scripts’, ‘allow_jquery_ui_accordion’); wp_enqueue_style(‘jquery-custom-style’, get_stylesheet_directory_uri(). ’/css/jquery-ui-1.12.1/jquery-ui.css’, array(), ‘1’, ‘screen’ );
Here I’m basically embedding one script: ‘jquery-ui-accordion’ (From the WordPress Core). The second one is only registered since I have to send some global variable values before enqueuing it. Then I also add the style sheets from jquery-ui, which I got from their official website.
Here my script: accordion.js, which is stored on my theme as a text file:
jQuery(document).ready(function($) { accordion_vars.forEach(function(accordion_object) { $( ‘#’ + accordion_object.id ).accordion({ active: accordion_object.active, heightStyle: accordion_object.height_style, }); }); })
Please note the variable: accordion_object. It is an array with the attributes of each accordion. This will be injected in javascript from php by using wp_localize_script. This will be done at a later time.
Then I define the Shortcodes and its functions
add_shortcode(‘jm-accordion-group’, ‘jm_accordion_group’); add_shortcode(‘jm-accordion’, ‘jm_accordion’);
First the main div that encapsulates all the accordion sections:
function jm_accordion_group( $atts, $content = null ) { extract( shortcode_atts(array( ‘class’ => ”, ‘active’ => 1, ‘height_style’ => ‘content’, ), $atts) ); $accordions_count = isset($GLOBALS[‘accordions_count’]) ? $GLOBALS[‘accordions_count’] + 1 : 1; $GLOBALS[‘accordions_count’] = $accordions_count; $id = ‘jm-accordion-‘ . $GLOBALS[‘accordions_count’]; init_accordion($id, $active, $height_style); $output = ‘<div id=”‘ . $id . ‘”‘; if (!empty($class)) { $output .= ‘class=”‘ . $class . ‘”‘; } $output .= ‘>’ . do_shortcode(shortcode_unautop($content)). ‘</div>’; return $output; }
Then each accordion section:
function jm_accordion( $atts, $content = null ) { extract( shortcode_atts(array( ‘id’ => ”, ‘title’ => ‘— Untitled —‘, ‘tag’ => ‘h5’, ‘class’ => ” ), $atts) ); $output = “<” . $tag . “>” . $title . “</” . $tag . “><div”; if ( !empty($id) ) { $output .= ‘ id=”‘ . $id . ‘”‘; } if ( !empty($class) ) { $output .= ‘ class=”‘ . $class . ‘”‘; } $output .= ‘>’ . do_shortcode(shortcode_unautop($content)) . ‘</div>’; return $output; }
On the jm_accordion_group function, I’m using a global variable called accordions_count to know how many accordions were processed and based on this, an id will be generated. There you will see also a function called: init_accordion; since all accordions can be setup in a different way, ie: the ‘active’ parameter (which accordion section will be expanded by default) may not the same for the whole accordions, I’m processing all parameters and saving them into a global variable as follows:
function init_accordion($id, $active, $height_style) { //Since the code is long, I will only put the relevant //parts here. After processing and converting all //parameters to string, I save them into a global //variable called: accordion_objects, which has //all the parameters from the accordions on a page, ie: //$GLOBALS[‘accordion_objects’] = [ // {‘id’: ‘jm-accordion-1’, ‘active’: 1, // ‘height_style’: ‘content’}, // {‘id’: ‘jm-accordion-2’, ‘active’: 3, // ‘height_style’: ‘auto’}, //] //… Processing comes here //Here I stored the parameters if ( !isset($GLOBALS[‘accordion_objects’]) ) { $GLOBALS[‘accordion_objects’] = array(); } $GLOBALS[‘accordion_objects’][] = array ( ‘id’ => $id, ‘active’ => $active, ‘height_style’ => $height_style ); //Then I enqueue the ‘jm-accordion_script’, which // I registered before wp_enqueue_script(‘jm-accordion_script’); //Finally I sent the value of the global //variable to javascript wp_localize_script(‘jm-accordion_script’, ‘accordion_vars’, $GLOBALS[‘accordion_objects’]); }
So, as you see there, the ‘wp_localize_script’ call will be done each time a new accordion group is detected. This causes that the accordion_vars is embed in javascript several times, ie:
<script type=’text/javascript’> /* <![CDATA[ */ var accordion_vars = [{“id”:“jm-accordion-1“, “active”:“false”, “height_style” : “content”}]; var accordion_vars = [{“id”:“jm-accordion-1”, “active”:“false”, “height_style” : “content”}, {“id” : “jm-accordion-2”, “active” : 1, “height_style” : “content”}]; /* ]]> */ </script>
Where can I call the ‘wp_localize_script’ so that it gets called only once? I tried the ‘wp_loaded’ action, but unfortunately the value of the global is always null at that point.
I also know that using global variables isn’t a good way, but I don’t know how else to do it.
Thanks in advanced
Josef
Ok, I solved this by using wp_add_inline_script instead of wp_localize_script as follows.
First, I won’t register my accordion.js script inside of allow_jquery_ui_accordion. So, I redefined it as follows:
function allow_jquery_ui_accordion() { if ( !is_admin() ) { wp_enqueue_script('jquery-ui-accordion'); } } add_action('wp_enqueue_scripts', 'allow_jquery_ui_accordion');
Then I deleted the accordion_objects global from the php code. I won’t need it after all. I only need it on the javascript. So, the new init_accordion function looks like:
function init_accordion($id, $active, $height_style) { //... Processing comes here // Some code comes here, but is not relevant to the post //... Finished processing. Here I will have initialized: // $id, $active, and $height_style $script_data = "accordion_vars.push({" . " 'id': '$id'," . " 'active': $active," . " 'height_style' : '$height_style'" . "});"; //If this is the first processed accordion group, then //the javascript variable accordion_vars is initialized //with an empty array if ($GLOBALS['accordions_count'] == 1) { $script_data = "var accordion_vars = []; " . $script_data; } //Then I enqueue the 'jm-accordion_script' wp_enqueue_script( 'jm-accordion_script', get_stylesheet_directory_uri() . '/js/accordion.js' ); //Finally I add the inline javascript just before the //script gets excecuted wp_add_inline_script('jm-accordion_script', $script_data, 'before'); }
The good thing is that even if the wp_enqueue_script function gets call several times, the script will be only embedded once. The result will look similar to this:
<script type='text/javascript'’> var accordion_vars = [] accordion_vars.push({ 'id': 'jm-accordion-1', 'active': false, 'height_style' : 'content' }); accordion_vars.push({ 'id': 'jm-accordion-2', 'active': 1, 'height_style' : 'content' }); </script> <script type='text/javascript' src='My_WordPress/themes/my_theme/js/accordion.js?ver=4.9.7'> </script>
If somebody else has another solution, I would like to see it.
Best regards
Josef
- The topic ‘Calling wp_localize_script after the page was loaded’ is closed to new replies.