Asset Manager Extended To Combine Different CSS Files

Posted by Damodar Bashyal on March 18, 2009

 

Today I extended my Asset Manager to combine several css into one. As i understand, YSLOW Says there should be as less http requests as possible. So i decided to add this optional feature. For now this is controlled through MY_config file located at config folder.

This is how addition config setting looks:

<?php
//do you want to combine your css file into one
//default is false
$config['cf']['combine_css'] = false;/*
 * Cache directory
 * No trailing or leading slashes (/)
 */
$config['cf']['cache_dir'] = 'cache';

?>

And on my Assets Manager I added this:

<?php
var $combine_css  = false;    
var $cache_dir = '';//process css
function echo_css($css_array = array(), $media = 'all')
{
	echo "\n<!-- START: CSS for media type $media -->";
	if($this->combine_css == true) {
			$css_array = $this->combine($css_array, 'css', $media);
	}
	else {
		foreach($css_array as $c) {
			$c = $this->get_path_url($c);
			if(isset($c['url']))
			echo "\n" . '';
		}
	}
	echo "\n<!-- END: CSS -->\n";
}
//combine assets | Currently support for css only
function combine($css_array = array(), $type = 'css', $media='all')
{
	$file_name = 'cf';
	$combined_code = '';
	foreach($css_array as $k => $c) {
		$file_name .= $c;
		$p = $this->get_path_url($c);
		if(isset($p['path'])) $combined_code .= file_get_contents($p['path']);
	}
	
	//clean filename
	$file_name = preg_replace('/[^0-9a-z]+/','',strtolower($file_name));
	
	//destination dir where combined file will be written
	$destination_dir = $this->base_path.$this->assets_dir.$this->cache_dir.'/';
	
	//if destination dir does not exists, create one
	if(!is_dir($destination_dir)) mkdir($destination_dir);
	
	//if the file already exists, delete it first
	if(is_file($destination_dir.$file_name.'.'.$type)) unlink($destination_dir.$file_name.'.'.$type);
	
	//create file and write contents.
	$oFile = fopen($destination_dir.$file_name.'.'.$type, 'w');
	if (flock($oFile, LOCK_EX)) {
		fwrite($oFile, $combined_code);
		flock($oFile, LOCK_UN);
	}
	fclose($oFile);
	
	//if successfully created combined file, display|echo this file
	if(is_file($destination_dir.$file_name.'.'.$type)) 
	echo "\n" . '<link rel="stylesheet" href="' . $this->base_url.$this->assets_dir.$this->cache_dir.'/'.$file_name.'.'.$type . '" type="text/css" media="' . $media . '" />';
}

?>
ISSUES:

if the css is in different folder i.e. assets/admin/css, assets/common/css etc and they have image url defined relative to these folder ie. assets/admin/img images then it will break because cache dir will be created at assets folder and img folders are one folder down of admin, common etc... But if i create cache dir in admin,common,... so that it doesn't break images then this will be less useful as i can't combine css from different folders because result will be same, image break for css from different folder. There is no issue if there are no images defined or images defined relative to cache folder.

TO DO:
  • Check cache file time modification and create only after certain period
  • Find a better way and flexibility for above issue.
  • Combine JS as well
  • Minify JS and CSS
  • Support for images [i.e. $this->assets->get_image('logo');]
  • and so on...
 
not published on website


QR Code: Asset Manager Extended To Combine Different CSS Files