Compile a referenced LESS file into CSS with PHP automatically
caching, compiler-construction, css, less, php
Solution
THIS ASSUMES LESSPHP v0.3.8+ Unsure about earlier versions, but you'll get the gist of how it works if it doesn't straight out of the box.
`<link rel="stylesheet" type="text/css" href="styles/main.less" />`
If you were using less.js to compile client side, make sure you change `rel="stylesheet/less"` to `rel="stylesheet"`
1) Grab Lessphp I placed these files in `/www/compilers/lessphp/` for the context of this demo
2) Make a PHP script that we can throw out LESS files at. This will deal with caching, compiling to CSS and returning the CSS as a response. I have placed this file at `/www/compilers/` and called it `lessphp.php`
Most of this code was on the Lessphp site, except there were errors in it, and I have added the response at the end.
<?php
require "lessphp/lessc.inc.php";
$file = $_GET["file"];
function autoCompileLess($inputFile, $outputFile) {
// load the cache
$cacheFile = $inputFile.".cache";
if (file_exists($cacheFile)) {
$cache = unserialize(file_get_contents($cacheFile));
} else {
$cache = $inputFile;
}
$less = new lessc;
$less->setFormatter("compressed");
$newCache = $less->cachedCompile($cache);
if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) {
file_put_contents($cacheFile, serialize($newCache));
file_put_contents($outputFile, $newCache['compiled']);
}
}
autoCompileLess('../' . $file, '../' . $file . '.css');
header('Content-type: text/css');
readfile('../' . $file . '.css');
?>
This will compile the LESS file (eg, `styles/main.less`) to a cache file and a CSS file (eg, `styles/main.less.css`).
3) Add a `mod_rewrite` rule so that any LESS files a user requests are redirected to our compiler, giving it its path. This was placed in the root `.htaccess` file.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^([^.]*\.less)$ compilers/lessphp.php?file=$1 [R,QSA,L]
</ifModule>
If you are using WordPress, this rule will need to come after it - even if WordPress is in a sub directory, it seems to overwrite these rules, and LESS compilation will not occur for referenced files which exist below (directory wise) WordPress's `.htaccess` rules.
4) Your LESS code should be relatively referenced in relation to the compilers location. Additionally, Lessphp compiler will fail if there are empty attributes, eg. `background-color: ;`
If all is working well, the following should occur:
Directly browse your LESS file `http://domain.com/styles/main.less`
Be automatically redirected to `http://domain.com/compilers/lessphp?file=styles/main.less`
Be presented with minified CSS
`main.less.css` and `main.less.cache` should now exist in the same directory as your LESS file
The last modified dates shouldn’t change unless you update your LESS file
Problem
I want the following things to occur: Have the process automated server side. Simply be able to reference the LESS file as I would a CSS file in my code. The user is returned minified CSS instead of the LESS file - cached so the compiler doesn't need to run unless the LESS file has been updated. For this to work with any LESS file that is referenced anywhere within my domain. I spotted Lessphp, but the documentation isn't very clear, nor does it explain how to dynamically get any LESS file to it. I thought I would post up how I got it all working as I haven't seen a run through on how to achieve this with PHP.