Skip to content

Instantly share code, notes, and snippets.

@stuporglue
Created September 15, 2017 13:00
Show Gist options
  • Save stuporglue/39777add448008096cb6a43a6ffc8c47 to your computer and use it in GitHub Desktop.
Save stuporglue/39777add448008096cb6a43a6ffc8c47 to your computer and use it in GitHub Desktop.
Load required scripts and styles into a page if they're not already loaded.
<?php
/**
* We'll need access to these two objects.
*/
global $wp_scripts, $wp_styles;
/**
* Loop over all queued styles. If a style is still in the queue it hasn't been printed yet.
*
* Get its info so we can later check if it needs to be loaded.
*
* The queue only has the handles of the css files.
*/
$maybe_missing_css = array();
foreach( $wp_styles->queue as $handle ){
if ( strpos( $handle, 'leafletphp' ) === 0 ) {
$maybe_missing_css[] = $handle;
}
}
/**
* The queued CSS files might depend on other CSS files. Load depenencies, then get info
* about each script from the to_do list.
*/
$missing_css = array();
if ( !empty( $maybe_missing_css ) ) {
$wp_styles->all_deps( $maybe_missing_css, true );
foreach ( $wp_styles->to_do as $handle ) {
$src = $wp_styles->registered[$handle]->src;
// Some styles may be empty if they only have dependencies and no source. Skip these. We'll process their dependencies.
if ( empty( $src ) ) {
continue;
}
// Append the absolute URL to the stylesheet if it's a relative path.
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_styles->content_url && 0 === strpos( $src, $wp_styles->content_url ) ) ) {
$src = $wp_styles->base_url . $src;
}
$missing_css[] = add_query_arg( 'ver', $wp_styles->registered[$handle]->ver, $src);
}
}
/**
* Now we do the exact same thing for JavaScript
*/
$maybe_missing_js = array();
foreach( $wp_scripts->queue as $handle ){
if ( strpos( $handle, 'leafletphp' ) === 0 ) {
$maybe_missing_js[] = $handle;
}
}
$missing_js = array();
if ( !empty( $maybe_missing_js ) ) {
$wp_scripts->all_deps( $maybe_missing_js, true );
foreach( $wp_scripts->to_do as $handle ) {
$src = $wp_scripts->registered[$handle]->src;
if ( empty( $src ) ) {
continue;
}
if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && 0 === strpos( $src, $wp_scripts->content_url ) ) ) {
$src = $wp_scripts->base_url . $src;
}
$missing_js[] = add_query_arg( 'ver', $wp_scripts->registered[$handle]->ver, $src );
}
}
/**
* At this point any CSS files which haven't been printed during this request
* should be in $missing_css and any JS which hasn't been printed should be in
* $missing_js. Note that since this may be an ajax request we don't know what
* was loaded on the actual page, or by other ajax calls.
*
* Now we print our HTML, including our <script> tag.
*
* In reality this might be bundled in a function and return the HTML as a string
* which would be included in the ajax response.
*/
// Generate a unique ID for our div, so we can reference it in JavaScript later.
$div_id = 'my_div_' . time();
// Set up the div wrapper.
?>
<div id="<?php echo $div_id;?>">
<script>
// The ajax call may occur many times on a page, but we only need to load the JS/CSS once.
// Use a global to keep track of our promises.
window.js_promises = window.js_promises || [];
// Only run after the document is ready. This code may be being printed inline, in which case
// scripts may be being printed in the footer, in which case we don't want to also print ours.
jQuery(document).ready(function(){
var maybe_missing_css = <?php echo json_encode( $missing_css ); ?>;
jQuery(maybe_missing_css).each(function(i,css){
// Search for any missing CSS files.
if ( jQuery('link[href="'+css+'"]').length === 0 ) {
// CSS <link> elements can be added to the DOM at any time and they'll be loaded.
jQuery('head').append('<link rel="stylesheet" href="'+css+'">');
}
});
var maybe_missing_js = <?php echo json_encode( $missing_js ); ?>;
jQuery(maybe_missing_js).each(function(i,js){
if ( jQuery('script[src="'+js+'"]').length === 0 ) {
// Adding a <script> to the DOM doesn't actually load it. We just do this
// so that if we have multiple blocks of ajax loaded content we don't end
// up loading a script for each one.
jQuery('head').append('<link rel="stylesheet" href="'+js+'">');
// We could use .getScript() instead of .ajax(), but .getScript
// doesn't cache requested files, and we want caching.
var promise = jQuery.ajax({
dataType: 'script',
cache: true,
url: js
});
// Gather up the promises.
window.js_promises.push( promise );
}
});
// jQuery.when takes a comma delimited list of promises/deferred objects.
// Since we have an array of them, use .apply.
jQuery.when.apply( jQuery, window.js_promises ).then(function(){
// This function will run when all of the promises have successfully
// completed, or in other words, when all our required JavaScript is available.
var div_id='<?php echo $div_id;?>';
// With the scripts all loaded we're ready to do something awesome with this div!
jQuery('#'+div_id).doSomethingAwesome();
});
});
</script>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment