<coded>


Create Wordpress auto compress function for your CSS and JavaScript

August 13, 2022

This can become very useful if you run a staging environment beside your live page. You might have compressed CSS and JavaScript on your live page but still work with raw files and develop on the staging site.

The easiest way to achive this is to wrap a new function around wp_enqueue_style() and wp_enqueue_script() and load the minified files only on the live site.

Requirements

1. Include CSS and JS compression libs

Copy both PHP files to your theme directory, then open your functions.php in your Wordpress and add these lines at the top:

require get_stylesheet_directory() . '/php-html-css-js-minifier.php';
require get_stylesheet_directory() . '/Minifier.php';

2. Define a constant for dev or live mode

This will later tell your function whether to compress files or not (true = compress, false = dont compress):

define("DEV_MODE", true);

3. Creating the function

Like said before we will not use wp_enqueue_style() and wp_enqueue_script() on it's own, when finished we will use wp_auto_compress() function to embed our css and js. So let's wrap up the basic structure:

<?php
function wp_auto_compress($name, $path, $normfile, $minfile, $type, $args) {
    $the_theme = wp_get_theme();
    $md5 = md5(date("YmdHis"));

    $n_file = get_stylesheet_directory().$path.$normfile;
    $m_file = get_stylesheet_directory().$path."min/".$minfile;

    if($type == "css") {
        ...
    }
    elseif($type == "js") {
        ...
    }
}

As you can see we have a few arguments. Most things should be pretty self explaining here, like $name and $path. With $type we just define if the file is css or js to pick the correct minifier script. Optional you can give extra $args like on the original Wordpress functions.

We will store all minified files in an extra subfolder called "min".

4. Let's do the minifying

But we only want this if our source file is newer than our compression file, means if we made changes in the source file we want to auto update the min file too. We can easily achive this by using filemtime function on the two files and compare them.

<?php
function wp_auto_compress($name, $path, $normfile, $minfile, $type, $args) {
    $the_theme = wp_get_theme();
    $md5 = md5(date("YmdHis"));

    $n_file = get_stylesheet_directory().$path.$normfile;
    $m_file = get_stylesheet_directory().$path."min/".$minfile;

    if(filemtime($n_file) > filemtime($m_file) || !file_exists($m_file)) {
        if($type === "css") {
            $output = minify_css(file_get_contents($n_file));
        }
        elseif($type === "js") {
            $output = \JShrink\Minifier::minify(file_get_contents($n_file));
        }

        file_put_contents($m_file, $output);
    }

    if($type === "css") {
        ...
    }
    elseif($type === "js") {
        ...
    }
}

5. Load files based on dev or live setting

We are nearly finished, but the last step will be to load minified files only needed. You will notice the $md5 variable maybe, it's just a little workaround to 100% prevent caching of files. It will create a simple md5 string of the current timestamp and add it to the filename, so make it unique everytime you load your page.

<?php
function wp_auto_compress($name, $path, $normfile, $minfile, $type, $args) {
    $the_theme = wp_get_theme();
    $md5 = md5(date("YmdHis"));

    $n_file = get_stylesheet_directory().$path.$normfile;
    $m_file = get_stylesheet_directory().$path."min/".$minfile;

    if(filemtime($n_file) > filemtime($m_file) || !file_exists($m_file)) {
        if($type === "css") {
            $output = minify_css(file_get_contents($n_file));
        }
        elseif($type === "js") {
            $output = \JShrink\Minifier::minify(file_get_contents($n_file));
        }

        file_put_contents($m_file, $output);
    }

    if($type === "css") {
        if(DEV_MODE) {
            wp_enqueue_style($name, get_stylesheet_directory_uri().$path.$normfile."?".$md5, array(), $the_theme->get("Version"), $args);
        }
        else {
            wp_enqueue_style($name, get_stylesheet_directory_uri().$path."min/".$minfile, array(), $the_theme->get("Version"), $args);
        }
    }
    elseif($type === "js") {
        if(DEV_MODE) {
            wp_enqueue_script($name, get_stylesheet_directory_uri().$path.$normfile."?".$md5, array(), $the_theme->get("Version"), $args);
        }
        else {
            wp_enqueue_script($name, get_stylesheet_directory_uri().$path."min/".$minfile, array(), $the_theme->get("Version"), $args);
        }
    }
}

6. Example Script

Here you have a little example for the functions.php on how to use it correctly on your Wordpress.

Show example script

Did you find this useful? Please rate this post: