ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Carabiner 1.4: Asset Management Library

June 01, 2009 3:30pm

Subscribe [76]
  • #16 / Jun 19, 2009 4:36pm

    topherdan1

    9 posts

    On line 654 in the carabiner class, I think that

    if( !isset($this->js[$group]) ):

    should read:

    if( !isset($this->css[$group]) ):

    Change ‘js’ to ‘css’

    This helps fixed a bug for when you define a group that is only supposed to display CSS files.

  • #17 / Jun 19, 2009 4:52pm

    tonydewan

    100 posts

    I’ve made the fix and updated the library (and download) to 1.43. Thanks for catching this issue!

  • #18 / Jun 19, 2009 5:01pm

    topherdan1

    9 posts

    Thanks for the quick fix! There are two features that I am interested in implementing on the library:

    1. Have the cache automatically rebuild when the files have changed.
    2. A smooth process for rebuilding the cache and then syncing the updated files to the a content delivery network when in production mode.

    Have any thoughts about how to implement these features?

  • #19 / Jun 19, 2009 8:17pm

    tonydewan

    100 posts

    1. Carabiner will automatically build new cache files when the files have changed.  If it’s not doing so for you, let me know.

    2. This is something I’ve been thinking about lately.  It wouldn’t be super hard to implement.  You would need to update the _cache function to do whatever is necessary to connect to your CDN (I think you could even use another library for this) and write to it. You would also need to change the style_uri and script_uri to be appropriate for your CDN.

    What CDN are you using?  I might be interested in abstracting some of this out to make working with a CDN easier…

  • #20 / Jun 20, 2009 7:56am

    topherdan1

    9 posts

    I am using Amazon’s CDN, CloudFront.

    Two options that I can think of:
    - 1. If the file is in production mode, whenever the cache is rebuilt it automatically syncs it to the CDN
    - 2. There is batch script that is run as part of syncing the file to the production server which will check if the files have change and if so rebuild the cache and synch it to the CDN

    The CDN credentials and whether a CDN is being used could be placed in the config file so that it’s simple to implement.

  • #21 / Jun 20, 2009 12:47pm

    tonydewan

    100 posts

    I don’t really think batch scripts are necessary.  You should be able to do it without that.  The thing that I think might be hard about abstracting the CDN connection is that the authentication schemes might not always be the same.  Unfortunately, I don’t know enough about different CDNs.  Then again, the simpler (and perhaps better) solution would be to just bake CloudFront support right in, and then add others later…

    I’ll think more about this and do some research.  In the meantime, I’d love to see what you come up with!

  • #22 / Jun 22, 2009 1:04pm

    quasiperfect

    132 posts

    hi

    i tried to use u’r lib but i have some problems

    i use ci on windows using wamp

    so i have c:\wamp\www as web folder

    i made a alias so now my app is installed like this

    c:\wamp\app\ with url <a href="http://localhost/app/">http://localhost/app/</a>

    and it works ok

    i took out the application folder from system
    and moved system out of app folder and changed in index.php $system_folder = “../system”;

    so now i have

    c:\wamp\system
    c:\wamp\app\application
    c:\wamp\app\cache
    c:\wamp\app\js
    c:\wamp\app\css

    in my .htaccess i have

    Options +FollowSymLinks
    Options -Indexes
    DirectoryIndex index.php
    RewriteEngine on
    RewriteBase /app/
    RewriteCond $1 !^(index\.php|imagini|css|js|cache|robots\.txt|favicon\.ico)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

    in carabiner conf i have folders defined like this $config[‘cache_dir’] = ‘cache/’;

    when i load a js it tries to write it to C:\wamp\cache\ but it should be c:\wamp\app\cache\

    any sugestion ?

  • #23 / Jun 22, 2009 3:26pm

    topherdan1

    9 posts

    I think I have Amazon S3/CDN integration with Caribinner working pretty well now. Here are the steps I took:

    1. Add an S3 library to your application/libraries folder. I used the one available here: http://undesigned.org.za/2007/10/22/amazon-s3-php-class and then customized it so that it pulled the variables from my config file. The only thing I changed in the S3.php file (which is the one to add to application/libraries) was the __construct on line 57 so that it looked like this:

    public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
          //Start Customizations
          $this->CI = get_instance();
        $accessKey = $this->CI->config->item('key_id');
        $secretKey = $this->CI->config->item('secret_key');
        //End Customizations
            if ($accessKey !== null && $secretKey !== null)
                self::setAuth($accessKey, $secretKey);
            self::$useSSL = $useSSL;
        }

    2. Next, update the carabiner config file with the following variables

    $config['key_id'] = 'XXXXXXXX'; //Your Amazon key_id
    $config['secret_key'] = 'XXXXX'; //Your Amazon secret_key
    $config['cdn_bucket'] = 'yourcdnbucket'; //The bucket that will act as your CDN
    $config['use_cdn'] = TRUE; //Enabling the CDN functions in carabiner
    $config['cdn_url'] = 'http://cdn.example.com/'; //The URL used to access your CDN

    3. Finally, modify the carabiner library in two spots:
    The _cache function should look like this:

    private function _cache($filename, $file_data)
        {
    
            $filepath = $this->cache_path . $filename;
            $success = file_put_contents( $filepath, $file_data );
    
            if($success) : 
                log_message('debug', 'Carabiner: Cache file '.$filename.' was written to '.$this->cache_path);
          
          if($this->CI->config->item('use_cdn') == TRUE)
          {
            //If it's a production environment, move the file to the Amazon S3 CDN bucket
            if($this->dev == FALSE)
            {
              $this->CI->load->library('S3');
              $this->CI->s3->putObjectFile($filepath, $this->CI->config->item('cdn_bucket'), $this->cache_dir.$filename, S3::ACL_PUBLIC_READ);
            }
          }
    
          
                return TRUE;
            else : 
                log_message('error', 'Carabiner: There was an error writing cache file '.$filename.' to '.$this->cache_path);
                return FALSE;
            endif;
        }

    The _tag function should look like this:

    private function _tag($flag, $ref, $cache = FALSE, $media = 'screen')
        {
    
            switch($flag){
            
                case 'css':
                    
                    $dir = ( $this->isURL($ref) ) ? '' : ( ($cache) ? $this->cache_uri : $this->style_uri );
            
            if($this->CI->config->item('use_cdn') === TRUE && $this->dev == FALSE)
            {
              $dir = $this->CI->config->item('cdn_url').$this->cache_dir;
            }
                    
                    return '<link type="text/css" rel="stylesheet" href="'.$dir.$ref.'" media="'.$media.'" />'."\r\n";
                
                break;
    
                case 'js':
                    
                    $dir = ( $this->isURL($ref) ) ? '' : ( ($cache) ? $this->cache_uri : $this->script_uri );
                    
            if($this->CI->config->item('use_cdn') === TRUE && $this->dev == FALSE)
            {
              $dir = $this->CI->config->item('cdn_url').$this->cache_dir;
            }
            
                    return '[removed]CI->config->item('charset').'">[removed]'."\r\n";
                
                break;
            
            }
        
        }

    That should be it. Now when you are in a production environment, anytime a new cache file is created it will automatically be loaded into Amazon S3, which can act as a CDN. Then, on the site, the files use the CDN domain instead of the normal domain. Let me know if you have suggestions on how to improve this.

  • #24 / Jun 24, 2009 10:59am

    quasiperfect

    132 posts

    solved my problem i modified the lib changed dirname(FCPATH) to just FCPATH

  • #25 / Jun 25, 2009 9:31am

    tonydewan

    100 posts

    @quasiperfect I’m glad you got it to work.

    @topherdan1 That looks like a really solid solution!  There are a few things you could change to make the code a little simpler:

    First, you can just do

    if($this->use_cdn && !$this->dev)

    instead of

    if($this->CI->config->item('use_cdn') === TRUE && $this->dev == FALSE)

    That’s because the config function is lazy, and will drink up whatever items are in the config file (or array) and make them class variables. That also applies to anyplace you use this syntax:

    $this->CI->config->item('')

    The only other thing I would do is adjust the logging in the cache function, so it looks something like this:

    private function _cache($filename, $file_data)
        {
            $filepath = $this->cache_path . $filename;
            $success = file_put_contents( $filepath, $file_data );
    
            if($success) :
                log_message('debug', 'Carabiner: Cache file '.$filename.' was written to '.$this->cache_path);
          
                if($this->use_cdn == TRUE && $this->dev == FALSE):
    
                    $this->CI->load->library('S3');
                    $cdn = $this->CI->s3->putObjectFile($filepath, $this->cdn_bucket, $this->cache_dir.$filename, S3::ACL_PUBLIC_READ);
                    
                    if($cdn){
                        log_message('debug', 'Carabiner: Cache file '.$filename.' was written to the CDN bucket '.$this->cdn_bucket);
                        return TRUE;
                    }else{
                        log_message('error', 'Carabiner: There was an error writing cache file '.$filename.' to  the CDN bucket '.$this->cdn_bucket);
                        return FALSE;
                    }
        
                endif;
          
                return TRUE;
            else :
                log_message('error', 'Carabiner: There was an error writing cache file '.$filename.' to '.$this->cache_path);
                return FALSE;
            endif;
        }

    These are all minor things, though.

  • #26 / Jun 26, 2009 12:44am

    ntheorist

    84 posts

    Just want to say great job on this lib. I’ve been toying around with building a library with the same basic functionality but this is working great for me so far (it’s been an hour 😛 )

    I only have 2 comments :

    1) integration with tinyMCE seems sticky, i got it to work finally but i have it linking to the tiny_mce.js separately. I might be doing something else wrong, but i’ll have to look in further.

    2) if you could, allow for a return value on the display function, ie

    $script_tag = $this->carabiner->display('js', TRUE);  // return as string
    $this->head->add_line($script_tag);

    i build my page head through output buffering so the echo doesn’t matter, but i think its more CI-view-esque to have that option.

    thx again!

    CC

  • #27 / Jun 26, 2009 1:12pm

    tonydewan

    100 posts

    Thanks!  I’m glad it’s working for you.

    1) I’ve had issues with other Rich Text Editors as well.  Flagging the file(s) to not be combined (or minified, frankly) should solve the problem.  Of course, this is less than ideal, but there’s sufficient complexity in those tools that I’ve been willing to accept the trade-off between my time trying to troubleshoot and the extra few kb and http request.

    2) That’s an interesting idea.  I’ll keep it mind. In the short term, output buffering is the perfect solution.

  • #28 / Jul 04, 2009 8:48am

    quasiperfect

    132 posts

    +1 for “if you could, allow for a return value on the display function”

  • #29 / Jul 14, 2009 2:21am

    Devon Lambert

    139 posts

    Hi Tony,

    Great application and extension of these different libraries in such an efficient manner. I have gotten the library to work but I am wondering how one would go about dynamically adding a js file to the head of site, based on the controller/method being called?

    I tried exploring the new “groups” feature but this only seemed to add my new js file at the top of the other js files. In turn this seemed to break my site?

  • #30 / Jul 14, 2009 2:35am

    tonydewan

    100 posts

    @dnyce I’m glad you like it.

    Adding scripts to the head of your site is as easy as calling

    $this->carabiner->display();

    in your view.

    If that doesn’t help, feel free to provide some code examples of what you’re trying to do.  You can post it here, or message me directly.

    Good Luck!

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases