Okey doke. What I wanted to do is make it so that we can use LESS files as well as CSS files, without messing around with compression, concatenation, parsing (for the LESS files), or minification each time I made a modification to the CSS or LESS. I have made a script that will take care of all that for me, with no configuration required.
<?php
//This function minifies the CSS and the final parsed LESS files, before it is written to cache.css
function minifyCSS($css) {
$css = trim($css);
$css = str_replace("\r\n", "\n", $css);
$search = array("/\/\*[^!][\d\D]*?\*\/|\t+/", "/\s+/", "/\}\s+/");
$replace = array(null, " ", "}\n");
$css = preg_replace($search, $replace, $css);
$search = array("/;[\s+]/", "/[\s+];/", "/\s+\{\\s+/", "/\\:\s+\\#/", "/,\s+/i", "/\\:\s+\\\'/i", "/\\:\s+([0-9]+|[A-F]+)/i", "/\{\\s+/", "/;}/");
$replace = array(";", ";", "{", ":#", ",", ":\'", ":$1", "{", "}");
$css = preg_replace($search, $replace, $css);
$css = str_replace("\n", null, $css);
return $css;
}
//this bit set up gzipping
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
ob_start("ob_gzhandler");
} else {
ob_start();
}
//$LESSfiles gets all the files with either .css or .less extentions
$LESSfiles = glob("{*.less,*.css}", GLOB_BRACE);
//$time is set to a really far back date, so when we check against it, it always is less that the file creation date.
$time = mktime(0, 0, 0, 21, 5, 1980);
//$cache == the name of the file we write all the finished css and less to. This is what the browser will see.
$cache = 'cache.css';
//here we are checking each file against $time. For each file we get from $LESSfiles, $fileTime is set to its modification date.
//Then we check $time against $fileTime, and only change $time if it is greater than $fileTime.
//This ensures that we only get the single latest modification date for all the files.
foreach ($LESSfiles as $file) {
$fileTime = filemtime($file);
if ($fileTime > $time) {
$time = $fileTime;
}
}
//This statement checks to make sure $cache exists. If it does exist, then it checks the $cache modification date against $time, which we set above.
//If $cacheTime is less than $time, we set $recache to "true". Otherwise, $recache is set to false.
//If the file doesn't exist, $recache is set to true.
//$recache lets the rest of the script know whether to rebuild the cache.css file or not.
if (file_exists($cache)) {
$cacheTime = filemtime($cache);
if ($cacheTime < $time) {
$time = $cacheTime;
$recache = true;
} else {
$recache = false;
}
} else {
$recache = true;
}
//This part tells the browser whether or not it has a recent version of cache.css or not.
if (!$recache && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= strtotime($time)) {
header("HTTP/1.0 304 Not Modified");
exit();
} else {
header('Content-type: text/css');
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $time) . " GMT");
if ($recache) {
if (file_exists($cache)) {
unlink($cache);
}
require 'lessc.inc.php'; //here we make sure to include lessc.inc.php. This script won't work without it. You can get it from http://leafo.net/lessphp/docs/
$lc = new lessc(); //initialize lessc
$css = ''; //empty $css variable
foreach ($LESSfiles as $file) {//iterate through the $LESSfiles array
$css .= file_get_contents($file); //get the raw contents of each file, and add all of them into the $css variable
}
$css = $lc->parse($css); //parse the css and less contents. LESS is compatible with css syntax.
$minified = minifyCSS($css); //we call the function that we made above (at the top of this document) and minify the pure css.
file_put_contents($cache, $minified); //put minified css into our cache.css file.
echo $minified; //echo the raw variable if we just did a recache, otherwise
} else {
readfile($cache); //we simply tell the browser to read the cached cache.css file
}
}
?>
Just paste this into a file called styles.php, and simply drop it into your directory that has your CSS or LESS (or both) files in it. Make sure you have lessc.inc.php in there as well! (required). You can get lessphp at http://leafo.net/lessphp/docs/
Link to it in your header like this (I am using a directory in the root of my theme folder called "less"):
echo '<link rel="stylesheet" type="text/css" href="' . $this->getThemePath(); . '/less/styles.php" media="screen, projection" />';
To order the css and less files so they are included in the correct order (like for a reset.css), just append a number to the file, like 1screen.less, 2main.less, 3typography.less, 4interface.css, etc...
Also, I figured out that tinyMCE doesn't actually need typography.css to be included in the header in order to use it. It just needs to be in the theme root. So you can combine your typography.css/less into one file with everything else, and just set a custom typography.css in your theme root. You don't really even need styles in it. It will grab any classes in there even if they are blank (.button{}.caps{}) and add them to the drop down selector. You can then define those classes in your typography.less file that is now combined into the rest of the css.
That will remove one more http request from your header. :-)
NOTE: If you delete one of the files, the script won't know it, because it only checks the modified date. If you decide to delete a file from the folder after it has already built the cache.css file, simply delete cache.css and the script will rebuild it with the correct files.
I hope this is useful to someone! :-D
EDIT: Make sure you visit the styles.php in your browser and be sure you don't have any errors being written to the output (they won't show up in the browser, only in the styles.php output). Or you can just check to make sure it is actually generating a cache.css file. I recently had an issue on a live server where styles.php couldn't write to the LESS folder, and it was working, but since it couldn't find the cache.css file to check against, it had to recompile the css every time someone visited the page. This adds quite a bit of overhead (~300ms more).
To fix this, I simply had to chmod the LESS folder so that styles.php could write to it. Try to get the least liberal permissions settings to work. To chmod in cpanel just right click on the LESS folder, and select permissions. Then you can work with it to get it working. I used 777 settings on my particular server, but 755 is safer.