On part of a project, I have some CSS being read using twig's source()
function.
But sending a huge chunk of CSS is not optimal.
To reduce the size of the HTML, I've written this twig filter.
However, I've noticed that some big files would take a bit more to be minimified.
To reduce the time to re-minify the CSS, I've added a crude caching system.
Assuming that you have the following:
$twig = new Twig_Environment(new Twig_Loader_Filesystem( ... ), array( ... ));
You have the following code:
$twig->addFilter(new Twig_SimpleFilter('minify_css', function($css, $cache = true){
$path = $_SERVER['DOCUMENT_ROOT'] . '/cache/minify_css/';
$min_length = 1024;
if(!is_dir($path))
{
mkdir($path, 0755, true);
}
$length = strlen($css);
$result = '';
if($cache && $length > $min_length && @is_file($file = $path . ($hash = md5($css)) . '.css' ))
{
$result = file_get_contents($file);
}
else if($length >= 9)
{
$result = preg_replace(
array(
'@/\*[^*]*\*+([^/][^*]*\*+)*\/@', // /*abc*/ ->
'@([\-;\{]\w*)\s*:\s*@', //a : b -> a:b
'@\s*;\s*\}\s*@', //a:b ; } -> a:b}
'@\s*\{\s*@', // a { b:c} -> a{b:c}
'@\s*!important\s*@i', // a:b !important } -> a:b!important}
'@([,;}!:]|^)\s*0+\s*px@i', // a: 0px -> a:0
'@([,;:!.>~\+=\[\{\}\(]|^)[\s\r\n]+@', // a, b -> a,b
'@[\s\r\n]+([,;!>~\+=\]\{\}\)]|$)@', // a ,b -> a,b
'@([,:\( ])\s*#([\da-f])\2([\da-f])\3([\da-f])\4@i' // a: #FF00CC -> a:#F0C
),
array(
'',
'$1:',
'}',
'{',
'!important',
'${1}0',
'$1',
'$1',
'$1#$2$3$4'
),
str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css)
);
if($cache && $length > $min_length)
{
file_put_contents($file, $result);
}
}
return $result;
}), array('is_safe' => array('html', 'css', 'js'))
);
This filter takes 1 parameter, to indicate if there's or not caching, and returns the minified CSS when applicable.
An example of it's usage:
{% for file in css_files %}
<style>{{ source('assets/css/' ~ file ~ '.css') | minify_css }}</style>
{% endfor %}
This assumes that the template has access to the variable css_files
, containing the name of those files.
What else can I improve here?
Any speed improvements or readability improvements?