diff --git a/API.md b/API.md index aba5cb5..0d28f8e 100644 --- a/API.md +++ b/API.md @@ -11,42 +11,49 @@ Assets -Constants + + +Properties ---------- -### DEFAULT_REGEX +### $asset_regex ``` -const DEFAULT_REGEX = '/.\.(css|js)$/i' +protected string $asset_regex = '/.\.(css|js)$/i' ``` +Regex to match against a filename/url to determine if it is an asset. +* Visibility: **protected** + -### CSS_REGEX +### $css_regex ``` -const CSS_REGEX = '/.\.css$/i' +protected string $css_regex = '/.\.css$/i' ``` +Regex to match against a filename/url to determine if it is a CSS asset. +* Visibility: **protected** -### JS_REGEX + +### $js_regex ``` -const JS_REGEX = '/.\.js$/i' +protected string $js_regex = '/.\.js$/i' ``` +Regex to match against a filename/url to determine if it is a JavaScript asset. - -Properties ----------- +* Visibility: **protected** ### $public_dir diff --git a/README.md b/README.md index 54d54e8..27a5a1a 100644 --- a/README.md +++ b/README.md @@ -139,12 +139,12 @@ To preconfigure collections using the config file: // ... config.php ... 'collections' => array( - 'one' => 'one.css', - 'two' => ['two.css', 'two.js'], - 'external' => ['http://example.com/external.css', 'https://secure.example.com/https.css', '//example.com/protocol/agnostic.js'], - 'mix' => ['internal.css', 'http://example.com/external.js'], - 'nested' => ['one', 'two'], - 'duplicated' => ['nested', 'one.css','two.css', 'three.js'], + 'one' => 'one.css', + 'two' => array('two.css', 'two.js'), + 'external' => array('http://example.com/external.css', 'https://secure.example.com/https.css', '//example.com/protocol/agnostic.js'), + 'mix' => array('internal.css', 'http://example.com/external.js'], + 'nested' => array('one', 'two'), + 'duplicated' => array('nested', 'one.css','two.css', 'three.js'), ), Let me show you how to use the above collection in different scenarios: @@ -201,7 +201,6 @@ Once it's enabled all your assets will be concatenated and minified to a single This process can take a few seconds depending on the amount of assets and your connection but it's triggered only the first time you load a page whose assets have never been pipelined before. The subsequent times the same page (or any page using the same assets) is loaded, the previously pipelined file will be used giving you much faster loading time and less bandwidth usage. - **Note:** For obvious reasons, using the pipeline is recommended only for production environment. If your assets have changed since they were pipelined use the provided artisan command to purge the pipeline cache @@ -219,6 +218,9 @@ will produce: +If you happend to use NGINX with the [gzip_static](http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html) feature enabled, add the following config option to automatically create a suitable gziped version of the pipelined assets: + + 'pipeline_gzip' => 12345, ### Other configurable options @@ -278,34 +280,39 @@ You can use the library without using static methods. The signature of all metho ## Sample collections // jQuery (CDN) - 'jquery-cdn' => ['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'], + 'jquery-cdn' => array('//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'), // jQuery UI (CDN) - 'jquery-ui-cdn' => [ + 'jquery-ui-cdn' => array( 'jquery-cdn', - '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js', - ], + '//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js', + ), // Twitter Bootstrap (CDN) - 'bootstrap-cdn' => [ + 'bootstrap-cdn' => array( 'jquery-cdn', '//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css', '//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css', '//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js' - ], + ), // Zurb Foundation (CDN) - 'foundation-cdn' => [ + 'foundation-cdn' => array( 'jquery-cdn', - '//cdn.jsdelivr.net/foundation/5.3.3/css/normalize.css', - '//cdn.jsdelivr.net/foundation/5.3.3/css/foundation.min.css', - '//cdn.jsdelivr.net/foundation/5.3.3/js/foundation.min.js', + '//cdn.jsdelivr.net/foundation/5.4.7/css/normalize.css', + '//cdn.jsdelivr.net/foundation/5.4.7/css/foundation.min.css', + '//cdn.jsdelivr.net/foundation/5.4.7/js/foundation.min.js', 'app.js' - ], + ), ## Troubleshooting / F.A.Q. + +### Where can I ask for help/support? + +First make sure you read this [F.A.Q.](#troubleshooting) and if you still need help [open an issue on GitHub](https://github.com/Stolz/Assets/issues/new) or use your GitHub account to [ask for support here](http://laravel.io/forum/02-17-2014-package-an-ultra-simple-to-use-assets-managementpipeline-package). + ### Where should I copy my assets files? @@ -341,7 +348,7 @@ If you use a massive amount of assets make sure your connection is fast enough a ### Can I use multiple instances of the library? -Yes you can but there is no need. Read next question. +Yes you can but there is no need. Read next question. If you still want to use multiple instances, [read how](https://github.com/Stolz/Assets/issues/37#issuecomment-57676554). ### Can I change settings on the fly? @@ -351,17 +358,18 @@ Yes you can. There is a `config()` public method to change settings on the fly. echo Assets::add('jquery-cdn')->js(); echo Assets::reset()->add(array('custom.js', 'main.js'))->config(array('pipeline' => true))->js(); - -### Why my pull requests with *some feature* was not merged? + +### How can I contribute? -Remember this is a framework agnostic library, if your PR uses code related to your framework it will not get merged. Also, the main reason for the library to exist is to be easy to use, if your PR involves changing this and makes the library cumbersome to use then it will not get merged. +Send a pull requests to the **develop** branch. Read next question for your PR to have more chances to be accepted. - -### How can I help? + +### Why my pull requests was not accepted? -Send a pull requests to the `develop` branch. I really hate writing unit tests, any addition to improving test coverage will be very welcome. +Remember, the main reason for the library to exist is to be easy to use. If your PR involves changing this and makes the library cumbersome to use then it will not be accepted. - -### Where can I ask for help/support? +This is a framework agnostic library, if your PR uses code related to your framework it will not be accepted. + +If your contribution adds new features make sure to include a proper PHPUnit test for it. -First make sure you read the [F.A.Q.](#troubleshooting) and if you still need help [open an issue on GitHub](https://github.com/Stolz/Assets/issues/new). +Please use PHP_CodeSniffer to make sure your code follows the project coding standards (which is a slightly variation of [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)). diff --git a/src/Stolz/Assets/Manager.php b/src/Stolz/Assets/Manager.php index 777d9fa..2bfff3e 100644 --- a/src/Stolz/Assets/Manager.php +++ b/src/Stolz/Assets/Manager.php @@ -9,14 +9,24 @@ class Manager { - /** @const Regex to match CSS and JavaScript files */ - const DEFAULT_REGEX = '/.\.(css|js)$/i'; + /** + * Regex to match against a filename/url to determine if it is an asset. + * @var string + */ + protected $asset_regex = '/.\.(css|js)$/i'; - /** @const Regex to match CSS files */ - const CSS_REGEX = '/.\.css$/i'; + /** + * Regex to match against a filename/url to determine if it is a CSS asset. + * @var string + */ - /** @const Regex to match JavaScript files */ - const JS_REGEX = '/.\.js$/i'; + protected $css_regex = '/.\.css$/i'; + + /** + * Regex to match against a filename/url to determine if it is a JavaScript asset. + * @var string + */ + protected $js_regex = '/.\.js$/i'; /** * Absolute path to the public directory of your App (WEBROOT). @@ -43,7 +53,7 @@ class Manager protected $js_dir = 'js'; /** - * Directory for package assets. + * Directory for local package assets. * Relative to your public directory ('public_dir'). * No trailing slash!. * @var string @@ -52,7 +62,7 @@ class Manager /** * Enable assets pipeline (concatenation and minification). - * If you set an integer value greather than 1 it will be used as pipeline timestamp. + * If you set an integer value greather than 1 it will be used as pipeline timestamp taht will be added to the URL. * @var bool|integer */ protected $pipeline = false; @@ -135,54 +145,32 @@ public function __construct(array $options = array()) */ public function config(array $config) { - // Set pipeline mode - if(isset($config['pipeline'])) - $this->pipeline = $config['pipeline']; + // Set regex options + foreach(array('asset_regex', 'css_regex', 'js_regex') as $option) + if(isset($config[$option]) and (@preg_match($config[$option], null) !== false)) + $this->$option = $config[$option]; - // Set public dir - if(isset($config['public_dir'])) - $this->public_dir = $config['public_dir']; + // Set common options + foreach(array('public_dir', 'css_dir', 'js_dir', 'packages_dir', 'pipeline', 'pipeline_dir', 'pipeline_gzip') as $option) + if(isset($config[$option])) + $this->$option = $config[$option]; // Pipeline requires public dir if($this->pipeline and ! is_dir($this->public_dir)) throw new Exception('stolz/assets: Public dir not found'); - // Set custom pipeline directory - if(isset($config['pipeline_dir'])) - $this->pipeline_dir = $config['pipeline_dir']; - - // Set pipeline gzip compression - if(isset($config['pipeline_gzip'])) - $this->pipeline_gzip = $config['pipeline_gzip']; - // Set custom pipeline fetch command if(isset($config['fetch_command']) and ($config['fetch_command'] instanceof Closure)) $this->fetch_command = $config['fetch_command']; - // Set custom CSS directory - if(isset($config['css_dir'])) - $this->css_dir = $config['css_dir']; - - // Set custom JavaScript directory - if(isset($config['js_dir'])) - $this->js_dir = $config['js_dir']; - - // Set custom packages directory - if(isset($config['packages_dir'])) - $this->packages_dir = $config['packages_dir']; - // Set collections if(isset($config['collections']) and is_array($config['collections'])) $this->collections = $config['collections']; // Autoload assets if(isset($config['autoload']) and is_array($config['autoload'])) - { foreach($config['autoload'] as $asset) - { $this->add($asset); - } - } return $this; } @@ -204,24 +192,18 @@ public function add($asset) foreach($asset as $a) $this->add($a); } + // Collection elseif(isset($this->collections[$asset])) - { $this->add($this->collections[$asset]); - } - else - { - // JavaScript or CSS - $info = pathinfo($asset); - if(isset($info['extension'])) - { - $ext = strtolower($info['extension']); - if($ext === 'css') - $this->addCss($asset); - elseif($ext === 'js') - $this->addJs($asset); - } - } + + // JavaScript asset + elseif(preg_match($this->js_regex, $asset)) + $this->addJs($asset); + + // CSS asset + elseif(preg_match($this->css_regex, $asset)) + $this->addCss($asset); return $this; } @@ -605,46 +587,34 @@ public function getJs() * @return Manager * @throws Exception */ - public function addDir($directory, $pattern = self::DEFAULT_REGEX) + public function addDir($directory, $pattern = null) { // Check if public_dir exists if( ! is_dir($this->public_dir)) throw new Exception('stolz/assets: Public dir not found'); - // Get files + // By default match all assets + if(is_null($pattern)) + $pattern = $this->asset_regex; + + // Get assets files $files = $this->rglob($this->public_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->public_dir); // No luck? Nothing to do if( ! $files) return $this; - // Add CSS files - if($pattern === self::CSS_REGEX) - { - $this->css = array_unique(array_merge($this->css, $files)); - return $this; - } - - // Add JavaScript files - if($pattern === self::JS_REGEX) - { + // Avoid polling if the pattern is our old friend JavaScript + if($pattern === $this->js_regex) $this->js = array_unique(array_merge($this->js, $files)); - return $this; - } - // Unknown pattern. We must poll to know the extension :( - foreach($files as $asset) - { - $info = pathinfo($asset); - if(isset($info['extension'])) - { - $ext = strtolower($info['extension']); - if($ext === 'css' and ! in_array($asset, $this->css)) - $this->css[] = $asset; - elseif($ext === 'js' and ! in_array($asset, $this->js)) - $this->js[] = $asset; - } - } + // Avoid polling if the pattern is our old friend CSS + elseif($pattern === $this->css_regex) + $this->css = array_unique(array_merge($this->css, $files)); + + // Unknown pattern. We must poll to know the asset type :( + else foreach($files as $asset) + $this->add($asset); return $this; } @@ -657,7 +627,7 @@ public function addDir($directory, $pattern = self::DEFAULT_REGEX) */ public function addDirCss($directory) { - return $this->addDir($directory, self::CSS_REGEX); + return $this->addDir($directory, $this->css_regex); } /** @@ -668,7 +638,7 @@ public function addDirCss($directory) */ public function addDirJs($directory) { - return $this->addDir($directory, self::JS_REGEX); + return $this->addDir($directory, $this->js_regex); } /**