Setting the $in_footer parameter to true in wp_enqueue_script loads a script in the footer. This is great if I'm adding a new script. However, WordPress already provides a version of jQuery by default and this is enqueued in the document head.
How can I move the jQuery provided by WordPress from the header to the footer?
You need to de-register the existing query and re-register it to load in the footer.
function jquery_in_footer() {
if (!is_admin()) {
wp_deregister_script('jquery');
// load the local copy of jQuery in the footer
wp_register_script('jquery', home_url(trailingslashit(WPINC) . 'js/jquery/jquery.js'), false, null, true);
wp_enqueue_script('jquery');
}
}
add_action('init', 'jquery_in_footer');
Bear in mind that if you have any other scripts enqueued that depend on jQuery and are not loaded in the footer, WordPress will still load jQuery in the header to satisfy that dependency.
(adapted from http://www.ericmmartin.com/5-tips-for-using-jquery-with-wordpress/)
Edit: If you really want to get crazy, you could modify the WP_Scripts object directly, but then you're dependent on the implementation never changing. I imagine that would change before they even thought of moving jquery.js' location in wp-includes :)
But just for fun…
function load_jquery_footer() {
global $wp_scripts;
$wp_scripts->in_footer[] = 'jquery';
}
add_action('wp_print_scripts', 'load_jquery_footer');
Maybe the defer attribute will help. There is a good article on this topic.
I use the following code for convinient nonblocking loading of any scripts, not just jQuery.
// Defer scripts.
function dt_add_defer_attribute( $tag, $handle ) {
$handles = array(
'jquery-core',
'jquery-migrate',
'fancybox',
);
foreach( $handles as $defer_script) {
if ( $defer_script === $handle ) {
return str_replace( ' src', ' defer src', $tag ); // Or ' async src'
}
}
return $tag;
}
add_filter( 'script_loader_tag', 'dt_add_defer_attribute', 10, 2 );
Related
I've put some custom code in my active child theme's functions.php. I'm trying to enqueue some style on a admin page. However, a style enqueued in admin_enqueue_scripts hook gets automatically removed and after debugging I found that its not present in the very next hook i.e. admin_print_styles.
Here's some code in active child theme's functions.php which I used for debugging purposes:
function debug_enqueue_admin_scripts() {
wp_enqueue_style( 'gforms_datepicker_css', GFCommon::get_base_url() . "/css/datepicker{$min}.css", null, GFCommon::$version );
if( wp_style_is( 'gforms_datepicker_css' ) {
// NOTE: This runs and I am able to view the following log
error_log( __FUNCTION__ . ': datepicker_css is enqueued.' );
}
}
add_action( 'admin_enqueue_scripts', 'debug_enqueue_admin_scripts', 11 );
function check_if_still_enqueued() {
if( wp_style_is( 'gforms_datepicker_css', 'registered' ) ) {
error_log( __FUNCTION__ . ' datepicker_css registered.');
} else {
// NOTE: It gets in this else block and following output is logged
error_log( __FUNCTION__ . ' datepicker_css **NOT** registered.');
}
}
add_action( 'admin_print_styles', 'check_if_still_enqueued' );
I'm not deregistering the gforms_datepicker_css anywhere, but its getting removed maybe due to some plugin.
While debugging, I've gone further and inspected if it was deregistered by putting extra line in WordPress core class method WP_Dependencies::remove() located here as following.
public function remove( $handles ) {
// NOTE: Check if deregistered
error_log( __METHOD__ . ' ' . var_export( $handles, true ) );
foreach ( (array) $handles as $handle )
unset($this->registered[$handle]);
}
But I'm unable to see log output with gforms_datepicker_css in it from this method.
I'm unsure why the style is getting removed from enqueue list. Can anybody please help me debugging this behaviour and find the solution?
The scripts and styles were not loading on admin pages because the No-Conflict Mode setting of Gravity Forms plugin was turned ON. As the setting is designed to do so:
As described in Gravity Forms documentation:
To temporarily resolve the issue, go to Forms > Settings and enable No
Conflict mode. This should stop third party scripts from writing to
Gravity Forms administration pages and allow you to do the things you
need.
The issue resolved after turning OFF the No-Conflict Mode.
I have created a wordpress plugin that creates various widgets. To keep page load time down, I only want to enqueue the associated scripts when the widget is being used.
To do this I created a function like this:
function enqueue_lightbox(){
wp_enqueue_style(
SKIZZAR_SHORTCODES__PLUGIN_SLUG . '-fancybox-css',
'https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.css',
array(),
SKIZZAR_SHORTCODES__VERSION
);
wp_enqueue_script( SKIZZAR_SHORTCODES__PLUGIN_SLUG . '-lightbox' );
wp_enqueue_script( SKIZZAR_SHORTCODES__PLUGIN_SLUG . '-lightbox-media' );
}
And in my widget class I call it like this:
enqueue_lightbox();
The issue I have is that I have 2 widgets sharing the same piece of code, so I'd like to create a statement that says, if it hasn't been enqueued elsewhere already, enqueue it.
How would I write this function?
You can use wp_script_is function to check the file and load it like this
$handle = 'fluidVids.js';
$list = 'enqueued';
if (wp_script_is( $handle, $list )) {
return;
} else {
wp_register_script( 'fluidVids.js', plugin_dir_url(__FILE__).'js/fluidvids.min.js');
wp_enqueue_script( 'fluidVids.js' );
}
My PHP code below works great locally but as soon as I put this on the live server it takes the whole site down. After investigation error logs, it has an issue with the [] used in this line of code:
wp_enqueue_script( 'jquery', '//fake-jquery-script.js', [], null );
Here's the php in full, how do I get around this issue?
/**
* #desc De-register WP jquery
**/
add_action( 'wp_print_scripts', 'de_script', 100 );
function de_script() {
wp_dequeue_script( 'jquery' );
wp_deregister_script( 'jquery' );
}
/**
* Inject jQuery early if there's a Gravity Form
*/
function gc_gform_inject_jquery( $content = '' ) {
global $gc_jquery_loaded_before_gform;
if ( !isset( $gc_jquery_loaded_before_gform )) {
// set global variable so jQuery isn't loaded twice
$gc_jquery_loaded_before_gform = true;
// inject jQuery code
echo '<!-- loading jquery before Gravity Form inline scripts -->';
gc_load_jquery_cdn_and_fallback();
}
return $content;
}
add_filter( 'gform_cdata_open', 'gc_gform_inject_jquery' );
/**
* Load jQuery in the footer or before the first Gravity Form.
* Include a local fallback if the Google CDN fails (e.g. User is in China)
*/
function gc_load_jquery_cdn_and_fallback() {
// Google CDN
echo '<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery'. (SCRIPT_DEBUG ? '.js' : '.min.js') .'"></script>';
// Local fallback
echo '<script>if (!window.jQuery) { document.write(\'<script src="'. get_stylesheet_directory_uri() .'/js/vendor/jquery-1.11.2'. (SCRIPT_DEBUG ? '.js' : '.min.js') .'"><\/script>\'); }</script>';
}
/**
* Loading jQuery and jQuery-dependent scripts
* If jQuery was not already loaded before a Gravity Form, load it
* Also enqueue a fake version of it (for dependencies) and then
* remove this fake script
*/
function gc_load_javascript_in_footer() {
global $gc_jquery_loaded_before_gform;
// If jQuery has not been loaded already, load it
if ($gc_jquery_loaded_before_gform !== true) {
gc_load_jquery_cdn_and_fallback();
}
// Enqueue a fake script called "jquery" to for dependent enqueued scripts
// HERE'S THE PROBLEM
wp_enqueue_script( 'jquery', '//fake-jquery-script.js', [], null );
// Remove the fake script
function gc_remove_fake_jquery_script($tag) {
$tag = ( strpos($tag, 'fake-jquery-script') !== false ) ? '' : $tag;
return $tag;
}
add_filter( 'script_loader_tag', 'gc_remove_fake_jquery_script' );
}
add_action('wp_footer', 'gc_load_javascript_in_footer');
[] is PHP short hand for an empty array.
http://php.net/manual/en/language.types.array.php
But you require PHP 5.4+ for it to work.
If it works locally but fails remotely, chances are your remote server is running < PHP 5.4
Please call javascript with thid code
wp_enqueue_script( 'jquery', '//fake-jquery-script.js', array('jquery'), '2015-10-26' );
and Please download fake-jquery-script.js .and put on the projects js template folder and call javascript in
wp_enqueue_script( 'jquery', '//fake-jquery-script.js', array('jquery'), '2015-10-26' );
I'm trying to change the og:url content on specific posts but I am unsure how to implement my changes from the functions.php file.
I have tried doing this using the content I have found on the internet but believe it has been updated since then.
I have updated the class-opengraph.php file in the the wordress-seo plugin folder which works, please find my edits below:
public function url() {
$url = apply_filters('wpseo_opengraph_url',
WPSEO_Frontend::get_instance()->canonical(false));
if (is_string($url) && $url !== '' ) {
if (is_page(32721)) {
$this->og_tag('og:url', esc_url('testing'));
} else {
$this->og_tag( 'og:url', esc_url( $url ) );
}
return true;
}
return false;
}
It's not good to modify the plugin files directly because when you update the plugin, you will lose all your changes to those files.
There are two solutions that I have found to do such thing.
You get the instance of the class WPSEO_Frontend, then update it's options for the og:url.
e.g.
$object = WPSEO_Frontend::get_instance();
$object->options['og_url'] = esc_url( $url );
This can be added before the wp_head()
You can use add_filter to hook a function to the filter action. We use the filter action below.
Filter: 'wpseo_opengraph_url' - Allow changing the OpenGraph URL
e.g.
function update_og_url($url) {
return "http://www.yoursampleurl.com";
}
add_filter('wpseo_opengraph_url', 'update_og_url', 10, 1);
Source: Wordpress SEO API
I'm not sure if this is possible but I was hoping that I could retrieve WordPress' built-in jQuery version number programmatically via PHP.
I prefer to include a CDN version of jQuery using wp_register_script(), then I use the WordPress' built-in jQuery as a fallback.
The problem with using a CDN version is that if WordPress updates their built-in version of jquery, the CDN version might not match. So I was hoping to fetch the version number (maybe using wp_default_scripts()), and then pass that through to wp_register_script().
Any ideas on how I get do this?
I borrowed from WP jQuery Plus:
function hs_script_enqueuer() {
if( !is_admin() ) {
// Enqueue so we can grab the built-in version
wp_enqueue_script( 'jquery' );
// Get jquery handle - WP 3.6 or newer changed the jQuery handle (once we're on 3.6+ we can remove this logic)
$jquery_handle = (version_compare($wp_version, '3.6-alpha1', '>=') ) ? 'jquery-core' : 'jquery';
// Get the WP built-in version
$wp_jquery_ver = $GLOBALS['wp_scripts']->registered[$jquery_handle]->ver;
// Just in case it doesn't work, add a fallback version
$jquery_ver = ( $wp_jquery_ver == '' ) ? '1.8.3' : $wp_jquery_ver;
// De-register built-in jquery
wp_deregister_script('jquery');
// Register CDN version
wp_register_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/'. $jquery_ver .'/jquery.min.js' );
// Enqueue new jquery
wp_enqueue_script( 'jquery' );
}
}
add_action( 'wp_enqueue_scripts', 'hs_script_enqueuer' );
// Add jquery fallback if CDN is unavailable
function jquery_fallback() {
echo '<script>window.jQuery || document.write(\'<script src="' . includes_url( 'js/jquery/jquery.js' ) . '"><\/script>\')</script>' . "\n";
}
add_action( 'wp_head', 'jquery_fallback' );
if( ! function_exists('register_jquery_script') ){
function register_jquery_script(){
/* Get jquery handle - WP 3.6 or newer changed the jQuery handle (once we're on 3.6+ we can remove this logic) */
$jquery_handle = (version_compare($wp_version, '3.6-alpha1', '>=') ) ? 'jquery-core' : 'jquery';
/* Get the WP built-in version */
$wp_jquery_ver = $GLOBALS['wp_scripts']->registered[$jquery_handle]->ver;
/* Just in case it doesn't work, add a fallback version */
$jquery_ver = ( $wp_jquery_ver == '' ) ? '1.8.3' : $wp_jquery_ver;
/* the URL to check CDN accessibility */
$url = 'http://ajax.googleapis.com/ajax/libs/jquery/' . $jquery_ver . '/jquery.min.js';
/* test CDN accessibility */
$test_url = wp_remote_fopen($url);
/* deregisters the default WordPress jQuery */
wp_enqueue_script( 'jquery' );
wp_deregister_script( 'jquery' );
/* if CDN available - load it */
if( $test_url !== false ) {
wp_register_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/'. $jquery_ver .'/jquery.min.js', false , false , true );
}
/* if CDN unavailable - load local jquery copy */
else{
wp_register_script('jquery', get_template_directory_uri() . '/js/jquery.min.js', __FILE__, false, false, true);
}
wp_enqueue_script('jquery');
}
add_action('wp_enqueue_scripts','register_jquery_script');
}
you must be sure that you loaded local jquery into the template_directory/js/ with name jquery.min.js
I'm loading all scripts in wp_footer() by default for page loading performance.
If you loading your js scripts in wp_header(), you will change the last true to false on lines:
wp_register_script( 'jquery' , $src , false , false , false );
Enjoy it!