Skip to content

Instantly share code, notes, and snippets.

@DaveyJake
Last active August 4, 2019 09:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaveyJake/f664a5ebf24f079242df1f78c20f1af9 to your computer and use it in GitHub Desktop.
Save DaveyJake/f664a5ebf24f079242df1f78c20f1af9 to your computer and use it in GitHub Desktop.
[WP] Replace Underscore with Lodash
<?php
/**
* Use `Lodash` as the drop-in replacement for Underscore in WordPress.
*
* This script uses the `CDNJS` API to ensure the latest version of Lodash is
* always retrieved. By default, Lodash will run only on the WordPress frontend
* unless the `$sitewide` parameter is set to `true`.
*
* @author Davey Jacobson <djacobson@usarugby.org>
* @package Davey_Jacobson
* @subpackage Use_Lodash
*/
if ( ! defined( 'ABSPATH' ) ) exit; // exit if directly accessed
class DJ_Use_Lodash {
/**
* This current version of this class.
*
* @var string
*/
private $version = '1.0.0';
/**
* The appropriate scope to load Lodash in.
*
* @var string
*/
public $scope;
/**
* Transient for the API retrieval.
*
* @var string
*/
public $transient = 'use_lodash_';
/**
* Primary constructor.
*
* @param bool [$sitewide=false] Optional. Set to `true` if you want to
* use Lodash across all of WordPress.
* @return DJ_Use_Lodash
*/
public function __construct( $sitewide = false ) {
$this->transient .= md5( $this->version );
$this->scope = $sitewide && is_admin() ? 'admin' : 'wp';
add_action( "{$this->scope}_enqueue_scripts", array( $this, 'replace_underscore_with_lodash' ), 10 );
}
/**
* Replace the default version of `Underscore` with `Lodash` in WordPress.
*
* @since 1.0.0
*
* @uses {@see 'wp_deregister_script'}
* @uses {@see 'wp_register_script'}
* @uses {@see 'wp_enqueue_script'}
*/
public function replace_underscore_with_lodash() {
// Prevent WordPress from loading Underscore.
wp_deregister_script( 'underscore' );
// Get Lodash from CDNJS.
$lodash = $this->get_lodash_from_cdnjs();
/*
* Re-register the `underscore` hook with Lodash as its script. This ensures that
* Lodash will be used as THE drop-in replacement for Underscore all across WordPress.
*/
wp_register_script( 'underscore', $lodash['url'], null, $lodash['version'], true );
wp_enqueue_script( 'underscore' );
}
/**
* Query the `CDNJS` API and return the lastest version of Lodash.
*
* @access private
*
* @since 1.0.0
*
* @return array Lodash filepath and version from `CDNJS` API.
*/
private function get_lodash_from_cdnjs() {
// All files on CDNJS are found in this path.
define( 'CDNJS', 'https://cdnjs.cloudflare.com/ajax/libs' );
// This will hold what's needed by WordPress.
$lodash = array();
// This is our current cached-for-the-year request to the CDNJS API.
$data = get_transient( $this->transient );
// Check if we've cached this request and cache it if needed.
if ( false === $data ) {
// Lodash is named `lodash.js` on CDNJS.
$lodash_on_cdnjs = 'lodash.js';
// The CDNJS API endpoint.
$cdnjs_api_endpoint = "https://api.cdnjs.com/libraries/{$lodash_on_cdnjs}?fields=name,filename,version";
// Send request to CDNJS.
$request = wp_remote_get( $cdnjs_api_endpoint );
if ( is_wp_error( $request ) ) {
return $request->get_error_message();
}
// If no errors were found, retrieve the CDNJS response.
$response = wp_remote_retrieve_body( $request );
if ( is_wp_error( $response ) ) {
return $response->get_error_message();
}
// If no error were found, parse the response from CDNJS.
$data = json_decode( $response );
// Set the transient for this retrieval.
set_transient( $this->transient, $data, YEAR_IN_SECONDS );
}
// Ensure you're grabbing the file you requested.
if ( $lodash_on_cdnjs === $data->name ) {
// Build the Lodash URL from the CDNJS response.
$lodash_url = CDNJS . "/{$lodash_on_cdnjs}/{$data->version}/{$data->filename}";
// Remember the array we made on line 78?
$lodash['url'] = $lodash_url;
$lodash['version'] = $data->version;
}
// Return the Lodash components needed for WordPress.
if ( ! empty( $lodash['url'] ) ) {
return $lodash;
}
}
}
new DJ_Use_Lodash();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment