stolz / assets Goto Github PK
View Code? Open in Web Editor NEWAn ultra-simple-to-use assets management library for PHP
License: MIT License
An ultra-simple-to-use assets management library for PHP
License: MIT License
It would be great to set an option to all exported assets countains full url (with domain) no just relative path (at least it should get / at the beging).
Now only way to work around is to use base tag, but all my assets, css and javascript are located under different domain (don't ask), so i can't change it...
There are problems loading assets when the website uses localization because assets are added with relative routes, for example:
<link type="text/css" rel="stylesheet" href="css/style.css" />
And thus the browser tries to load the assets using the route: "http://www.mysite.com/en/css/style.css" instead of "http://www.mysite.com/css/style.css".
I found an easy solution to this by simply adding "URL::asset(...)" when generating the headers to include the assets (in the functions css and js of your code). The changes I made are:
/**
* Build the CSS link tags
*
* @return string
*/
public function css()
{
if( ! $this->css)
return null;
if($this->pipeline)
return '<link type="text/css" rel="stylesheet" href="'.URL::asset($this->cssPipeline()).'" />'."\n";
$output = '';
foreach($this->css as $file)
$output .= '<link type="text/css" rel="stylesheet" href="'.URL::asset($file).'" />'."\n";
return $output;
}
/**
* Build the JavaScript script tags
*
* @return string
*/
public function js()
{
if( ! $this->js)
return null;
if($this->pipeline)
return '<script type="text/javascript" src="'.URL::asset($this->jsPipeline()).'"></script>'."\n";
$output = '';
foreach($this->js as $file)
$output .= '<script type="text/javascript" src="'. URL::asset($file).'"></script>'."\n";
return $output;
}
You also have to include "use Illuminate\Support\Facades\URL;" at the beginning.
As per the instructions, I've executed:
composer require stolz/assets
However, when
'Stolz\Assets\Laravel\ServiceProvider',
Exists within the providers array, I get this when doing composer update/install:
generating autoload files
"type": Symfony\\Component\\Debug\\Exception\\FatalErrorException
"message": Call to undefined method Stolz\\Assets\\Laravel\\ServiceProvider::mergeConfigFrom()
"file": vendor\\stolz\\assets\\src\\Laravel\\ServiceProvider.php (line 17)
Script php artisan clear-compiled handling the post-update-cmd event returned with an error
(cleaned it up some out of the just plain json it provides.)
Any help would be appreciated, I'm using Laravel 4.2
NGINX has a nifty feature called gzip_static.
CSS and JS resources need to be compressed by the server, and this happens on every request.
But if this option is enabled, and a file exists with a .gz extension, it is assumed to be a compressed version of the file.
For example, if you request pipeline.css
and a file also exists called pipeline.css.gz
, then NGINX sends the latter file, along with appropriate headers, and does not need to compress it.
To implement this, we'd need a boolean option gzip_static
, defaulting to false
.
If it is set to true
, then immediately after creating a pipeline file, we'd also create a .gz
version of it.
Note, that we'd still need to generate the same URLs - without the .gz
- as this is a feature of the webserver, not the application.
It seems like purging the cache isn't as convenient as checking the files for updated content. Could the JS minify function be changed to something like this?
protected function jsPipeline()
{
$file = md5(implode($this->js)) . '.js';
$relative_path = "{$this->js_dir}/{$this->pipeline_dir}/$file";
$absolute_path = $this->public_dir . DIRECTORY_SEPARATOR . $this->js_dir . DIRECTORY_SEPARATOR . $this->pipeline_dir . DIRECTORY_SEPARATOR . $file;
$timestamp = (intval($this->pipeline) > 1) ? '?' . $this->pipeline : null;
$old_content = ''; // variable to hold current minified code
// If pipeline exist return it
if (file_exists($absolute_path))
$old_content = md5_file($absolute_path); //grab the old code
//return $relative_path . $timestamp;
// Create destination directory
$directory = $this->public_dir . DIRECTORY_SEPARATOR . $this->js_dir . DIRECTORY_SEPARATOR . $this->pipeline_dir;
if (!is_dir($directory))
mkdir($directory, 0777, true);
// Concatenate files
$buffer = $this->buildBuffer($this->js);
// Minifiy
$min = \JSMin::minify($buffer);
if ($old_content == $min) {
return $relative_path . $timestamp; //check the new code and if they are the same, return same old code
}
//code changed so let's write the new code to the file
// Write file
file_put_contents($absolute_path, $min);
return $relative_path . $timestamp;
}
Thoughts? You could make it an option and set it in the config file.
I would like to add any asset to group and call via this group name.
Please help
Hi,
How does this actually work if you use templates/layout.
Lets say I have an included view create.blade.php and I want only a specific javascript file to be loaded in there. How does that work?
It would be great if one can hook on file-extensions with callbacks. This way you can extend this great and simply asset manager.
When trying to autoload a Google Fonts font I noticed it wasn't being included into the css array. I found that the reason for this is that Assets uses the file extension to determine if it's a css file or javascript file, which doesn't work with a Google Fonts API link since it doesn't even have a file extension.
Example: These two fonts will not autoload due to the link not having an actual file extension.
$config = array(
...
'collections' => array(
'fonts' => [
'//fonts.googleapis.com/css?family=Roboto:100,300,500',
'//fonts.googleapis.com/css?family=Lato:900'
]
),
'autoload' => array(
'fonts'
)
...
)
About 139 seconds to be exact.
According to this article (and some other resources)
http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
In pipeline function we add query at the end of the path $timestamp = (intval($this->pipeline) > 1) ? '?' . $this->pipeline : null;
If we add $timestamp
just before $extension
this can be easily solved. Let me know what you think, I would be happy to send a pull request.
I can't config my asset dir when publish package. I try to print config variable in boot() method but it return a empty array
Hi.
I'd like to give a suggestion.
On the lines that generate <script>
and <link>
tags on Stolz/Assets/Manager.php
, the Laravel helper asset()
could be used, so local assets tags would always point to the full asset URL.
Eg. (on line 220):
public function css()
{
if( ! $this->css)
return null;
if($this->pipeline)
return '<link type="text/css" rel="stylesheet" href="'.asset($this->cssPipeline()).'" />'."\n";
$output = '';
foreach($this->css as $file)
$output .= '<link type="text/css" rel="stylesheet" href="'.asset($file).'" />'."\n";
return $output;
}
As well as external resources (files), it is often useful to manage inline resouces (scripts) at the same time.
For example, ZendFramework offers this feature via its headScript->appendScript() and headScript->appendFile() methods. I have coded something similar in many projects.
Translated to stolz/assets, it would look something like this:
/* load the libraries */
Asset::addJs('jquery.js');
Asset::addJs('jquery.widget.js');
/* use the libraries */
Asset::addInlineJs('jQuery("#abc").widget();');
When you come to render the data, you would get this:
<script src="asset-pipeline.js"></script>
<script>jQuery("#abc").widget();</script>
We collect the inline scripts, and render them after the external scripts.
Does this sort of feature have a place in this project?
I noticed two issues:
css/myfile.css
, while adding files from a package results in paths like /packages/vendor/package/myfile.css
(relative vs absolute).I would be great if http cache headers could also be included
When running php artisan asset:flush
in an Laravel 5 installation the commands like
$pipeDir = Config::get('assets::pipeline_dir', 'min');
Config::get('assets::css_dir', 'css')
Config::get('assets::js_dir', 'js')
always use the given default value ("min") and flush will fail (wrong directories get cleared).
Hi!
When i try to register resource for controller on second level, i've got a problem with every asset url (autoload too). I have default config. Look at my routes.php:
// First level - all right
Route::resource('main', 'FirstController');
// Second level - bad assets
Route::resource('second/level', 'SecondController');
expect:
js/vendor/backbone-min.js
have /second before asset url:
second/js/vendor/backbone-min.js
I hope, that i simple don't understand how it works and you help me.
p.s. app starts with "php artisan serve" on localhost:8000
Hi!
Is there any chance to implement a {version} wildcard support when we define the bundle (collection)? Like in C# MVC4...
http://www.asp.net/mvc/overview/performance/bundling-and-minification
http://johnnewcombe.net/blog/mvc-4-part-4
http://stackoverflow.com/questions/12029161/version-wildcard-in-mvc4-bundle
Thanks!
Hello, thanks for your work, but i have an idea about allow folders support in package config:
'collections' => array(
'main' => 'js/main.js',
// include all .js files in /plugins and /modules folders
'modules' => ['js/plugins/*.js', 'js/modules/*.js'],
// include all files in /bootstrap folder
'bootstrap' => 'bootstrap/*',
// include all .css files in /css
'styles' => 'css/*.css',
'app' => ['main', 'modules', 'bootstrap', 'styles']
)
Is it possible next time?
Hello!
Currently, your plugin uses JSMin to minify JS files in the pipeline. Please add an option to choose JSMinPlus instead (via an option in config.php).
Currently, I have to change this line every time your plugin updates (in Manager.php)
return \JSMin::minify($buffer);
->
return \JSMinPlus::minify($buffer);
Hi,
Could you please implement an option to add attributes when you define an asset?
For example:
Assets::addCss('site.css', array('media' => 'screen'));
Assets::addCss('site-print.css', array('media' => 'print'));
And the generated will looks like this:
<link href="site.css" type="text/css" rel="stylesheet" media="screen">
<link href="site-print.css" type="text/css" rel="stylesheet" media="print">
Thank you!
Hi there,
Just started using this package, and wondering if there is any option to add the async
or defer
attribute on the script
tag? If not, I can prepare a pull request if there is demand?
Best,
Joram
Hi,
I recently did a composer update
and got the following error:
PHP Fatal error: Call to undefined method Stolz\Assets\Laravel\ServiceProvider::mergeConfigFrom() in /Users/myUser/Projects/laravel/laravel/vendor/stolz/assets/src/Laravel/ServiceProvider.php on line 17
So I grep'ed the vendor
directory, only found the call of $this->mergeConfigFrom()
but no definition of the function itself.
Just for the record, my composer.json
:
"require": {
"laravel/framework": "4.2.*",
"jenssegers/mongodb": "*",
"zizaco/confide": "~4.0@dev",
"zizaco/entrust": "1.2.*@dev",
"stolz/assets": "0.1.*"
},
and my config/app.php
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
'Illuminate\Session\CommandsServiceProvider',
'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
'Illuminate\Routing\ControllerServiceProvider',
'Illuminate\Cookie\CookieServiceProvider',
'Illuminate\Database\DatabaseServiceProvider',
'Illuminate\Encryption\EncryptionServiceProvider',
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Illuminate\Log\LogServiceProvider',
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
'Illuminate\Queue\QueueServiceProvider',
'Illuminate\Redis\RedisServiceProvider',
'Illuminate\Remote\RemoteServiceProvider',
'Illuminate\Auth\Reminders\ReminderServiceProvider',
'Illuminate\Database\SeedServiceProvider',
'Illuminate\Session\SessionServiceProvider',
'Illuminate\Translation\TranslationServiceProvider',
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Workbench\WorkbenchServiceProvider',
'Jenssegers\Mongodb\MongodbServiceProvider',
'Way\Generators\GeneratorsServiceProvider',
'Stolz\Assets\Laravel\ServiceProvider',
'Zizaco\Confide\ServiceProvider',
'Zizaco\Entrust\EntrustServiceProvider',
'FiveMissions\Place\PlaceServiceProvider',
'FiveMissions\Validation\CustomValidationServiceProvider',
),
I also deleted the whole stolz
subdir at the vendors
folder and reinstalled via composer update
, also doing a composer dump-autoload
Suggestions are very welcome!
Kind regards
ralf
can be remove... sry
This is just a suggestion.
I recently ran into an issue adding the following css file to the 'autoload' array:
I was able to work around this issue by adding a parameter with '.css' as the value so that the regex would pick it up, like this:
However, this isn't very clean. Here are two options:
Thanks
There is a new array syntax in service provider and flush pipeline that make it not working on php 5.3.
After replacing the syntax it works again.
There are some suckers that have to work with 5.3 and it would be cool to keep it compatible with 5.3
Thx.
Today, doing 'composer update', I get this error:
syntax error, unexpected '.', expecting ',' or ';'
File: vendor\stolz\assets\src\Laravel\ServiceProvider.php (line 14)
Previously, I got another error:
Class 'Stolz\Assets\ManagerServiceProvider' not found
after reading the doc, I noticed (maybe) the provider has changed, so after changing it in
Stolz\Assets\Laravel\ServiceProvider
...I get the syntax error.
Thank you.
Some of shared hosting companies disabled the file_get_contents() function in php.ini and in that case it is unable to get the content of external links. The solution could be the usage of cURL.
Is it possible to add non public asset paths?
My main point is using package-assets, without the need to publish them separately.
After composer update
- Removing stolz/assets (dev-master 0ef3b3f)
- Installing stolz/assets (dev-master e1a1c03)
Downloading: 100%
[RuntimeException]
Error Output: PHP Fatal error: Call to undefined method Stolz\Assets\Laravel\Serv
iceProvider::mergeConfigFrom() in /var/www/nest_source/vendor/stolz/assets/src/Lar
avel/ServiceProvider.php on line 17
laravel 4.2.16
Hi,
This is the first time I am using this package with Laravel 5. When I run the vendor:publish
command, it doesn't add assets.php
to config folder.
I've been trying to find out the problem when minifying a specific file and finally found the issue, which appears has been fixed in a newer version of mrclay/minify found here.
Issue found here.
It would be nice if you updated the composer file here so that commit will be used.
I see that there's some debate on relative / absolute linking to the generated asset links using this package. For the most part I don't really take a side one way or the other. The tag allows you to get away with handling assets relative to the root URI of your application from subdirectories without much issue.
HOWEVER... I feel like if there was a config variable to specify whether or not there is to be some sort of prefix path to the relative link paths we could easily supply a CDN path for our Assets that are generated via Pipelines. Any thoughts on that?
Hello, it would be good if you could implement a feature that allows adding async to a script tag.
Here is doc about it http://www.w3schools.com/tags/att_script_async.asp
Issue: The minification works really well, but is there a way to keep comments in the code, for instance for licenses? They all seem to be stripped out.
Expectation: there should be a flag in the config file to keep comments for JSMin.
I've tried the addDir()
as you suggested in #61 but for some reason it drop back wrong path for the assets. This is my asset definition:
Assets::addDir('js', '/(script-)(\d+)(\.min\.js)/');
And the js_dir
is default 'js'
.
It find the file in the dir but when I check the generated and inserted link URL in HTML code, it's wrong:
http://www.dev.local/js//js/script-123456.min.js
If I use the normal Assets::addJs('script-123456.min.js')
then it's working.
I've tried the following variations as well (all get back with same wrong result):
Assets::addDir('js/', '/(script-)(\d+)(\.min\.js)/');
Assets::addDir('', '/(script-)(\d+)(\.min\.js)/');
Assets::addDir('./', '/(script-)(\d+)(\.min\.js)/');
Seems the wrong path is generating in buildLocalLink()
when this runs:
if($package === false)
return $dir . '/' . $asset;
$dir
= js
$asset
= /js/script-123456.min.js
So it returns js//js/script-123456.min.js
.
What am I doing wrong? I use the v0.0.9 because of Laravel 4.2.
Thanks!
Great package,
It will be nice if a config option can be used to skip cdn/external from the pipeline (in my case font-awesome wont work pipelined), or if a method can be invoked runtime like:
{{ Assets::reset()->add('jquery-cdn')->js() }}
{{ Assets::reset()->add(array('custom.js', 'main.js'))->pipeline()->js() }}
I'm using a css file that overrides any css plugin classes I'm loading to fit my app needs. That file needs to be loaded last, always last. Is there a way to define that file just once instead of adding it on every Controller?
Suppose I have a CSS file /css/style.css
, which contains a rule such as #id { background-image: url(img.png); }
and I use the pipeline option.
My pipeline file (e.g. /min/7c358b3d092429876a4fb752721bfca8.css
) still contains the exact same rule #id { background-image: url(img.png); }
. However this doesn't work, because img.png
is in the css
folder and not the min
folder.
The pipeline file needs to contain #id { background-image: url(../css/img.png); }
.
The Minify_CSS library seems to have an option to rewrite URLs like this (prependRelativePath
), but I can't work out how to configure/enable it. Am I missing something obvious?
First, I want to say that this is a wonderful little package. We have been using it and it helps us wonderfully. I have forked the package, however, to add a few new features. I wanted to run them by you.
Support for multiple source directories outside the /public/ path.
So, through configuration or runtime manipulation, it would be possible to pipeline css and javascript from:
/app/assets/js
/app/assets/css
into
/public/
Even more, the user could add multiple source directories if using modules.
/app/modules/modlue1/assets/ *
/app/modules/module2/assets/ *
app/assets/ *
would all pipeline to
/public/
This is a common workflow, especially for those using Javascript MVC frameworks like Ember.js. We do use ember.
Hello,
While attempting to configure a new laravel project (migrating my L4 project to L5) I now receive the error:
ErrorException in Manager.php line 457:
mkdir(): Permission denied
I believe that my permissions are set correctly on my public folder, and this issue only occurs when pipeline is set to true. Additionally, I have not deployed my new project yet, and have only been using the 'php artisan serve' command to test.
I have not changed any of the directories in the config, as my assets are located within public/js and public/css, and the 'min' folder should still be created within their respective folders.
Any help on this matter would be greatly appreciated, as I really would like to use the pipeline feature!
Once I pipeline, all css files are minified and served from min directory. The problem I am facing is it's not able to find font files, images.
So I have to rewrite paths in css files or keep my images,fonts etc., in min directory.
For example:
public/css/vendor/bootstrap/css/bootstrap.css
public/css/vendor/bootstrap/fonts/..
public/css/custom.css
I do:
Assets::add('vendor/bootstrap/css/bootstrap.css');
Assets::add('custom.css');
The file in min dir has same paths for fonts so it can't find.
Any advice on how to solve this problem?
Hi,
if i use your package i cant upgrade to Laravel 4.1 because the dependencies are still require "illuminate/support: 4.0.x". Have you tested it with 4.1? If so, can you upgrade to dependencies so we can upgrade to 4.1.
Thanks
Just a heads up, I'm using your excellent package in the dev branch of what will be Laravel 5.0 in November. The only compatibility issue I've found is that the publish config has changed to
php artisan publish:config stolz/assets
Referencing Assets::add() in a controller returns the following error in L5.
Class 'App\Http\Controllers\Assets' not found
Where is the assets folder that i can put my css, js files. Maybe I dont understood right that part please help me. Or I have to create an assets folder in the app folder. I'm using larval framework.
Thanks.
What I'm trying to do is have a collection of base JS & CSS that gets included via the autoload assets array. I want this "base" collection to get pipelined. Then as I manually add javascript via Asset::add() for specific pages, that should not get pipelined into the main file. It could get pipelined into a separate file specific files as long as it's independent of the main base collection. Is this possible?
First, thank you for your plugin, it is very good and I use it for my most recent project.
I would like to have support for two different pipelines, one for CSS and one for JS.
I happen to modify the css without touching the JS files ...
When I increment the pipeline, the JS minified file is recreated.... and I don't like it.
Also, the ->reset->addJs/css trick is cumbersome for a plugin that aims to do it easy... and yells for some more flexible config, eventually.
I would like to have support for exceptions (i.e. files that are NOT minfied and inserted as they are...) in config.
For example I use Google maps v3 JS api.
If I add it in a collection in config.php, it will not work, simply because the library is not working LOCALLY (unlike jQuery, bootstrap etc), and must be on the Google servers.
'googlemaps' => [
['http://maps.googleapis.com/maps/api/js?v=3.exp', insert_as_it_is => true] //// I WOULD LOVE TO CAN BE ABLE TO DO THS
In this case, Assets::js(), should output ideally both the google maps script NOT MINIFIED, PIPELINED and the rest of the scripts, pipelined.
Thank you once again!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.