Compile a referenced LESS file into CSS with PHP automatically
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
andmain.less.cache
should now exist in the same directory as your LESS fileThe last modified dates shouldn’t change unless you update your LESS file
Compiling Less CSS for Bootstrap 3 with PHP
AFAIK http://leafo.net/lessphp/ is not compatible with Boostrap 3 > 3.0.0, see https://github.com/leafo/lessphp/issues/503
http://lessphp.gpeasy.com/ works for me i have successful used it for JBST (https://github.com/bassjobsen/jamedo-bootstrap-start-theme/issues/82) i didn't use the cache function.
Without caching you can call $parser->parseFile()
for every file you include, it will compile to one file. array(/var/www/mysite/bootstrap.less' => '/mysite/');
. Use an array of array's for multiple files: array(array(/var/www/mysite/bootstrap.less' => '/mysite/'), array(/var/www/mysite/.less' => '/mysite/'));
<?php
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' );
$parser->parseFile( '/var/www/mysite/mainless.css', 'http://example.com/mysite/' );
$css = $parser->getCss();
Less_Cache::Get seems to work for only one file a time.
update As commented by @user697576 Less_Cache::Get()
accepts a single file or a list (array of files). A single file will be array like array(/var/www/mysite/bootstrap.less' => '/mysite/');
From the docs:
Use the Less_Cache class to save and reuse the results of compiled
less files. This method we check the modified time of each less file
(including imported files) and regenerate when changes are found.
I highlight including imported files cause this seems to solve your problem. Merge your files with LESS:
styles.less:
@import "my.less";
@import "mainless.css";
And compile styles.less only.
/var/www/mysite/bootstrap.less - Is this the less file to be compiled?
Yes, why not? Make sure the files imported in bootstrap.less are available in the same directory as bootstrap.less, or use $parser->SetImportDirs()
to set the right path.
/mysite/ - what is this for??
It setting the right path. If you LESS file contain for example url(image.png)
it outputs url( /mysite/image.png)
. Note Bootstrap use ../ for the path of the glyphicons, this won't be corrected or even worse become /mysite/../. You will have to set this path in LESS: @icon-font-path: "/mysite/fonts/";
/var/www/writable_folder - Is this wherethe css is written to?
Nope after $compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
$compiled
contains the (compiled) CSS you have to write this to a file. Or use: $css_file_name = Less_Cache::Get( $to_cache ); in your HTML:
<link rel="stylesheet" type="text/css" href="/writable_folder/<?php echo $css_file_name;?>">
update
Notice that since Bootstrap 3.2.0. prefixing of the properties in Bootstrap is be done by the autoprefixer in the build process. The preceding means that the Bootstrap Less code code contain property declaration which only use the W3C syntax whilst prefixing is required for cross browser support. Compiling your source with less.php does not run the autoprefixer. See also: https://github.com/oyejorge/less.php/issues/158
LESS compiler for PHP
Here's the answer:
https://github.com/leafo/lessphp
There's no other way for the moment.
How to use/compile LESS for Bootstrap?
You could try using lessphp.
A simple setup to compile the principle Bootstrap LESS files would be:
<?php
require "lessc.inc.php";
$less = new lessc;
$less->checkedCompile("bootstrap.less", "bootstrap.css");
$less->checkedCompile("bootstrap-responsive.less", "bootstrap-responsive.css");
How can I execute the LESS compiler from PHP (using Symfony)?
You can make a shell script that compiles things the way you want:
compile_css.sh
/Users/jordanb/node/node_modules/less/bin/lessc less/bootstrap.less css/bootstrap.css
Then
chmod +x compile_css.sh
And finally call it from your script
$command = '/path/to/compile_css.sh';
This will give you more control over what you can execute, but if you still want to do it from php, try this:
$command = '/Users/jordanb/node/node_modules/less/bin/lessc "less/bootstrap.less css/bootstrap.css"';
// note the quotes around the arguments.
LESS & automatic CSS cacheing
Less.js will already recompile if the source has changed -- I have never had an issue with it being stale during development. I did end up switching to a compile-on-save workflow using textmate's less bundle though wince switching out link tags before deployment and testing was getting annoying.
That being said I'm sure you could wire up something to watch the file on disk and invoke the node.js lessc compiler.
UPDATE TO CLARIFY DEV CYCLE:
During development I include the less.js file in the page and link to my styles.less
file via <link rel="stylesheet/less" type="text/css" href="styles.less>
When I push out to production I change that to:
<link rel="stylesheet" type="text/css" href="styles.css">
But, during development, every time I save the styles.less
file, I use a TextMate bundle to also compile down a styles.css
file, so the change out is a matter of commenting/uncommenting in my source file.
I have the bundle set to use node.js lessc compiler with --compress
set so it gives you a nice compact stylesheet.
Related Topics
In PHP, How to Detect the Execution Is from Cli Mode or Through Browser
What Is the Format for E-Mail Headers That Display a Name Rather Than the E-Mail
Guzzle: Handle 400 Bad Request
Error 403 in Loading Resources Like CSS and Js in My Index.Php
Looping Through All the Properties of Object PHP
How to Get the Newest File in a Directory in PHP
Is MySQL_Real_Escape_String() Necessary When Using Prepared Statements
How to Load CSS File in Codeigniter
How to Fix "Set Samesite Cookie to None" Warning
Apache Error [Notice] Parent: Child Process Exited with Status 3221225477 -- Restarting
999 Error Code on Head Request to Linkedin
Notice: Undefined Offset: 0 In
PHP Printed Boolean Value Is Empty, Why