Skip to content

Instantly share code, notes, and snippets.

@crstauf
Last active October 12, 2019 01:37
Show Gist options
  • Save crstauf/20479cb9d1dbcd59fa81647aae484cd9 to your computer and use it in GitHub Desktop.
Save crstauf/20479cb9d1dbcd59fa81647aae484cd9 to your computer and use it in GitHub Desktop.
A drop-in (mu-plugin or include) helper for adding dynamic styles to a template.
<?php
/**
* Plugin name: Dynamic Styles
* Plugin URI: https://gist.github.com/crstauf/20479cb9d1dbcd59fa81647aae484cd9
* Author: Caleb Stauffer
* Author URI: https://develop.calebstauffer.com
* Version: 1.1
*/
/**
* Class: DynamicStyles
*/
class DynamicStyles {
/**
* @var string[] $registered Registered dynamic styles (handle => selectors and properties).
* @var string[] $queue Handles to print.
* @var array $done Handles printed (handle => microtime)
*/
public $registered = array();
public $queue = array();
public $done = array();
/**
* Get or initialize instance.
*
* @return self
*/
static function instance() {
static $_instance = null;
if ( is_null( $_instance ) )
$_instance = new self;
return $_instance;
}
/**
* Construct.
*/
protected function __construct() {
add_action( 'wp_print_styles', array( $this, 'action__wp_print_styles' ) );
add_action( 'wp_print_footer_scripts', array( $this, 'action__wp_print_footer_scripts' ) );
add_action( 'dynamic-styles/print_queued_items', array( $this, 'print_queued_items' ) );
}
/**
* Register styles.
*
* @param string $handle
* @param string $selectors
* @param string $properties
* @uses self::instance()
*/
static function register( $handle, $selectors, $properties ) {
$self = static::instance();
if ( isset( $self->registered[$handle] ) )
return;
$self->registered[$handle] = $selectors . ' { ' . $properties . ' }';
}
/**
* Enqueue styles.
*
* @param string $handle
* @param string $selectors
* @param string $properties
* @uses self::register()
* @uses self::instance()
*/
static function enqueue( $handle, $selectors = '', $properties = '' ) {
if (
!empty( $selectors )
&& !empty( $properties )
)
static::register( $handle, $selectors, $properties );
$self = static::instance();
if (
!isset( $self->registered[$handle] )
|| isset( $self->done[$handle] )
)
return;
$self->queue[] = $handle;
}
/**
* Print items.
*
* @param string|array $handles
* @return array
*/
static function print_items( $handles ) {
$handles = ( array ) $handles;
$self = static::instance();
$handles = array_filter( $handles, function( $handle ) {
return (
isset( $self->registered[$handle] )
&& !isset( $self->done[$handle] )
);
} );
do_action( 'dynamic-styles/printing_items', $handles );
# Open style block.
echo '<style type="text/css">' . "\n";
# Start items timer.
do_action( 'qm/start', ( $timer = 'dynamic-styles/printing_items' ) );
# Print items.
foreach ( $handles as $handle ) {
echo $self->registered[$handle] . "\n";
$self->done[$handle] = microtime( true );
# Lap items timer.
do_action( 'qm/lap', $timer );
}
# Stop items timer.
do_action( 'qm/stop', $timer );
# Close style block.
echo '</style>' . "\n";
do_action( 'dynamic-styles/printed_items', $handles );
}
/**
* Print queued styles.
*
* @uses self::print_items()
*/
function print_queued_items() {
# Store queue.
$queue = $this->queue;
do_action( 'dynamic-styles/printing_queued_items', $queue );
static::print_items( $queue );
foreach ( $queue as $i => $handle )
if ( isset( $this->done[$handle] ) )
unset( $this->queue[$i] );
do_action( 'dynamic-styles/printed_queued_items', $queue );
}
/**
* Action: wp_print_styles
*
* - print queued styles in header
*/
function action__wp_print_styles() {
if ( empty( $this->queue ) )
return;
echo '<!-- Begin header dynamic styles -->' . "\n";
do_action( 'dynamic-styles/print_queued_items' );
echo '<!-- End header dynamic styles -->' . "\n";
}
/**
* Action: wp_print_footer_scripts
*
* - print queued styles in footer
*/
function action__wp_print_footer_scripts() {
if ( empty( $this->queue ) )
return;
echo '<!-- Begin footer dynamic styles -->' . "\n";
do_action( 'dynamic-styles/print_queued_items' );
echo '<!-- End footer dynamic styles -->' . "\n";
}
}
if ( !function_exists( 'register_dynamic_style' ) ) {
/**
* Register styles.
*
* @param string $handle
* @param string $selectors
* @param string $properties
* @uses DynamicStyles::register()
*/
function register_dynamic_style( $handle, $selectors, $properties ) {
DynamicStyles::register( $handle, $selectors, $properties );
}
}
if ( !function_exists( 'enqueue_dynamic_style' ) ) {
/**
* Enqueue styles.
*
* @param string $handle
* @param string $selectors
* @param string $properties
* @uses DynamicStyles::enqueue()
*/
function enqueue_dynamic_style( $handle, $selectors = '', $properties = '' ) {
DynamicStyles::enqueue( $handle, $selectors, $properties );
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment