1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
[![Build Status](https://github.com/wikimedia/less.php/actions/workflows/php.yml/badge.svg)](https://github.com/wikimedia/less.php/actions)
Less.php
========
This is a PHP port of the [official LESS processor](https://lesscss.org).
* [About](#about)
* [Installation](#installation)
* [Security](#%EF%B8%8F-security)
* [Basic Use](#basic-use)
* [Caching](#caching)
* [Source Maps](#source-maps)
* [Command Line](#command-line)
* [Integration with other projects](#integration-with-other-projects)
* [Transitioning from Leafo/lessphp](#transitioning-from-leafolessphp)
* [Credits](#credits)
About
---
The code structure of Less.php mirrors that of the official processor which helps us ensure compatibility and allows for easy maintenance.
Please note, there are a few unsupported LESS features:
- Evaluation of JavaScript expressions within back-ticks (for obvious reasons).
- Definition of custom functions.
Installation
---
You can install the library with Composer or manually.
#### Composer
1. [Install Composer](https://getcomposer.org/download/)
2. Run `composer require wikimedia/less.php`
#### Manually from release
1. [Download a release](https://github.com/wikimedia/less.php/releases) and upload the PHP files to your server.
2. Include the library:
```php
require_once '[path to less.php]/lib/Less/Autoloader.php';
Less_Autoloader::register();
```
⚠️ Security
---
The LESS processor language is powerful and including features that can read or embed arbitrary files that the web server has access to, and features that may be computationally exensive if misused.
In general you should treat LESS files as being in the same trust domain as other server-side executables, such as Node.js or PHP code. In particular, it is not recommended to allow people that use your web service to provide arbitrary LESS code for server-side processing.
_See also [SECURITY](./SECURITY.md)._
Basic Use
---
#### Parsing strings
```php
$parser = new Less_Parser();
$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
$css = $parser->getCss();
```
#### Parsing LESS files
The parseFile() function takes two arguments:
1. The absolute path of the .less file to be parsed
2. The url root to prepend to any relative image or @import urls in the .less file.
```php
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', 'https://example.org/mysite/' );
$css = $parser->getCss();
```
#### Handling invalid LESS
An exception will be thrown if the compiler encounters invalid LESS.
```php
try{
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', 'https://example.org/mysite/' );
$css = $parser->getCss();
}catch(Exception $e){
$error_message = $e->getMessage();
}
```
#### Parsing multiple sources
Less.php can parse multiple sources to generate a single CSS file.
```php
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
$css = $parser->getCss();
```
#### Getting info about the parsed files
Less.php can tell you which `.less` files were imported and parsed.
```php
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$css = $parser->getCss();
$imported_files = $parser->allParsedFiles();
```
#### Compressing output
You can tell Less.php to remove comments and whitespace to generate minimized CSS files.
```php
$options = [ 'compress' => true ];
$parser = new Less_Parser( $options );
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$css = $parser->getCss();
```
#### Getting variables
You can use the `getVariables()` method to get an all variables defined and
their value in a php associative array. Note that LESS has to be previously
compiled.
```php
$parser = new Less_Parser;
$parser->parseFile( '/var/www/mysite/bootstrap.less');
$css = $parser->getCss();
$variables = $parser->getVariables();
```
#### Setting variables
You can use the `ModifyVars()` method to customize your CSS if you have variables stored in PHP associative arrays.
```php
$parser = new Less_Parser();
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$parser->ModifyVars( [ 'font-size-base' => '16px' ] );
$css = $parser->getCss();
```
#### Import directories
By default, Less.php will look for imported files in the directory of the file passed to `parseFile()`.
If you're using `parse()`, or if import files reside in a different directory, you can tell Less.php where to look.
```php
$directories = [ '/var/www/mysite/bootstrap/' => '/mysite/bootstrap/' ];
$parser = new Less_Parser();
$parser->SetImportDirs( $directories );
$parser->parseFile( '/var/www/mysite/theme.less', '/mysite/' );
$css = $parser->getCss();
```
Caching
---
Compiling LESS code into CSS is a time-consuming process, caching your results is highly recommended.
#### Caching CSS
Use the `Less_Cache` class to save and reuse the results of compiled LESS files.
This class will check the modified time and size of each LESS file (including imported files) and regenerate a new CSS file when changes are found.
Note: When changes are found, this method will return a different file name for the new cached content.
```php
$less_files = [ '/var/www/mysite/bootstrap.less' => '/mysite/' ];
$options = [ 'cache_dir' => '/var/www/writable_folder' ];
$css_file_name = Less_Cache::Get( $less_files, $options );
$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
```
#### Caching CSS with variables
Passing options to `Less_Cache::Get()`:
```php
$less_files = [ '/var/www/mysite/bootstrap.less' => '/mysite/' ];
$options = [ 'cache_dir' => '/var/www/writable_folder' ];
$variables = [ 'width' => '100px' ];
$css_file_name = Less_Cache::Get( $less_files, $options, $variables );
$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
```
#### Parser caching
Less.php will save serialized parser data for each `.less` file if a writable folder is passed to the `SetCacheDir()` method.
Note: This feature only caches intermediate parsing results to improve the performance of repeated CSS generation.
Your application should cache any CSS generated by Less.php.
```php
$options = [ 'cache_dir'=>'/var/www/writable_folder' ];
$parser = new Less_Parser( $options );
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$css = $parser->getCss();
```
You can specify the caching technique used by changing the `cache_method` option. Supported methods are:
* `php`: Creates valid PHP files which can be included without any changes (default method).
* `var_export`: Like "php", but using PHP's `var_export()` function without any optimizations.
It's recommended to use "php" instead.
* `serialize`: Faster, but pretty memory-intense.
* `callback`: Use custom callback functions to implement your own caching method. Give the "cache_callback_get" and
"cache_callback_set" options with callables (see PHP's `call_user_func()` and `is_callable()` functions). Less.php
will pass the parser object (class `Less_Parser`), the path to the parsed .less file ("/some/path/to/file.less") and
an identifier that will change every time the .less file is modified. The `get` callback must return the ruleset
(an array with `Less_Tree` objects) provided as fourth parameter of the `set` callback. If something goes wrong,
return `NULL` (cache doesn't exist) or `FALSE`.
Source maps
---
Less.php supports v3 sourcemaps.
#### Inline
The sourcemap will be appended to the generated CSS file.
```php
$options = [ 'sourceMap' => true ];
$parser = new Less_Parser($options);
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$css = $parser->getCss();
```
#### Saving to map file
```php
$options = [
'sourceMap' => true,
'sourceMapWriteTo' => '/var/www/mysite/writable_folder/filename.map',
'sourceMapURL' => '/mysite/writable_folder/filename.map',
];
$parser = new Less_Parser($options);
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
$css = $parser->getCss();
```
Command line
---
An additional script has been included to use the compiler from the command line.
In the simplest invocation, you specify an input file and the compiled CSS is written to standard out:
```
$ lessc input.less > output.css
```
By using the `-w` flag you can watch a specified input file and have it compile as needed to the output file:
```
$ lessc -w input.less output.css
```
Errors from watch mode are written to standard out.
For more help, run `lessc --help`
Integration with other projects
---
#### Drupal 7
This library can be used as drop-in replacement of lessphp to work with [Drupal 7 less module](https://drupal.org/project/less).
How to install:
1. [Download the Less.php source code](https://github.com/wikimedia/less.php/archive/main.zip) and unzip it so that 'lessc.inc.php' is located at 'sites/all/libraries/lessphp/lessc.inc.php'.
2. Download and install [Drupal 7 less module](https://drupal.org/project/less) as usual.
3. That's it :)
#### JBST WordPress theme
JBST has a built-in LESS compiler based on lessphp. Customize your WordPress theme with LESS.
How to use / install:
1. [Download the latest release](https://github.com/bassjobsen/jamedo-bootstrap-start-theme) copy the files to your {wordpress/}wp-content/themes folder and activate it.
2. Find the compiler under Appearance > LESS Compiler in your WordPress dashboard
3. Enter your LESS code in the text area and press (re)compile
Use the built-in compiler to:
- set any [Bootstrap](https://getbootstrap.com/docs/3.4/customize/) variable or use Bootstrap's mixins:
- `@navbar-default-color: blue;`
- create a custom button: `.btn-custom {
.button-variant(white; red; blue);
}`
- set any built-in LESS variable: for example `@footer_bg_color: black;` sets the background color of the footer to black
- use built-in mixins: - add a custom font: `.include-custom-font(@family: arial,@font-path, @path: @custom-font-dir, @weight: normal, @style: normal);`
The compiler can also be downloaded as [plugin](https://wordpress.org/plugins/wp-less-to-css/)
#### WordPress
This simple plugin will simply make the library available to other plugins and themes and can be used as a dependency using the [TGM Library](http://tgmpluginactivation.com/)
How to install:
1. Install the plugin from your WordPress Dashboard: https://wordpress.org/plugins/lessphp/
2. That's it :)
Transitioning from Leafo/lessphp
---
Projects looking for an easy transition from leafo/lessphp can use the lessc.inc.php adapter. To use, [Download the Less.php source code](https://github.com/wikimedia/less.php/archive/main.zip) and unzip the files into your project so that the new `lessc.inc.php` replaces the existing `lessc.inc.php`.
Note, the `setPreserveComments` will no longer have any effect on the compiled LESS.
Credits
---
Less.php was originally ported to PHP in 2011 by [Matt Agar](https://github.com/agar) and then updated by [Martin Jantošovič](https://github.com/Mordred) in 2012. From 2013 to 2017, [Josh Schmidt](https://github.com/oyejorge) lead development of the library. Since 2019, the library is maintained by Wikimedia.
|