From 9ac2e741eca3f6a4e081ccb7afdaa3f3627f003d Mon Sep 17 00:00:00 2001 From: David Sferruzza Date: Fri, 29 Nov 2013 00:14:11 +0100 Subject: [PATCH] Add loader system for @import --- docs/docs.md | 24 ++++++++++++++++++++++++ lessc.inc.php | 29 +++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/docs/docs.md b/docs/docs.md index 797b0f1a..f88c2b0d 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -1003,6 +1003,8 @@ Methods: * [`addImportDir($dir)`](#import_directory) -- Append directory to search path for imports +* [`setLoader($callback)`](#loader) -- Register a callback use to fetch imported files + ### Compiling @@ -1277,6 +1279,28 @@ overwriting the whole thing. $less->addImportDir("public/stylesheets"); ``` +### Loader + +It is possible to register a callback that will be called to fetch imported files (using `@import`). +This can be useful when LESS files are not in a directory on the filesystem. + +The callback takes one parameter, which is the name of the file (as specified in the `@import` directive). + +It will return either `false` or a string of LESS code to be parsed. +If it returns `false`, the `@import` directive will stay. + + ```php + $less->loader(function($name) { + // Use $name to do whatever you want to fetch your LESS code + + // return $content; <- will use the $content you just fetched + // return false; <- will let the `@import` directive untouched + // return ''; <- will import nothing and remove the `@import` directive + }); + ``` + +If no callback is registered, the `@import` directives will be resolved using the classic behaviour (see **Import Directory**). + ### Custom Functions **lessphp** has a simple extension interface where you can implement user diff --git a/lessc.inc.php b/lessc.inc.php index 6ad6c649..ba26e880 100644 --- a/lessc.inc.php +++ b/lessc.inc.php @@ -54,6 +54,8 @@ class lessc { public $importDisabled = false; public $importDir = ''; + public $loader = null; + protected $numberPrecision = null; protected $allParsedFiles = array(); @@ -90,6 +92,10 @@ static public function preg_quote($what) { return preg_quote($what, '/'); } + public function setLoader($callback) { + $this->loader = $callback; + } + protected function tryImport($importPath, $parentBlock, $out) { if ($importPath[0] == "function" && $importPath[1] == "url") { $importPath = $this->flattenList($importPath[2]); @@ -100,13 +106,21 @@ protected function tryImport($importPath, $parentBlock, $out) { $url = $this->compileValue($this->lib_e($str)); - // don't import if it ends in css - if (substr_compare($url, '.css', -4, 4) === 0) return false; - - $realPath = $this->findImport($url); - - if ($realPath === null) return false; + if (is_callable($this->loader)) { + $realPath = $url; + $content = call_user_func($this->loader, $realPath); + if ($content === false) return false; + } + else { + // don't import if it ends in css + if (substr_compare($url, '.css', -4, 4) === 0) return false; + $realPath = $this->findImport($url); + if ($realPath === null) return false; + $content = file_get_contents($realPath); + $this->addParsedFile($realPath); + } + if ($this->importDisabled) { return array(false, "/* import disabled */"); } @@ -115,9 +129,8 @@ protected function tryImport($importPath, $parentBlock, $out) { return array(false, null); } - $this->addParsedFile($realPath); $parser = $this->makeParser($realPath); - $root = $parser->parse(file_get_contents($realPath)); + $root = $parser->parse($content); // set the parents of all the block props foreach ($root->props as $prop) {