wp_localize_script returns underfined in jQuery - php

I'm trying to pass a WordPress shortcode attribute to jQuery as a variable, but it keeps returning as undefined in jQuery. Everything with the shortcode function works as intended, same for the jQuery aside from the attribute returning as undefined. The jQuery script is also enqueuing properly.
This is the start of my PHP function:
function aw_simple_sorter_creator($atts) {
extract(shortcode_atts(array(
'show_posts' => '-1',
'effect' => ''
), $atts, 'aw_simple_sorter' ));
wp_enqueue_script('aw_simple_sorter_js', plugin_dir_url( __FILE__ ) . 'js/aw_simple_sorter.js');
wp_localize_script('aw_simple_sorter_js', 'aw_ss_script_vars', array(
'jQueryUIeffect' => __($effect),
)
);
In the above snippet, $effect should be equal to the shortcode attribute. The shortcode attribute does have a value as well. I've also tried 'jQueryUIeffect' => $effect, instead of this 'jQueryUIeffect' => __($effect),, but it still returns undefined in jQuery.
Then in my jQuery I'm trying to test the passed variable using the following wrapped in a .ready():
alert(aw_ss_script_vars.jQueryUIeffct);
Am I going about this the wrong way? Does something jump out that looks incorrect? Thanks.

You should start by changing your enqueue for register, secondly pass in the jquery dependancy.
If the script is being output on the page as you mention in the comments above, then the problem is likely in how you're trying to access the variables.
function do_scripts()
{
/* register the script */
wp_register_script( 'custom', plugin_dir_url( __FILE__ ) . '/js/scripts.js', array('jquery'), false, true );
$script_vars = array(
'key' => $value
... your values here....
);
/* actually enqueue jquery (that ships with WP) and your custom script */
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'custom' );
/* Localize the vairables */
wp_localize_script('custom', 'script_vars', $script_vars);
}
/* If we're not in the admin section call our function on the wp_enqueue_scripts hook */
if ( !is_admin() ) add_action( "wp_enqueue_scripts", "do_scripts", 10 );
to see if the variables are available, open your console in google chrome developer tools and type script_vars
in your script you should be able to access your values with dot notation as follows :
script_vars.yourKey

Related

Enqueue script url: put variable in url

I've created an option tab with Advanced Custom fields where you can paste your Google Maps API key, so I don't have to put the API key in the code over and over again when starting a new project.
Get the value of the custom field where I put my API key:
$mapsApi = get_field('maps_api', 'option');
Now, I am loading the API key with the following script:
function bredweb_files() {
// scripts
wp_enqueue_script('maps-api', 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY', array(), '1', true);
}
add_action( 'wp_enqueue_scripts', 'bredweb_files' );
(That is of course not the only thing I'm loading, also styles and other scripts)
So my question is, how do I place that variable ($mapsApi) in the url, instead of the YOUR_API_KEY?
I've tried the obvious: https://maps.googleapis.com/maps/api/js?key=$mapsApi, yet that doesn't work.
You can do such type of things.
function bredweb_files() {
$mapsApi = get_field('maps_api', 'option');
wp_enqueue_script('maps-api', 'https://maps.googleapis.com/maps/api/js? key='.$mapsApi, array(), '1', true);}
add_action( 'wp_enqueue_scripts', 'bredweb_files' );

Custom shortcode always displays at top of page

I realise there are similar questions to this on here, but all contain slightly different code to mine. I have a custom shortcode configured in the functions.php file, and for some reason it always displays at the top of the page. Nothing I do seems to be able to move it. Is this a result of something in the code?
function menu_shortcode( $atts ) {
return wp_nav_menu( array( 'theme_location' => 'header' ) );
}
add_shortcode( 'nav', 'menu_shortcode' );
Your shortcode is returning wp_nav_menu() but that function will output by default. Shortcodes aren't allowed to generate output so you need to set echo to false to prevent it.
function menu_shortcode( $atts ) {
return wp_nav_menu( array(
'theme_location' => 'header',
'echo' => false,
) );
}
add_shortcode( 'nav', 'menu_shortcode' );
Documentation:
https://developer.wordpress.org/reference/functions/wp_nav_menu/#parameters
https://codex.wordpress.org/Function_Reference/add_shortcode
The answer you received to your original question has been updated to fix the problem you've described: How to make a PHP function into a short code
All right, I've tested it on my own WordPress install with the following code:
function menu_shortcode() {
return wp_nav_menu( array( 'theme_location' => 'header' ) );
}
add_shortcode( 'b3_add_menu', 'menu_shortcode' );
I created a page called test and added the shortcode [b3_add_menu] to it. This is the result:
For me the menu is not displayed only at the top of the page, could you maybe tell me where you placed your "nav" shortcode?

wp_enqueue_script( ) function parameters in functions.php

I am making my first steps coding. I already made some courses of php in internet and now I am trying to continue learning from the practice while I am making a Wordpress theme.
I made a child theme from an existing theme and there is something that I dont understand in this function:
wp_enqueue_script( 'twentyfourteen-script', get_template_directory_uri() . '/js/functions.js', array( 'jquery' ), '20150315', true );
I found this in the site of wordpress:
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
I understand that $handle is the name of the script file, but i have to put that name in some place in the script file to make my code work?
Then i know that I should write get_template_directory_uri(), the source, and write array(jquery) in the case that it is a jquery file but what means '20150315', true . What means that number? Why I have to write true at the end?
Parameters
$handle
(string) (Required) Name of the script. Should be unique.
$src
(string) (Optional) Full URL of the script, or path of the script relative to the WordPress root directory.
Default value: false
$deps
(array) (Optional) An array of registered script handles this script depends on.
Default value: array()
$ver
(string|bool|null) (Optional) String specifying script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version. If set to null, no version is added.
Default value: false
$in_footer
(bool) (Optional) Whether to enqueue the script before </body> instead of in the <head>. Default 'false'.
Default value: false
So for your example:
wp_enqueue_script( 'twentyfourteen-script', get_template_directory_uri() . '/js/functions.js', array( 'jquery' ), '20150315', true );
Which breaks down to:
$handle = 'twentyfourteen-script'
$src = get_template_directory_uri() . '/js/functions.js'
$deps = array( 'jquery' )
$ver = '20150315'
$in_footer = true

wordpress shortcode attributes not being passed

I've created a short code that I'm trying to pass an attribute into, but I don't seem to be receiving the value on the other end.
Here's what I've got below;
function list_display($atts) {
extract( shortcode_atts(
array(
'pageName' => 'No Page Received',
), $atts )
);
echo $pageName;
add_shortcode('list-briefings-display', 'list_display');
}
and the shortcode being used is
[list-display pageName="My Page Name"]
and I'm running a require_once from functions.php
require_once ( TEMPLATEPATH. '/includes/list-display.php' );
But what I'm seeing on the screen is 'No Page Received', can anyone think of something I might've missed?
There is more content being generated by the shortcode, which I have't included, that's rendering fine. So it just seems to be something to do with how I've passed the attribute.
Any help is appreciated.
function list_display($atts) {
$atts = shortcode_atts( array(
'pagename' => 'No Page Received'
), $atts );
extract($atts);
echo $pagename;
}
add_shortcode('list-display', 'list_display');
You'll probably want to use "return" instead of "echo" if you're using the shortcode within pages and posts.. Echo could cause it to send output to the screen a little too early and won't end up exactly where you may be expecting it to be.
There was also a little formatting issue in your code that I've corrected, mainly trying to use add_shortcode() from within the very same function you're trying to reference. I also changed the first parameter of add_shortcode() to the shortcode you were trying to use in your example.

wordpress: loading javascript only where shortcode appears

have an interesting conundrum. I need to load about 8 javascript files and the same number of styles for my plugin. These are only needed where ever my shortcode is ran.
I've tried to load them with print_styles and print_scripts but they aren't rendering properly, plus to do so breaks xhtml validation. So at the moment they load on every page and due to the number of files needed its not feasible to leave it like this.
On another project I wrote a function into my plugin's index.php file that would take the current page, search it for my shortcode and if found only then would it print the scripts, but this is an ugly hack.
Has anybody got any suggestions or solutions?
any help would be appreciated,
regards,
Daithi
to answer my own question... I had it write the first time. You have to search each page to check that your shortcode is being used. This has to be done when page data is loaded and before page is displayed. To me it is complete overkill on the system, but unfortunately it is the way it is. I got this information from:
get_shortcode_regex
and
old nabble
So first:
add_action('template_redirect','wp_my_shortcode_head');
then:
function wp_my_shortcode_head(){
global $posts;
$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $posts[0]->post_content, $matches);
if (is_array($matches) && $matches[2] == 'YOURSHORTCODE') {
//shortcode is being used
}
}
replace 'YOURSHORTCODE' with the name of your shortcode and add your wp_enqueue_scripts into where it says //shortcode is being used.
I read a solution in here: http://scribu.net/wordpress/conditional-script-loading-revisited.html
Basically if using wordpress 3.3 you can enqueue your scripts in your short code function.
function my_shortcode($atts){
wp_enqueue_script( 'my-script', plugins_url( 'plugin_name/js/script.js' ), array('jquery'), NULL, true);
// if you add a css it will be added to the footer
//wp_enqueue_style( 'my-css', plugins_url( 'plugin_name/css/style.css' ) );
//the rest of shortcode functionality
}
Loading Scripts and Styles Dynamically Per Page Using a Shortcode
Advantages
Does not search through all the posts everytime the shortcode is called.
Able to add styles as well as scripts dynamically only when shortcode is on the page.
Does not use regexes since they tend to be slower than strstr() or strpos(). If you need to pickup args then you should use the shortcode regex mentioned above.
Reduces file calls
Explanation of Code
Finds the shortcodes on page using the save_post hook only when the post is not a revision and matches the specified post_type.
Saves the found post ids as an array using add_option() with autoload set to yes unless the entry is already present. Then it will use update_option().
Uses hook wp_enqueue_scripts to call our add_scripts_and_styles() function.
That function then calls get_option() to retrieve our array of page ids. If the current $page_id is in the $option_id_array then it adds the scripts and styles.
Please note: I converted the code from OOP Namespaced classes so I may have missed something. Let me know in the comments if I did.
Code Example: Finding Shortcode Occurences
function find_shortcode_occurences($shortcode, $post_type = 'page')
{
$found_ids = array();
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => -1,
);
$query_result = new WP_Query($args);
foreach ($query_result->posts as $post) {
if (false !== strpos($post->post_content, $shortcode)) {
$found_ids[] = $post->ID;
}
}
return $found_ids;
}
function save_option_shortcode_post_id_array( $post_id )
{
if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
return;
}
$option_name = 'yourprefix-yourshortcode';
$id_array = find_shortcode_occurences($option_name);
$autoload = 'yes';
if (false == add_option($option_name, $id_array, '', $autoload)) update_option($option_name, $id_array);
}
add_action('save_post', 'save_option_shortcode_id_array' );
Code Example: Shortcode Dynamically Include Scripts and Styles
function yourshortcode_add_scripts_and_styles() {
$page_id = get_the_ID();
$option_id_array = get_option('yourprefix-yourshortcode');
if (in_array($page_id, $option_id_array)) {
wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
wp_enqueue_style( $handle, $src , $deps);
}
}
add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');
Just read this tutorial over here: http://scribu.net/wordpress/optimal-script-loading.html
Seems to be the best way.
add_action('init', 'register_my_script');
add_action('wp_footer', 'print_my_script');
function register_my_script() {
wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
}
function print_my_script() {
global $add_my_script;
if ( ! $add_my_script )
return;
wp_print_scripts('my-script');
}
In this case, the script will be enqueued only if the $add_my_script
global was set at some point during the rendering of the page.
add_shortcode('myshortcode', 'my_shortcode_handler');
function my_shortcode_handler($atts) {
global $add_my_script;
$add_my_script = true;
// actual shortcode handling here
}
So, the script will be added if [myshortcode ...] was found in any of
the posts on the current page.
Load Scripts and Styles if Post/Page has Short Code
The best solution is to load the files into the page header if, and only if, the current post or page has the short code inside its content. And that’s exactly what the following function does:
function flip_register_frontend_assets()
{
//register your scripts and styles here
wp_register_style('pp_font','plugin_styles.css', null, null, 'all');
global $post;
//check whether your content has shortcode
if(isset($post->post_content) && has_shortcode( $post->post_content, 'your-
shortcode')){
//Enqueue your scripts and styles here
wp_enqueue_style( 'pp_font');
}
}
Simply place this function inside of one of your plugin files and you’re good to go.
You will need to replace [your-shortcode] with the short code you want to search for, and you will also need to replace plugin_styles.css with your stylesheet name.
You can just use this code to check if the shortcode is implemented in page content or in sidebar widgets.
<?php
if ( shortcode_exists( 'gallery' ) ) {
// The [gallery] short code exists.
}
?>
I use WordPress Version 5.4 with OOP style of code i dont know if this affect why none of the above solutions didn't work for me so i come up with this solution:
public function enqueue_scripts() {
global $post;
//error_log( print_r( $post, true ) );
//error_log( print_r( $post->post_content, true ) );
//error_log( print_r( strpos($post->post_content, '[YOUR_SHORTCODE]'),true));
if ( is_a( $post, 'WP_Post' ) && strpos($post->post_content, '[YOUR_SHORTCODE]') )
{
wp_register_style('my-css', $_css_url);
wp_register_script('my-js', $_js_url);
}
}
Hope this help someone.
How many pages are these scripts going to be loaded on? Would it be feasible to maintain an array of pages, and only load the scripts/stylesheets when the current page is in the array?
Otherwise, without scanning the code there is no way to do this, as WP doesn't even know the shortcode exists until well into the page load.
BraedenP is right, I'm pretty sure there is no way to detect shortcode usage at the execution time of wp_enqueue_scripts / when the stylesheets load.
Is there any reason you must do this in 8 files? One would just be more efficient, then it may not be a problem to load it on every page.
You could consider a PHP stylesheet solution that only executes certain styles if needed. A css.php file may resemble:
<?php
header("content-type: text/css");
/* You can require the blog header to refer to WP variables and make queries */
//require '../../../wp-blog-header.php';
$css = '';
$css .= file_get_contents('style.css');
/* Consider using GET variables or querying a variable in the WP database to determine which stylesheets should be loaded. You could add an option to the backend that allows a stylesheet to be turned on or off. */
if($condition1 == TRUE) $css .= file_get_contents('condition1.css');
if($condition2 == TRUE) $css .= file_get_contents('condition2.css');
?>
Less scripts and less stylesheets means less http requests and a faster load time.

Categories