EllisLab text mark
Advanced Search
1 of 3
1
   
Carabiner 1.0: Asset Management Library
Posted: 28 January 2009 10:23 PM   [ Ignore ]
Avatar
Joined: 2009-01-21
109 posts

NOTE: Carabiner has been updated to version 1.42.  See the new thread for more info and to download.

Cara-wha?
Carabiner is a library for managing JavaScript and CSS assets.  It’s different from others that currently exist (for CodeIgniter, anyway) in that it acts differently depending on whether it is in a production or development environment.  In a production environment, it will combine, minify, and cache assets. (As files are changed, new cache files will be generated.) In a development environment, it will simply include references to the original assets.


Requirements
Carabiner requires the JSMin and CSSMin libraries that I previously ported.  They’re both included in this release.  You don’t need to load them, unless you’ll be using them elsewhere.  Carabiner will load them automatically as needed. (Note: the only reason they’re included as separate libraries is that it allows you to use them independently of Carabiner.  If desired, you could probably include them in the carabiner.php file itself.  You’d have to edit the Carabiner functions, but it could work.)


GZIP, Packer, etc.
Carabiner does not implement GZIP encoding, because I think that the web server should handle that.  I think GZIPing is important, I just prefer not to do it PHP. If you need GZIP in an Asset Library, AssetLibPro does it.  I’ve also chosen not to implement any kind of JavaScript obfuscation (like packer), primarily because of the client-side decompression overhead. More about this idea from John Resig. However, that’s not to say you can’t do it.  You can easily provide a production version of a script that is packed.  However, note that combining a packed script with minified scripts could cause problems.  In that case, you can flag it to be not combined. (See usage below) Also, that’s not to say that I won’t port a PHP Version and include it eventually.


Inspiration/License
Carabiner is inspired by Minify, PHP Combine by Niels Leenheer and AssetLibPro by Vincent Esche, among other things. Carabiner is released under a BSD License.


Usage
Load the library as normal:

$this->load->library('carabiner'); 


Configure it like so:

$carabiner_config = array(
    
'script_dir' => 'assets/scripts/'
    
'style_dir'  => 'assets/styles/',
    
'cache_dir'  => 'assets/cache/',
    
'base_uri'   => $base,
    
'combine'    => TRUE,
    
'dev'        => FALSE
);
        
$this->carabiner->config($carabiner_config); 


There are 8 relevant configuration options.  The first 4 are required for Carabiner to function, the last 4 are not.

script_dir
STRING Path to the script directory.  Relative to the CI front controller (index.php)
 
style_dir
STRING Path to the style directory.  Relative to the CI front controller (index.php)
 
cache_dir
STRING Path to the cache directory.  Must be writable. Relative to the CI front controller (index.php)
 
base_uri
STRING Base uri of the site, like ‘http://www.example.com/’


dev
BOOLEAN Flags whether your in a development environment or not.  See above for what this means. Defaults to FALSE.
 
combine
BOOLEAN Flags whether to combine files.  Defaults to TRUE.
 
minify_js
BOOLEAN Flags whether to minify javascript. Defaults to TRUE.

minify_css
BOOLEAN Flags whether to minify CSS. Defaults to TRUE.

 

Add assets like so:

$this->carabiner->js('scripts.js');
        
$this->carabiner->css('reset.css');
        
$this->carabiner->css('admin/styles.css'); 


To set a (prebuilt) production version of an asset:

// pass a second string to the method with a path to the production version
$this->carabiner->css('wymeditor/wymeditor.js''wymeditor/wymeditor.pack.js' ); 


And to prevent a file from being combined:

// pass a boolean FALSE as the third attribute of the method
$this->carabiner->css('wymeditor/wymeditor.js''wymeditor/wymeditor.pack.js'FALSE ); 


You can also pass arrays (and arrays of arrays) to these methods. Like so:

// a single array
$this->carabiner->css( array('base.css''base.prod.css') );
        
// an array of arrays
$js_assets = array(
    array(
'dev/jquery.js''prod/jquery.js'),
    array(
'dev/jquery.ext.js''prod/jquery.ext.js'),
)

$this->carabiner->js$js_assets ); 


To output your assets, including appropriate markup:

// display css
$this->carabiner->display('css');
    
//display js
$this->carabiner->display('js'); 


Finally, since Carabiner won’t delete old cached files, you’ll need to clear them out manually. To do so programatically:

// clear css cache
$this->carabiner->empty_cache('css');
        
//clear js cache
$this->carabiner->empty_cache('js');
        
// clear both
$this->carabiner->empty_cache(); 

Please let me know what you think!  If there’s something you would like changed or ad

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
Posted: 28 January 2009 10:30 PM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2009-01-21
109 posts

I forgot to mention that a feature I would like to add is asset grouping.  That is, allowing assets to be grouped (and then combined, minified, and output in those groups).  It’s not in this version because it’s not something I’ve needed, but I’ll get to it eventually.  If you need/want that, let me know.  I could move it up on the list if there was demand for it.

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
Posted: 29 January 2009 12:26 AM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-20
68 posts

This looks great dude!
Is there any advantage over AssetLibPro?

Thank you in advance!

 Signature 

http://www.demogar.com

 
Posted: 29 January 2009 12:56 AM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2009-01-21
109 posts

Well, that would probably be a matter of opinion.  I looked at AssetLibPro before i built Carabiner, and there were a few things I didn’t like about it. They are:

Use of a Config File
I think separate config file is a little overkill in this instance.

Unmodified CSS Tidy and JSMin
I rather dislike the idea of including tools in my CI application that aren’t directly usable within it. Plus CSSTidy is big.  I chose to port JSMin and a CSS minification class to CI directly, and use them the ‘CI way’ within Carabiner.

PHP Cached Files
AssetLibPro stores it’s cached files as PHP files.  I don’t like the idea of PHP being interpreted for static assets. I also don’t like how the file reference doesn’t have a proper (js|css) extension. This is the only way to do some of the things it does (like GZIP and far-future headers), so I’m not saying it’s wrong.  I just don’t like it.

Otherwise, the thing that I wanted most that AssetLibPro didn’t provide was the ability to do different things based on the environment.  Part of my standard CI install is an application-wide flag for development vs production environment.  Carabiner is set up using that flag, so I never have to think about it.  When I’m in development, the full scripts/stylesheets are in use, so I can easily debug, etc.  Then, when I move things to production, assets are automatically combined/minified/cached. So, to answer your question directly:

The biggest advantage of Carabiner over AssetLibPro is the fact that it automatically reacts differently based on where you are in the development cycle.

All that being said, AssetLibPro is really nice. There is a lot I like about it, and there’s a lot that it does that Carabiner does not (GZIP, Far-Future headers, asset grouping).  There’s a reason I listed it as inspiration!

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
Posted: 29 January 2009 01:07 AM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-20
68 posts

You’ve convinced me, cause I also dislike the idea of PHP files for js and css.
I’ll give a try to Carabiner, it looks really usefull.
I think I had a problem with AssetLibPro and CodeIgniter gzip.. is there any problem with Carabiner and CI gzip too?

 Signature 

http://www.demogar.com

 
Posted: 29 January 2009 01:16 AM   [ Ignore ]   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2009-01-21
109 posts

I think I had a problem with AssetLibPro and CodeIgniter gzip.. is there any problem with Carabiner and CI gzip too?

Do you mean Output Compression?  If so, I’m not sure whether there would be any problems.  I would think not, but I can’t say for sure.

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
Posted: 29 January 2009 01:24 AM   [ Ignore ]   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2008-07-20
68 posts

I’ll give a try tomorrow (it’s 23:24 here) and I let you know smile

 Signature 

http://www.demogar.com

 
Posted: 29 January 2009 02:26 AM   [ Ignore ]   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Wonderful stuff. Great addition to the framework, and definitely often requested

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 29 January 2009 03:48 AM   [ Ignore ]   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2007-01-10
63 posts

Thanks!
It’s looking sweet. I’ll give it a spin.
Any plans to include asset grouping in the future?

—trice

 Signature 

http://www.polarblau.com

 
Posted: 29 January 2009 07:58 AM   [ Ignore ]   [ # 9 ]   [ Rating: 0 ]
Avatar
Joined: 2007-06-11
2985 posts

This is a pretty handy backend to the lovely syntax of my asset helper. I will be combining them and I get to keep my modular folder structure, but gain minification.

 Signature 

————————
Blog | Twitter | GitHub | BitBucket
————————-
PyroCMS - open source modular CMS built with CodeIgniter
PancakeApp - Simple, hosted invoicing/w project management

 
Posted: 29 January 2009 10:23 AM   [ Ignore ]   [ # 10 ]   [ Rating: 0 ]
Avatar
Joined: 2009-01-21
109 posts

Trice: It’s definitely on the list.  I just need to think through how to best implement it…

Pyro: Let us know how that works for you!  I’ve not used your Asset Helper, but a quick glance makes me think that you might run into issues with caching.  Currently, Carabiner uses only one cache folder, and filenames are built based on the most recent last modified date of the files, plus an md5 hash of all of the filenames.  I’m not sure that would play nice with your helper, but I hope it works out.  Let me know if you need any illumination about how/why Carabiner does what it does.  You also might look at the two minification libraries separately.  They might be easier to hook into your helper.

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
Posted: 30 January 2009 08:47 AM   [ Ignore ]   [ # 11 ]   [ Rating: 0 ]
Joined: 2008-07-25
54 posts

Great library, thanks.

 
Posted: 30 January 2009 06:22 PM   [ Ignore ]   [ # 12 ]   [ Rating: 0 ]
Joined: 2008-01-30
159 posts

A great addition would be is to give screen or print with a css asset.

 
Posted: 01 February 2009 03:35 AM   [ Ignore ]   [ # 13 ]   [ Rating: 0 ]
Avatar
Joined: 2007-04-28
12 posts

Very good library. But you have some bugs in it.

When you try to pass array to $this->carabiner->css method, array offset error appears.
You need to use for each function inside $this->carabiner->js and $this->carabiner->css to when you pass array. For example:

if( is_array($dev_file) ){
        
        
if( is_array($dev_file[0]) ){
        
            
foreach($dev_file as $file){
                
                $this
->_asset('js'$file[0]$file[1]$file[2]);
            
            
}
            
        }else{
            
// you are missing this part
            
foreach($dev_file as $file){                
                $this
->_asset('js'$file$prod_file$combine);
            
}
            
        }
        
    }else{
    
        $this
->_asset('js'$dev_file$prod_file$combine);

    


One more bug is when you set combine = true false and dev = false.
In that case, js or css file path isn’t returned correctly.
Solution (arround line 484), you need to set $f = $f instead $f = $this->cache_uri . $f:

elseif(!$this->combine && $this->minify_css// we want to minify, but not combine
                    
                    // minify each file, cache it, and serve it up. Oy.
                    
foreach($this->css as $ref):
                        
                        if( isset(
$ref['prod']) ){
                        
                            $f 
$this->style_uri $ref['prod'];
                        
                        
else {
                        
                            $f 
filemtimerealpath$this->style_path $ref['dev') ) . md5($ref['dev']) . '.css';
                        
                            if( !
file_exists($this->cache_path.$f) ){
    
                                $c 
$this->_minify'css'$ref['dev');
                                
$this->_cache($f$c);
                            
                            
}
                            
// $f = $this->cache_uri . $f;
                            
$f $f;

                        
 
Posted: 01 February 2009 07:28 AM   [ Ignore ]   [ # 14 ]   [ Rating: 0 ]
Avatar
Joined: 2008-09-11
758 posts

hi on windows server I’m facing the following problem. while loading js and css assets. right now im loading js but it is same for css also.

A PHP Error was encountered

Severity
Warning

Message
file_get_contents(G:\umer_data\AppServ\www\dfwstatic/js/niceforms-default.css) [function.file-get-contents]failed to open streamNo such file or directory

Filename
libraries/carabiner.php

Line Number
611 
 Signature 

CI,JQuery,Google Maps | widget with CI loader | Thumbnail, Image Resize, Image Crop Helper | CI shortcode

 
Posted: 02 February 2009 11:44 AM   [ Ignore ]   [ # 15 ]   [ Rating: 0 ]
Avatar
Joined: 2009-01-21
109 posts

DannyD:

Thanks for the feedback!  The first bug you provided comes from not setting all 3 possible attributes in your array.  Your fix doesn’t quite work, but something like this will:

if( is_array($dev_file) ){
            
            
if( is_array($dev_file[0]) ){
            
                
foreach($dev_file as $file){
                    
                    $d 
$file[0];
                    
$p = (isset($file[1])) ? $file[1] '';
                    
$c = (isset($file[2])) ? $file[2] $combine;

                    
$this->_asset('js'$d$p$c);
                
                
}
                
            }else{
                
                $d 
$dev_file[0];
                
$p = (isset($dev_file[1])) ? $dev_file[1] '';
                
$c = (isset($dev_file[2])) ? $dev_file[2] $combine;
                
                
$this->_asset('js'$d$p$c);
                
            
}
            
        }else{
        
            $this
->_asset('js'$dev_file$prod_file$combine);
    
        

Your second bug is also a great find. However, you don’t need to set

$f $f

  You can just remove that line altogether.

I’ll be updating the library to include these fixes.  Thanks!

umefarooq:

I haven’t got access to a Windows server to test on, but I think this might fix your problem.  In the function called _minify, change both lines that look like this:

$contents file_get_contents($this->style_path.$file_ref'r')


to this:

$contents file_get_contentsrealpath($this->script_path.$file_ref) )

I think that will fix your problem, but I’m not sure.  Let me know if it does, and I’ll update the library with those fixes as well.

Note that you’ll probably get the same error again, but from a different part of the library. There are four calls to file_get_contents in the _combine function, that will need a similar change.

Thanks for the feedback, everyone.

 Signature 

Do you use CSS or JavaScript? Carabiner makes your life easier.  I promise.

CI-Disqus makes playing with the Disqus API a snap.

 
1 of 3
1