From a05613f88a83c9320d1f990c018b1bce568e62a0 Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Thu, 1 Mar 2018 15:57:15 +0100 Subject: [PATCH 1/7] fix for empty extension avoid empty extension if inner asset is something like => http://fonts.googleapis.com/css?family=Abel --- src/Assetic/Factory/AssetFactory.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Assetic/Factory/AssetFactory.php b/src/Assetic/Factory/AssetFactory.php index e267196ae..2ed503584 100644 --- a/src/Assetic/Factory/AssetFactory.php +++ b/src/Assetic/Factory/AssetFactory.php @@ -196,7 +196,11 @@ public function createAsset($inputs = array(), $filters = array(), array $option $asset->add(call_user_func_array(array($this, 'createAsset'), $input)); } else { $asset->add($this->parseInput($input, $options)); - $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; + // avoid empty extension if inner asset is something like + // http://fonts.googleapis.com/css?family=Abel + if(pathinfo($input, PATHINFO_EXTENSION)!='') { + $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; + } } } From 2af4c22cc3bf2abd9d95a0a90565a722fe3cdff4 Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Thu, 10 Jan 2019 10:25:22 +0100 Subject: [PATCH 2/7] added proxy option; added filters for BlackCat CMS --- src/Assetic/Asset/HttpAssetWithProxy.php | 30 +++++ src/Assetic/Factory/AssetFactory.php | 23 +++- src/Assetic/Filter/CATCssRewriteFilter.php | 133 +++++++++++++++++++++ src/Assetic/Filter/CATSourcemapFilter.php | 46 +++++++ 4 files changed, 228 insertions(+), 4 deletions(-) create mode 100644 src/Assetic/Asset/HttpAssetWithProxy.php create mode 100644 src/Assetic/Filter/CATCssRewriteFilter.php create mode 100644 src/Assetic/Filter/CATSourcemapFilter.php diff --git a/src/Assetic/Asset/HttpAssetWithProxy.php b/src/Assetic/Asset/HttpAssetWithProxy.php new file mode 100644 index 000000000..34d12cec4 --- /dev/null +++ b/src/Assetic/Asset/HttpAssetWithProxy.php @@ -0,0 +1,30 @@ + + */ +class HttpAssetWithProxy extends HttpAsset +{ + public function __construct($sourceUrl, $filters = array(), $ignoreErrors = false, array $vars = array(), $proxy, $port) + { + parent::__construct($sourceUrl,$filters,$ignoreErrors,$vars); + $this->vars['proxy'] = $proxy; + $this->vars['proxy_port'] = $port; + } +} diff --git a/src/Assetic/Factory/AssetFactory.php b/src/Assetic/Factory/AssetFactory.php index 2ed503584..b6aed2ff0 100644 --- a/src/Assetic/Factory/AssetFactory.php +++ b/src/Assetic/Factory/AssetFactory.php @@ -18,6 +18,7 @@ use Assetic\Asset\FileAsset; use Assetic\Asset\GlobAsset; use Assetic\Asset\HttpAsset; +use Assetic\Asset\HttpAssetWithProxy; use Assetic\AssetManager; use Assetic\Factory\Worker\WorkerInterface; use Assetic\Filter\DependencyExtractorInterface; @@ -37,6 +38,10 @@ class AssetFactory private $am; private $fm; + // for HttpAsset + private $proxy; + private $proxy_port; + /** * Constructor. * @@ -131,6 +136,17 @@ public function setFilterManager(FilterManager $fm) $this->fm = $fm; } + /** + * + * @access public + * @return + **/ + public function setProxy($proxy, $port=null) + { + if(strlen($proxy)) $this->proxy = $proxy; + if(strlen($port)) $this->proxy_port = $port; + } // end function setProxy() + /** * Creates a new asset. * @@ -196,13 +212,10 @@ public function createAsset($inputs = array(), $filters = array(), array $option $asset->add(call_user_func_array(array($this, 'createAsset'), $input)); } else { $asset->add($this->parseInput($input, $options)); - // avoid empty extension if inner asset is something like - // http://fonts.googleapis.com/css?family=Abel - if(pathinfo($input, PATHINFO_EXTENSION)!='') { + if(pathinfo($input, PATHINFO_EXTENSION)!='') $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; } } - } // filters foreach ($filters as $filter) { @@ -349,6 +362,8 @@ protected function createAssetReference($name) protected function createHttpAsset($sourceUrl, $vars) { + if(!empty($this->proxy)) + return new HttpAssetWithProxy($sourceUrl, array(), false, $vars, $this->proxy, $this->proxy_port); return new HttpAsset($sourceUrl, array(), false, $vars); } diff --git a/src/Assetic/Filter/CATCssRewriteFilter.php b/src/Assetic/Filter/CATCssRewriteFilter.php new file mode 100644 index 000000000..db487b05c --- /dev/null +++ b/src/Assetic/Filter/CATCssRewriteFilter.php @@ -0,0 +1,133 @@ + + * @author Bianka Martinovic + */ +class CATCssRewriteFilter extends BaseCssFilter +{ + public function filterLoad(AssetInterface $asset) + { + } + + public function filterDump(AssetInterface $asset) + { + $sourceBase = $asset->getSourceRoot(); + $sourcePath = $asset->getSourcePath(); + $targetPath = $asset->getTargetPath(); + + if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) { + return; + } + + // learn how to get from the target back to the source + if (false !== strpos($sourceBase, '://')) { + list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2); + list($host, $path) = explode('/', $url, 2); + + $host = $scheme.'://'.$host.'/'; + $path = false === strpos($path, '/') ? '' : dirname($path); + $path .= '/'; + } else { + // assume source and target are on the same host + $host = ''; + + // pop entries off the target until it fits in the source + if ('.' == dirname($sourcePath)) { + $path = str_repeat('../', substr_count($targetPath, '/')); + } elseif ('.' == $targetDir = dirname($targetPath)) { + $path = dirname($sourcePath).'/'; + } else { + $path = ''; + while (0 !== strpos($sourcePath, $targetDir)) { + if (false !== $pos = strrpos($targetDir, '/')) { + $targetDir = substr($targetDir, 0, $pos); + $path .= '../'; + } else { + $targetDir = ''; + $path .= '../'; + break; + } + } + $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/'); + $path = str_replace('../', '', $path); + + } + } + + $content = $this->filterReferences($asset->getContent(), function ($matches) use ($host, $path) { + // absolute or protocol-relative or data uri + if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) { + return $matches[0]; + } + + // root relative + if (isset($matches['url'][0]) && '/' == $matches['url'][0]) { + return str_replace($matches['url'], $host.$matches['url'], $matches[0]); + } + + // document relative + $url = $matches['url']; +// while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) { + + $pathinfo = pathinfo($url); + $filename = $pathinfo['basename']; + + if(substr_count($pathinfo['basename'],'?')) + list($filename,$ignore) = explode('?',$pathinfo['basename'],2); + $fullpath = Directory::sanitizePath(CAT_ENGINE_PATH.'/'.$path.'/'.$pathinfo['dirname'].'/'.$filename); + + if(file_exists($fullpath)) + { + if(!file_exists(CAT_PATH.'/assets') || !is_dir(CAT_PATH.'/assets')) + Directory::createDirectory(CAT_PATH.'/assets'); + if(!file_exists(CAT_PATH.'/assets/'.$filename)) + copy($fullpath,CAT_PATH.'/assets/'.$filename); + $url = CAT_SITE_URL.'/assets/'.$pathinfo['basename']; + $path = ''; + } + else + { + $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1); + $url = substr($url, 3); + } + +// } + + $parts = array(); + foreach (explode('/', $host.$path.$url) as $part) { + if ('..' === $part && count($parts) && '..' !== end($parts)) { + array_pop($parts); + } else { + $parts[] = $part; + } + } + + return str_replace($matches['url'], implode('/', $parts), $matches[0]); + }); + + $asset->setContent($content); + } +} diff --git a/src/Assetic/Filter/CATSourcemapFilter.php b/src/Assetic/Filter/CATSourcemapFilter.php new file mode 100644 index 000000000..066334542 --- /dev/null +++ b/src/Assetic/Filter/CATSourcemapFilter.php @@ -0,0 +1,46 @@ +getContent(); + $file = $asset->getSourcePath(); + $path = dirname($file); + + /*# sourceMappingURL=bootstrap.min.css.map */ + preg_match_all('~# sourcemappingurl=([\w\.]+)\s?~i', $content, $matches, PREG_PATTERN_ORDER); + if(count($matches)>0) { + for($i=0;$i Date: Thu, 10 Jan 2019 10:28:13 +0100 Subject: [PATCH 3/7] added { missing after merge --- src/Assetic/Factory/AssetFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Assetic/Factory/AssetFactory.php b/src/Assetic/Factory/AssetFactory.php index b6aed2ff0..c705d225b 100644 --- a/src/Assetic/Factory/AssetFactory.php +++ b/src/Assetic/Factory/AssetFactory.php @@ -212,7 +212,7 @@ public function createAsset($inputs = array(), $filters = array(), array $option $asset->add(call_user_func_array(array($this, 'createAsset'), $input)); } else { $asset->add($this->parseInput($input, $options)); - if(pathinfo($input, PATHINFO_EXTENSION)!='') + if(pathinfo($input, PATHINFO_EXTENSION)!='') { $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; } } From 8cc2a0c1ee76970762e129647267b8ae71e95417 Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Mon, 14 Jan 2019 16:11:23 +0100 Subject: [PATCH 4/7] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 80755d757..eb2678eb9 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name": "kriswallsmith/assetic", + "name": "webbird/assetic", "description": "Asset Management for PHP", "keywords": [ "assets", "compression", "minification" ], - "homepage": "https://github.com/kriswallsmith/assetic", + "homepage": "https://github.com/webbird/assetic", "type": "library", "license": "MIT", "authors": [ From 63788e2cca526ab33777aeecba7e474398273e47 Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Tue, 29 Oct 2019 18:55:49 +0100 Subject: [PATCH 5/7] # fixed author # fixed missing bracket in AssetFactory.php # some fixes in CATCssRewriteFilter.php --- composer.json | 4 ++-- src/Assetic/AssetWriter.php | 9 ++++++-- src/Assetic/Factory/AssetFactory.php | 1 + src/Assetic/Filter/CATCssRewriteFilter.php | 26 +++++++++++++--------- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 80755d757..eb2678eb9 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name": "kriswallsmith/assetic", + "name": "webbird/assetic", "description": "Asset Management for PHP", "keywords": [ "assets", "compression", "minification" ], - "homepage": "https://github.com/kriswallsmith/assetic", + "homepage": "https://github.com/webbird/assetic", "type": "library", "license": "MIT", "authors": [ diff --git a/src/Assetic/AssetWriter.php b/src/Assetic/AssetWriter.php index 4f010a487..999860b5c 100644 --- a/src/Assetic/AssetWriter.php +++ b/src/Assetic/AssetWriter.php @@ -58,7 +58,7 @@ public function writeAsset(AssetInterface $asset) { foreach (VarUtils::getCombinations($asset->getVars(), $this->values) as $combination) { $asset->setValues($combination); - + try { static::write( $this->dir.'/'.VarUtils::resolve( $asset->getTargetPath(), @@ -67,6 +67,12 @@ public function writeAsset(AssetInterface $asset) ), $asset->dump() ); + } catch ( \Exception $e ) { + echo "WRITE ERROR ", $e->getMessage(), "
"; +echo "FILE [",__FILE__,"] FUNC [",__FUNCTION__,"] LINE [",__LINE__,"]

"; + } } } @@ -75,7 +81,6 @@ protected static function write($path, $contents) if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) { throw new \RuntimeException('Unable to create directory '.$dir); } - if (false === @file_put_contents($path, $contents)) { throw new \RuntimeException('Unable to write file '.$path); } diff --git a/src/Assetic/Factory/AssetFactory.php b/src/Assetic/Factory/AssetFactory.php index c705d225b..0c34a157c 100644 --- a/src/Assetic/Factory/AssetFactory.php +++ b/src/Assetic/Factory/AssetFactory.php @@ -216,6 +216,7 @@ public function createAsset($inputs = array(), $filters = array(), array $option $extensions[pathinfo($input, PATHINFO_EXTENSION)] = true; } } + } // filters foreach ($filters as $filter) { diff --git a/src/Assetic/Filter/CATCssRewriteFilter.php b/src/Assetic/Filter/CATCssRewriteFilter.php index db487b05c..4ce7b32f9 100644 --- a/src/Assetic/Filter/CATCssRewriteFilter.php +++ b/src/Assetic/Filter/CATCssRewriteFilter.php @@ -73,7 +73,6 @@ public function filterDump(AssetInterface $asset) } $path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/'); $path = str_replace('../', '', $path); - } } @@ -90,26 +89,29 @@ public function filterDump(AssetInterface $asset) // document relative $url = $matches['url']; + if (empty($url)) { + return; + } // while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) { $pathinfo = pathinfo($url); $filename = $pathinfo['basename']; - if(substr_count($pathinfo['basename'],'?')) - list($filename,$ignore) = explode('?',$pathinfo['basename'],2); + if (substr_count($pathinfo['basename'], '?')) { + list($filename, $ignore) = explode('?', $pathinfo['basename'], 2); + } $fullpath = Directory::sanitizePath(CAT_ENGINE_PATH.'/'.$path.'/'.$pathinfo['dirname'].'/'.$filename); - if(file_exists($fullpath)) - { - if(!file_exists(CAT_PATH.'/assets') || !is_dir(CAT_PATH.'/assets')) + if (file_exists($fullpath)) { + if (!file_exists(CAT_PATH.'/assets') || !is_dir(CAT_PATH.'/assets')) { Directory::createDirectory(CAT_PATH.'/assets'); - if(!file_exists(CAT_PATH.'/assets/'.$filename)) - copy($fullpath,CAT_PATH.'/assets/'.$filename); + } + if (!file_exists(CAT_PATH.'/assets/'.$filename)) { + copy($fullpath, CAT_PATH.'/assets/'.$filename); + } $url = CAT_SITE_URL.'/assets/'.$pathinfo['basename']; $path = ''; - } - else - { + } else { $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1); $url = substr($url, 3); } @@ -128,6 +130,8 @@ public function filterDump(AssetInterface $asset) return str_replace($matches['url'], implode('/', $parts), $matches[0]); }); + $content = "/*** ".$asset->getSourcePath()." ***/\n\n".$content; + $asset->setContent($content); } } From 48fc9ce8446833af43e5da9a44b461e9281b5c2b Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Mon, 17 Feb 2020 10:43:40 +0100 Subject: [PATCH 6/7] added CATDebugAddPathInfoFilter.php --- .../Filter/CATDebugAddPathInfoFilter.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/Assetic/Filter/CATDebugAddPathInfoFilter.php diff --git a/src/Assetic/Filter/CATDebugAddPathInfoFilter.php b/src/Assetic/Filter/CATDebugAddPathInfoFilter.php new file mode 100644 index 000000000..dbc546a39 --- /dev/null +++ b/src/Assetic/Filter/CATDebugAddPathInfoFilter.php @@ -0,0 +1,36 @@ +getContent(); + $content = "\n/*** ".$asset->getSourcePath()." ***/\n".$content; + $asset->setContent($content); + } +} From b37948da58163da6470e59e0e3b10a77ccac9d97 Mon Sep 17 00:00:00 2001 From: Bianka Martinovic Date: Mon, 24 Feb 2020 12:02:54 +0100 Subject: [PATCH 7/7] Update README.md --- README.md | 352 +++--------------------------------------------------- 1 file changed, 17 insertions(+), 335 deletions(-) diff --git a/README.md b/README.md index 7ec0058aa..172557842 100644 --- a/README.md +++ b/README.md @@ -1,345 +1,27 @@ -# Assetic [![Build Status](https://travis-ci.org/kriswallsmith/assetic.png?branch=master)](https://travis-ci.org/kriswallsmith/assetic) ![project status](http://stillmaintained.com/kriswallsmith/assetic.png) # +# Assetic - Fork for BlackCat CMS v2 Assetic is an asset management framework for PHP. -``` php -dump(); -``` +New Filters +----------- -Assets ------- + * `CATCssRewriteFilter`: Rewrites CSS URLs to assets folder of current site + * `CATDebugAddPathInfoFilter`: For debugging + * `CATSourcemapFilter`: Find sourcemappingurl and add it to CAT Assets Helper + +Please note that these filters cannot be used without BlackCat CMS v2! But you may use them to create your own filters. -An Assetic asset is something with filterable content that can be loaded and -dumped. An asset also includes metadata, some of which can be manipulated and -some of which is immutable. +Other +----- -| **Property** | **Accessor** | **Mutator** | -|--------------|-----------------|---------------| -| content | getContent | setContent | -| mtime | getLastModified | n/a | -| source root | getSourceRoot | n/a | -| source path | getSourcePath | n/a | -| target path | getTargetPath | setTargetPath | + * Assetic/AssetWriter.php: Catch static::write() exceptions + * Assetic/Factory/AssetFactory.php: FIX for empty extension; ADDED HttpAssetWithProxy + * Assetic/Asset/HttpAssetWithProxy.php: ADDED - Load assets from http if you're behind a proxy -The "target path" property denotes where an asset (or an collection of assets) should be dumped. - -Filters -------- - -Filters can be applied to manipulate assets. - -``` php -dump(); -``` - -The filters applied to the collection will cascade to each asset leaf if you -iterate over it. - -``` php -dump(); -} -``` - -The core provides the following filters in the `Assetic\Filter` namespace: - - * `AutoprefixerFilter`: Parse and update vendor-specific properties using autoprefixer - * `CoffeeScriptFilter`: compiles CoffeeScript into Javascript - * `CompassFilter`: Compass CSS authoring framework - * `CssEmbedFilter`: embeds image data in your stylesheets - * `CssImportFilter`: inlines imported stylesheets - * `CssMinFilter`: minifies CSS - * `CleanCssFilter`: minifies CSS - * `CssRewriteFilter`: fixes relative URLs in CSS assets when moving to a new URL - * `DartFilter`: compiles Javascript using dart2js - * `EmberPrecompileFilter`: precompiles Handlebars templates into Javascript for use in the Ember.js framework - * `GoogleClosure\CompilerApiFilter`: compiles Javascript using the Google Closure Compiler API - * `GoogleClosure\CompilerJarFilter`: compiles Javascript using the Google Closure Compiler JAR - * `GssFilter`: compliles CSS using the Google Closure Stylesheets Compiler - * `HandlebarsFilter`: compiles Handlebars templates into Javascript - * `JpegoptimFilter`: optimize your JPEGs - * `JpegtranFilter`: optimize your JPEGs - * `JSMinFilter`: minifies Javascript - * `JSMinPlusFilter`: minifies Javascript - * `JSqueezeFilter`: compresses Javascript - * `LessFilter`: parses LESS into CSS (using less.js with node.js) - * `LessphpFilter`: parses LESS into CSS (using lessphp) - * `OptiPngFilter`: optimize your PNGs - * `PackagerFilter`: parses Javascript for packager tags - * `PackerFilter`: compresses Javascript using Dean Edwards's Packer - * `PhpCssEmbedFilter`: embeds image data in your stylesheet - * `PngoutFilter`: optimize your PNGs - * `ReactJsxFilter`: compiles React JSX into JavaScript - * `Sass\SassFilter`: parses SASS into CSS - * `Sass\ScssFilter`: parses SCSS into CSS - * `SassphpFilter`: parses Sass into CSS using the sassphp bindings for Libsass - * `ScssphpFilter`: parses SCSS using scssphp - * `SeparatorFilter`: inserts a separator between assets to prevent merge failures - * `SprocketsFilter`: Sprockets Javascript dependency management - * `StylusFilter`: parses STYL into CSS - * `TypeScriptFilter`: parses TypeScript into Javascript - * `UglifyCssFilter`: minifies CSS - * `UglifyJs2Filter`: minifies Javascript - * `UglifyJsFilter`: minifies Javascript - * `Yui\CssCompressorFilter`: compresses CSS using the YUI compressor - * `Yui\JsCompressorFilter`: compresses Javascript using the YUI compressor - -Asset Manager -------------- - -An asset manager is provided for organizing assets. - -``` php -set('jquery', new FileAsset('/path/to/jquery.js')); -$am->set('base_css', new GlobAsset('/path/to/css/*')); -``` - -The asset manager can also be used to reference assets to avoid duplication. - -``` php -set('my_plugin', new AssetCollection(array( - new AssetReference($am, 'jquery'), - new FileAsset('/path/to/jquery.plugin.js'), -))); -``` - -Filter Manager --------------- - -A filter manager is also provided for organizing filters. - -``` php -set('sass', new SassFilter('/path/to/parser/sass')); -$fm->set('yui_css', new Yui\CssCompressorFilter('/path/to/yuicompressor.jar')); -``` - -Asset Factory -------------- - -If you'd rather not create all these objects by hand, you can use the asset -factory, which will do most of the work for you. - -``` php -setAssetManager($am); -$factory->setFilterManager($fm); -$factory->setDebug(true); - -$css = $factory->createAsset(array( - '@reset', // load the asset manager's "reset" asset - 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/" -), array( - 'scss', // filter through the filter manager's "scss" filter - '?yui_css', // don't use this filter in debug mode -)); - -echo $css->dump(); -``` - -The `AssetFactory` is constructed with a root directory which is used as the base directory for relative asset paths. - -Prefixing a filter name with a question mark, as `yui_css` is here, will cause -that filter to be omitted when the factory is in debug mode. - -You can also register [Workers](src/Assetic/Factory/Worker/WorkerInterface.php) on the factory and all assets created -by it will be passed to the worker's `process()` method before being returned. See _Cache Busting_ below for an example. - -Dumping Assets to static files ------------------------------- - -You can dump all the assets an AssetManager holds to files in a directory. This will probably be below your webserver's document root -so the files can be served statically. - -``` php -writeManagerAssets($am); -``` - -This will make use of the assets' target path. - -Cache Busting -------------- - -If you serve your assets from static files as just described, you can use the CacheBustingWorker to rewrite the target -paths for assets. It will insert an identifier before the filename extension that is unique for a particular version -of the asset. - -This identifier is based on the modification time of the asset and will also take depended-on assets into -consideration if the applied filters support it. - -``` php -setAssetManager($am); -$factory->setFilterManager($fm); -$factory->setDebug(true); -$factory->addWorker(new CacheBustingWorker()); - -$css = $factory->createAsset(array( - '@reset', // load the asset manager's "reset" asset - 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/" -), array( - 'scss', // filter through the filter manager's "scss" filter - '?yui_css', // don't use this filter in debug mode -)); - -echo $css->dump(); -``` - -Internal caching -------- - -A simple caching mechanism is provided to avoid unnecessary work. - -``` php -dump(); -$js->dump(); -$js->dump(); -``` - -Twig ----- - -To use the Assetic [Twig][3] extension you must register it to your Twig -environment: - -``` php -addExtension(new AsseticExtension($factory)); -``` - -Once in place, the extension exposes a stylesheets and a javascripts tag with a syntax similar -to what the asset factory uses: - -``` html+jinja -{% stylesheets '/path/to/sass/main.sass' filter='sass,?yui_css' output='css/all.css' %} - -{% endstylesheets %} -``` - -This example will render one `link` element on the page that includes a URL -where the filtered asset can be found. - -When the extension is in debug mode, this same tag will render multiple `link` -elements, one for each asset referenced by the `css/src/*.sass` glob. The -specified filters will still be applied, unless they are marked as optional -using the `?` prefix. - -This behavior can also be triggered by setting a `debug` attribute on the tag: - -``` html+jinja -{% stylesheets 'css/*' debug=true %} ... {% stylesheets %} -``` - -These assets need to be written to the web directory so these URLs don't -return 404 errors. - -``` php -setLoader('twig', new TwigFormulaLoader($twig)); - -// loop through all your templates -foreach ($templates as $template) { - $resource = new TwigResource($twigLoader, $template); - $am->addResource($resource, 'twig'); -} - -$writer = new AssetWriter('/path/to/web'); -$writer->writeManagerAssets($am); -``` - ---- - -Assetic is based on the Python [webassets][1] library (available on -[GitHub][2]). - -[1]: http://elsdoerfer.name/docs/webassets -[2]: https://github.com/miracle2k/webassets -[3]: http://twig.sensiolabs.org