Git Product home page Git Product logo

wp-dynamic-css's Introduction

WordPress Dynamic CSS License License License

A library for generating static stylesheets from dynamic content, to be used in WordPress themes and plugins.

Contributors: ykadosh
Tags: theme, mods, wordpress, dynamic, css, stylesheet
Tested up to: 4.7
Stable tag: 1.0.5
Requires: PHP 5.3.0 or newer
WordPress plugin: wordpress.org/plugins/wp-dynamic-css/
License: GPLv3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html

--

WordPress Dynamic CSS allows you to convert this:

body {
   background-color: $body_bg_color;
}

into this:

body {
   background-color: #fff;
}

Using dynamic user data.

Contents

Overview

WordPress Dynamic CSS is a lightweight library for generating CSS stylesheets from dynamic content (i.e. content that can be modified by the user). The most obvious use case for this library is for creating stylesheets based on Customizer options. Using the special dynamic CSS syntax you can write CSS rules with variables that will be replaced by static values using a custom callback function that you provide.
As of version 1.0.2 this library supports multiple callback functions, thus making it safe to use by multiple plugins/themes at the same time.

Basic Example

First, add this to your functions.php file:

// 1. Load the library (skip this if you are loading the library as a plugin)
require_once 'wp-dynamic-css/bootstrap.php';

// 2. Enqueue the stylesheet (using an absolute path, not a URL)
wp_dynamic_css_enqueue( 'my_dynamic_style', 'path/to/my-style.css' );

// 3. Set the callback function (used to convert variables to actual values)
function my_dynamic_css_callback( $var_name )
{
   return get_theme_mod($var_name);
}
wp_dynamic_css_set_callback( 'my_dynamic_style', 'my_dynamic_css_callback' );

// 4. Nope, only three steps

Then, create a file called my-style.css and write your (dynamic) CSS in it:

body {
   background-color: $body_bg_color;
}

In the above example, the stylesheet will be automatically compiled and printed to the <head> of the document. The value of $body_bg_color will be replaced by the value of get_theme_mod('body_bg_color').

Now, let's say that get_theme_mod('body_bg_color') returns the value #fff, then my-style.css will be compiled to:

body {
   background-color: #fff;
}

Simple, right?

Installation

Via Composer

If you are using the command line: $ composer require askupa-software/wp-dynamic-css:dev-master

Or simply add the following to your composer.json file:

"require": {
     "askupa-software/wp-dynamic-css": "dev-master"
 }

And run the command composer install

This will install the package in the directory wp-content/plugins. For custom install path, add this to your composer.json file:

"extra": {
     "installer-paths": {
         "vendor/askupa-software/{$name}": ["askupa-software/wp-dynamic-css"]
     }
 }

Via WordPress.org

Install and activate the plugin hosted on WordPress.org: wordpress.org/plugins/wp-dynamic-css/

When the plugin is activated, all the library files are automatically included so you don't need to manually include them.

Manually

Download the package from github and include bootstrap.php in your project:

require_once 'path/to/wp-dynamic-css/bootstrap.php';

Dynamic CSS Syntax

This library allows you to use special CSS syntax that is similar to regular CSS syntax with added support for variables with the syntax $my_variable_name. Since these variables are replaced by values during run time (when the page loads), files that are using this syntax are therefore called dynamic CSS files. Any variable in the dynamic CSS file is replaced by a value that is retrieved by a custom 'value callback' function.

A dynamic CSS file will look exactly like a regular CSS file, only with variables. For example:

body {
   background-color: $body_bg_color;
}

During run time, this file will be compiled into regular CSS by replacing all the variables to their corresponding values by calling the 'value callback' function and passing the variable name (without the $ sign) to that function.

Array variables (since 1.0.3)

Version 1.0.3 added support for array subscripts, using a syntax similar to that of PHP. For example:

body {
   font-family: $font['font-family'];
}

The callback function should accept a second variable that will hold an array of subscript names. A more in-depth explanation can be found in the Setting the Value Callback section.

Future releases may support a more compex syntax, so any suggestions are welcome. You can make a suggestion by creating an issue or submitting a pull request.

Piped filters (since 1.0.5)

Version 1.0.5 added support for piped filters. Filters can be registered using the function wp_dynamic_css_register_filter( $handle, $filter_name, $callback ) where $filter_name corresponds to the name fo the filter to be used in the stylesheet. For example, if a filter named myFilter was registered, it can be applied using the following syntax:

body {
   font-family: $myVar|myFilter;
}

Filters can also be stacked together:

body {
   font-family: $myVar|myFilter1|myFilter2;
}

And can even take additional parameters:

body {
   font-family: $myVar|myFilter1('1',2,3.4);
}

See Registering Filters to learn how to register filter callback functions.

Enqueueing Dynamic Stylesheets

To enqueue a dynamic CSS file, call the function wp_dynamic_css_enqueue and pass it a handle and the absolute path to your CSS file:

wp_dynamic_css_enqueue( 'my_dynamic_style', 'path/to/dynamic-style.css' );

This will print the contents of dynamic-style.css into the document <head> section after replacing all the variables to their values using the given callback function set by wp_dynamic_css_set_callback().

The first argument - the stylesheet handle - is used as an id for associating a callback function to it.

If multiple calls to wp_dynamic_css_enqueue() are made with different CSS files, then their contents will be appended to the same <style> section in the document <head>.

Loading the Compiled CSS as an External Stylesheet

Instead of printing the compiled CSS to the head of the document, you can alternatively load it as an external stylesheet by setting the second parameter to false:

wp_dynamic_css_enqueue( 'my_dynamic_style', 'path/to/dynamic-style.css', false );

This will reduce the loading time of your document since the call to the compiler will be made asynchronously as an http request. Additionally, styelsheets that are loaded externally can be cached by the browser, as opposed to stylesheets that are printed to the head.

The disadvantage of this approach is that the Customizer's live preview will not show the changes take effect without manually reloading the page.

Setting the Value Callback

The example given in the overview section uses the get_theme_mod() function to retrieve the value of the variables:

function my_dynamic_css_callback( $var_name )
{
   return get_theme_mod($var_name);
}
wp_dynamic_css_set_callback( 'my_dynamic_style', 'my_dynamic_css_callback' );

However, the get_theme_mod() function also takes a second argument, which is the default value to be used when the modification name does not exists (e.g. no changes were made in Customizer since the theme was activated).

In that case, we can tweak our callback function to return default values as well:

$theme_mod_defaults = array(
   'body_bg_color' => '#fff',
   'body_text_color' => 'black'
);

function my_dynamic_css_callback( $var_name )
{
   return get_theme_mod($var_name, @$theme_mod_defaults[$var_name]);
}
wp_dynamic_css_set_callback( 'my_dynamic_style', 'my_dynamic_css_callback' );

Your CSS file can look something like this:

body {
   background-color: $body_bg_color;
   color: $body_text_color;
}

Which will be compiled to this (provided that no changes were made by the user in Customizer):

body {
   background-color: #fff;
   color: black;
}

Array variables

It is also possible to access array values using subscripts. An example dynamic CSS file may look like:

body {
   background-color: $body_bg_color;
   color: $body_text_color;
   font: $font['font-size']px '$font['font-family']';
}

However, in this case the callback function is passed 2 parameters: one holding the variable name, and a second holding an array of subscript names. The second variable is always going to be an array since there may be more than one subscript (multidimensional arrays). To retrieve to array value, the subscripts array is to be looped through to get each subscript. For example:

$theme_mod_defaults = array(
   'body_bg_color' => '#fff',
   'body_text_color' => 'black'
   'font' => array(
      'font-familiy' => 'Arial',
      'font-size' => 14
   )
);

function my_dynamic_css_callback( $var_name, $subscripts = null )
{
   $val = get_theme_mod($var_name, @$theme_mod_defaults[$var_name]);
   if( null !== $subscripts )
   {
      foreach( $subscripts as $subscript )
      {
          $val = $val[$subscript];
      }
   }
   return $val;
}
wp_dynamic_css_set_callback( 'my_dynamic_style', 'my_dynamic_css_callback' );

which compiles to:

body {
   background-color: #fff;
   color: black;
   font: 14px 'Arial';
}

Registering Filters

Filters are functions the alter the value of the variables. Filters can be registered using the function wp_dynamic_css_register_filter( $handle, $filter_name, $callback ). A registered filter can only be used within the stylesheet whose handle is given. A filter callback function takes the value of the variable as a parameter and should return the filtered value. For example:

function my_filter_callback( $value ) 
{
   return trim( $value );
}
wp_dynamic_css_register_filter( 'my_dynamic_style', 'myFilter', 'my_filter_callback' );

The filter can then be applied using the | operator. For example:

body {
   font-family: $myVar|myFilter;
}

Filters can also take additional arguments. For example:

function my_filter_callback( $value, $arg1, $arg2 ) 
{
   return $value.$arg1.$arg2;
}
wp_dynamic_css_register_filter( 'my_dynamic_style', 'myFilter', 'my_filter_callback' );

To pass addidional arguments, use braces () and separate each argument with a comma (no spaces are allowd). For example:

body {
   font-family: $myVar|myFilter(',arial',',sans-serif');
}

Accepted argument types are strings, integers, floats and boolean values. Strings must have single quotes around them. For exmaple:

body {
   font-family: $myVar|myFilter(1,2,3,'4',5.6,true,false);
}

API Reference

wp_dynamic_css_enqueue

Enqueue a dynamic stylesheet

function wp_dynamic_css_enqueue( $handle, $path, $print = true, $minify = false, $cache = false )

This function will either print the compiled version of the stylesheet to the document's section, or load it as an external stylesheet if $print is set to false. If $cache is set to true, a compiled version of the stylesheet will be stored in the database as soon as it is first compiled. The compiled version will be served thereafter until wp_dynamic_css_clear_cache() is called.

Parameters

  • $handle (string) The stylesheet's name/id
  • $path (string) The absolute path to the dynamic CSS file
  • $print (boolean) Whether to print the compiled CSS to the document head, or load it as an external CSS file via an http request
  • $minify (boolean) Whether to minify the CSS output
  • $cache (boolean) Whether to store the compiled version of this stylesheet in cache to avoid compilation on every page load.

wp_dynamic_css_set_callback

Set the value retrieval callback function

function wp_dynamic_css_set_callback( $handle, $callback )

Set a callback function that will be used to convert variables to actual values. The registered function will be used when the dynamic CSS file that is associated with the name in $handle is compiled. The callback function is passed the name of the variable as its first parameter (without the $), and the variable subscripts as its second parameter (if applicable). The callback function should return the variable's actual value.

Parameters

  • $handle (string) The name of the stylesheet to be associated with this callback function.
  • $callback (callable) The value retrieval callback function.

wp_dynamic_css_clear_cache

Clear the cached compiled CSS for the given handle.

function wp_dynamic_css_clear_cache( $handle )

Registered dynamic stylesheets that have the $cache flag set to true are compiled only once and then stored in cache. Subsequesnt requests are served statically from cache until wp_dynamic_css_clear_cache() is called and clears it, forcing the compiler to recompile the CSS.

Parameters

  • $handle (string) The name of the stylesheet to be cleared from cache.

wp_dynamic_css_register_filter

Register a filter function for a given stylesheet handle.

function wp_dynamic_css_register_filter( $handle, $filter_name, $callback )

A registered filter can be used to alter the value of a variable by using the | operator in the stylesheet. The callback function is passed the variable's value as its first argument, and any additional arguments thereafter.

Parameters

  • $handle (string) The handle of the stylesheet in which this filter is to be used.
  • $filter_name (string) The name of the filter to be used in the dynamic CSS file.
  • $callback (callable) The actual filter function. Accepts the variable's value as the first argument. Should return the filtered value.

wp-dynamic-css's People

Contributors

scrutinizer-auto-fixer avatar seothemes avatar ykadosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wp-dynamic-css's Issues

Ordering of style blocks

Hi,

Couldn't see any way of ordering the style blocks. Would be a useful addition as styles can come from both plugins & themes. And if they both use this lib then getting them to play nicely can be awkward - order of styles being important.

Is their a mechanism for this that I've missed? If not, I may consider submitting a PR if you take them?

Finally - great lib - really simple, effective & works just how you'd want - thanks for sharing it ๐Ÿ‘

Minify

Great library for my projects, I test today. Otherwise it is possible add in near future insert an option to minify the external css output?

Cache compiled CSS to improve performance

Since dynamic CSS files tend to get long and complex, and the variables only rarely change, it makes sense to store the compiled CSS in cache and serve it statically.

Additionally, I intend to add more features to the dynamic CSS syntax which will make it more computationally intensive.

Question: Possible for css variables to work with capital letters and/or dashes?

Hi.

Thanks for this REPO.

Is it possible for the css variables to work with capital letters and/or dashes?

I'm not sure if this is a php thing of the var, your plugin or the framework I am working with, but I figured I would ask here first as a starting point.

I've seen many authors' coding, maybe as a rule of thumb or best practice that they use underscores and lowercase letters, but I couldn't find anywhere online to backup that theory. So still being new to php, I'm not sure the rule, restriction or expectation here.

I have a nice work flow for my option values, but that includes capital letter and dashes. Capital letters have been omitted as of now, but these 2 things don't work with the dynamic css variables.

My theme option values may look something like...

// heading-variable-font_value
// heading-variable-color_value
// heading-variable-unit_amount_value
// heading-variable-unit_type_value
// heading-variable-line_height_value
// heading-variable-text_rendering_value

This allows my workflow to be faster because I can easily double click to copy and paste any text between a dash, like the "variable" above for example. And any text with underscores I can double click to copy as well. So in this case above I can easily just replace the variable for each similar option like...

// heading-1-font_value
// heading-1-color_value
// heading-1-unit_amount_value
// heading-1-unit_type_value
// heading-1-line_height_value
// heading-1-text_rendering_value
// heading-2-font_value
// heading-2-color_value
// heading-2-unit_amount_value
// heading-2-unit_type_value
// heading-2-line_height_value
// heading-2-text_rendering_value

And so on...

Can this be done? If so would you tell me how to tweak it so?

Fallbacks and Conditional Css Tags

@ykadosh

Thoughts on this? I was just thinking it over and looking at the css and there is no fallback or conditional tags. So looking forward it seems a little problematic at the moment to use WP Dynamic Css on a greater scale.

For example...

/*
Examples...
*/

/* Default H1 Setting */

h1 {
    color: $default_font_color;
}

/* Single Post H1 Setting */
/* (if this is NOT set, how to fallback to the above default setting?) */

h1 {
    color: $post_font_color;
}

/* Single Post H1 Setting */
/* (if a post setting is NOT set AND no default settings are set how to return a default value? Or return nothing and empty the line of css?) */

h1 {
    color: $post_font_color;
}

/* If the above is not set then the below will print */
h1 {
    color: ;
}

I had some ideas and tried to make it simple. I think it should operate like php, so I was thinking something like this to make my point... and used HTML syntax since it would likely be familiar and a little easy on the eyes when writing the css.

/*
Examples...
*/

/* Default H1 Setting */

h1 {
    color: <iftrue>$post_font_color</><else>$default_font_color</>;
}
h1 {
    color: <iftrue>$post_font_color</><elseif>$default_font_color</><else>#555</>;
}

Any ideas or feedback? How to go about this?

I only see one way which is to use php to find the option value then load the css file based on that value, but this can end up including a lot more css files than needed or user friendly.

My thoughts example...

If $post_font_color is true then...

wp_dynamic_css_enqueue('user-generated-styles', '/post-font-color.css');

If $post_font_color is false then...

wp_dynamic_css_enqueue('user-generated-styles', '/default-font-color.css');

But you can probably see how that can quickly become a lot of little css files when using multiple css properties for one css heading and others.

Print = false doesn't output the css

Hi there,

A great plugin. I just have an issue. I'm not getting any css output when I change print to false:

request:
wp-admin/admin-ajax.php?action=wp_dynamic_css&handle=my_dynamic_style&ver=5.7.2

/**

when print is true then the css shows in the head so I'm pretty sure I've got the correct variable names.

Any help appreciated.

$print = false doesn't work ??

Hi.

I meant to say this. In testing, I could never get this to work, neither with the latest update.

I don't think I will be using it at all, but never the less I wanted to let you know.

So for example...

This works...

wp_dynamic_css_enqueue('user-generated-styles', '/my-path/css-user-generated.css');

and this doesn't output anything...

wp_dynamic_css_enqueue('user-generated-styles', '/my-path/css-user-generated.css', false);

Does it work for you?

If so, maybe you can give me something to look into as to why it may not work with my setup?

I'm in localhost using a custom theme, but other than than I only have a couple dev plugins that are not the issue.

Add support for piped filters to the dynamic CSS syntax

Add support for filter functions to be called using the | (pipe) operator. In the dynamic CSS syntax, it will look something like:

body {
    color: $color|myFilter
}

Registering custom filters will be done like so:

function my_custom_filter_callback( $value ) {
    return $value;
}
wp_dynamic_css_register_filter( 'myFilter', 'my_custom_filter_callback' );

wp-dynamic-css gets overridden by styles generated from wp_enqueue_style

Here's my code on function.php.
``
function add_theme_styles() {
$turi = get_template_directory_uri();
wp_enqueue_style('font-awesome',$turi . '/css/font-awesome.min.css');
wp_enqueue_style('bootstrap',$turi .'/css/bootstrap.css');
wp_enqueue_style('star-rating',$turi .'/css/star-rating.min.css');
wp_enqueue_style('slick',$turi .'/css/slick.css');
wp_enqueue_style('ie10',$turi .'/css/ie10-viewport-bug-workaround.css');
wp_enqueue_style('sitestyle',$turi .'/css/sitestyle.css');
}
add_action( 'wp_print_styles', 'add_theme_styles');
wp_dynamic_css_enqueue( 'site_theme', get_template_directory_uri() . '/css/sitetheme.css', true, true);

It is generated from this order. 
 <style id="wp-dynamic-css"> .... </style>
<link rel='stylesheet' id='dashicons-css'  ... />
<link rel='stylesheet' id='admin-bar-css' .../>
<link rel='stylesheet' id='font-awesome-css' ... />
<link rel='stylesheet' id='bootstrap-css'  .../>
<link rel='stylesheet' id='star-rating-css' ... />
<link rel='stylesheet' id='slick-css' ... />
<link rel='stylesheet' id='ie10-css' .../>
<link rel='stylesheet' id='sitestyle-css' .../>

Setting add_action's priority does not work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.