Managing Assets with CodeIgniter
Posted on 23. Nov, 2009 by Shawn McCool in PHP, Web Development
This article discusses the reason behind the base_url() method and the creation of a helper file that will assist in managing images, css files, and more.
PHP code is far from the only content necessary for most web applications. Most frequently we need to include images, css files, flash files, and many other types of files. The CodeIgniter framework doesn’t contain a built-in methodology for asset management, leaving the developer to their own devices when it comes to deciding where to put this content. Every developer is going to have their own personal preference, and for the most part they’re equally valid.
The base_url() method
Imagine a scenario where you have developed a site that contains user profiles. Each user profile can have an image. The code in your view that would display the image may look something like this:
This works fine until your cool new site is bought up and now your application rests at http://www.bigcompany.com/mycoolsite. Now, you have to go through all of your code and search/replace “/images with “/mycoolsite/images while hoping that you’ve found everything and that something small won’t be missed until 500 users have seen it.
Instead, we use the base_url() method for creating absolute links. base_url() simply outputs the value of the $config['base_url'] variable that is set in your application/config/config.php file. Your new code would look like this:
Now, if you need to change the location of your site you can simply update the $config['base_url'] value in your application/config.php and your code will be updated throughout the site. For this reason it’s a good idea to use base_url() anywhere that you would use an absolute or relative url that points to your CodeIgniter site.
<a href="<?=base_url()?>admin/pages">Manage Pages</a>
The asset_url() function
We not only have to consider that our application may be moving, we need to consider how we’re keeping our static assets mobile, things like images, css files, etc. My method is to create a path_helper that contains a new function, asset_url().
if (!function_exists('asset_url'))
{
function asset_url()
{
// the helper function doesn't have access to $this, so we need to get a reference to the
// CodeIgniter instance. We'll store that reference as $CI and use it instead of $this
$CI =& get_instance();
// return the asset_url
return base_url() . $CI->config->item('asset_path');
}
}
Then, in either our config.php or in a new configuration file we would add:
$config['asset_path'] = 'system/application/assets/';
Now, we just add the path_helper and the configuration file (if you’re not using config.php) to the autoload.php file.
$autoload['helper'] = array('form', 'url', 'path');
// This line doesn't need to be use if you modified the config.php file, as it's already loaded for you.
// This line configures application/config/site.cfg to be autoloaded on every page load.
$autoload['config'] = array('site');
Now that the helper has been created, the configuration updated, and everything set to autoload we’re ready to use the asset_url() method. Here’s the new way of writing image source.
Now, the asset root folder can be moved anywhere you’d like and you’ll be able to easily move these files around. This can be very useful if users are uploading images to your live site and you wish to view them on your dev site as well. You could simply update your configuration so that instead of use base_url() it uses http://www.mysite.com/ so that asset requests hit your live site instead of the local development site.
A Quick Note on Preference
Naturally, all programmers prefer to do things differently. Some prefer the asset_url set to ‘./’ so that the images/ folder is at the same place as the CodeIgniter system/ folder. I personally prefer to place assets under the application folder as shown below:
system/application/assets/images
system/application/assets/js
system/application/assets/swf
I am of the opinion that the entirety of a site should be contained within the application/ folder, allowing for the rest of the CodeIgniter structure to be replaced (version upgrade) simply. It’s always important to consider the cost of maintaining the site in the future. It doesn’t cost any extra time to implement good practices during development but it can be very costly to retrofit a site with similar functionality, especially if there’s been personnel changes.
The mark of a professional developer is designing and developing with focus on the lifetime cost of the product.
If you have any questions or suggestions please leave a comment.
Related Posts
- Developing a Website with CodeIgniter Part 4: Admin Site CRUD
- How to Write a Better Model in CodeIgniter
- Developing a Website with CodeIgniter Part 3: The Login Process
- Developing a Website with CodeIgniter Part 1: Development Environment and Framework Configuration
- Developing a Website with CodeIgniter Part 2: Users Database Table and the User Model
Share this Post
Show Your Appreciation
If you'd like to express your appreciation for the work I've done why not buy me a coffee?Click here to donate $3 to my caffeine fund.


Hi Shawn,
I’ve been enjoying your CI series and I appreciate the all ‘best practices’ advice. I just thought that I’d mention that the form helper’s form_open function accepts 3 parameters, the first of which takes the segments that CI would then append to your base_url() value. so in your example you could use form_open(‘admin/users/edit/72′). Obviously not a huge difference but it seems a little cleaner with form_open.
@JakF
You’re absolutely right. I haven’t really gone into much detail on the form helper but I do use it in my own code to generate forms. I should probably make a post solely on utilizing the form helper and form_validation together. Thanks for the comment!
Tutorial added to thewebtuts.com
Shawn,
Thanks very much for the quick production of this tutorial…I couldn’t believe you had written up a post in response to my question. Now I have a question about this post: I’ve sucessfully used the helper you outlined above and it works perfectly for images and loading css but I’ve run into a problem where I have a stylesheet that references an image (something like (background: #00ff00 url(’smiley.gif’)) and I would like to use the asset_url() function to provide the path to the correct folder. I’ve swapped the stylesheet to be a php file with the appropriate header and everything seems to work until it reaches the asset_url(). I know the css is being parsed correctly because within my stylesheet.php file I can set a variable $pathtest to some path and use it in the background call: background: #00ff00 url(‘/smiley.gif’) and it works but when I use asset_url() it doesn’t work. Is this something about how function access works with Code Igniter? As I said before, I’m pretty new at this but I really like the asset_url() approach and I’d like to use it throughout my site so I can avoid a mixture of manual paths and flexible asset_url() paths.
Thanks
Kris
I’m been trying to decide the ‘best’ way to deal with this, myself. I’ve tried it a few ways and while, they worked, I really want to make sure that I’m sacrificing the least performance in exchange for flexibility as possible. I’ll be making a writeup on this in the next week or so, once I’ve had some time to do some benchmarking.
Maintaining performance is important to me in this case. When you transition a site, updating the CSS isn’t the issue that crawling through all of your views is. My goal in all of this is to implement something up front (that takes little to no extra effort during developement) that will reduce the chance for bugs / issues further down the road.
On the OTHER hand… JavaScript files need this functionality as well, even more than CSS since you often have many more JavaScript files on a site. I genuinely wish that CodeIgniter dealt with this out of the box.
At this point there’s definitely the question of whether or not it’s worth it. Any developer can come in and change the paths of images or post urls in CSS / JavaScript. But, it’s possible that many developers may come in and see the implemented solution and just drop a relative path into the CSS or JavaScript. This would create the exact kind of hit or miss bug that we’re trying to avoid in the first place.
I’d like to hear if anyone has an opinion on this. I’m leaning towards developing a solution and expecting the developers maintain proper documentation / notes in order to maintain the integrity of the product.
I use base_href:
<base href="” />
and my images…
Shawn,
What does the following bit of code at the top of path_helper.php do?
if (!function_exists(‘asset_url’))
@KRD
That’s an include guard. It doesn’t really need to be there. The idea is that if, for some reason, the helper gets called more than once the include guard will keep the asset_url() function from being declared more than once causing a fatal PHP error.
Hi, Shawn!
I’m trying to use your helper, but I’m facing a problem. I placed the assets exactly like in your example, but, when using the .htaccess from the codeigniter user guide, it doesn’n load anything. Can you help me with this?
Thanks!
@Constantin
Can you paste your .htaccess file here?
The following is what I use, typically.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 index.php
</IfModule>
Hi, Shawn!
Sorry, that was a silly post. I just forgot to change the path of an image and I thought it must be something wrong with the .htacces file.
Thanks for your reply!
Hi Shawn, thanks for the post.
Curious about your preference in asset locations. You say you prefer:
system/application/assets/images
system/application/assets/js
system/application/assets/swf
Though, for security purposes, shouldn’t everything in the system folder be inaccessible to the web? If you have root access it’s recommended to put your system folder outside your www public viewable folder I believe, yes? And then use the index.php to point to the system folder via server path. So:
root/system/
root/public_www/.htaccess
root/public_www/index.php
root/public_www/css/
root/public_www/images/
root/public_www/js/
If you don’t have access to that non-public root level on your host (like some cheap shared hosts) then you can use .htaccess to deny public access to the entire system folder. (More info: http://codeigniter.com/wiki/mod_rewrite/) Which means public assets like images, css, js etc should not be in the system folder.
So this would mean:
/.htaccess
/index.php
/css/
/images/
/js/
/system/
Thoughts? Considerations for folks reading this post.
—-
Also a minor point: I think folks suggest using:
vs the shortcut as some server hosts don’t have php syntax shortcuts enabled.
—–
Re: creating a helper ‘asset location’ variable: I think my preference is to keep the app extremely simple and dealing with the rare structure change in another method if it were to ever come up:
I wonder if an alternative to creating a new helper item: if you just used the traditional images/ path in your views and if you had to change it to say, my_new_folder/new_images/ that it might be feasible to open your views in a code editing text editor and do a simple replace of images/ with my_new_folder/new_images/ using the text editor’s “replace in all documents”. Even if theer are dozens and dozens of views it would just take seconds.
@NAT
My personal preference is to put the assets folder into your application folder. You can then move the system folder outside of the web root and then link system/application/assets to public_html/assets. Sometimes you’re faced with limitations and you just have to deal with that in whatever way you can. Naturally, part of working with clients is designing things around their needs and resources. If you create a path helper to prevent making relative calls then moving the site to a server with these limitations will pose no real extra costs in the context of storing assets in different folders.
There’s another big reason that I like to use the asset_url() function. Imagine that your website has use profiles and users can upload their own images. Those images exist on the live server and not on your local server. You could adjust your asset_url() to point to the live server so that even when developing on your local server you’ll be able to see the images. Really, this is an incomplete solution for most situations and it’s something that should be considered for every site individually. This is the kind of thing that has to be hammered out in the beginning before everything starts being developed. Thought has to be put into the complete lifecycle of the site lest money be lost making changes later.
Feel free to use <?php instead of <?. Future versions of PHP will discontinue allowing short tags. You’ll still see me using short tags in my views as, in my opinion, it’s much easier for people to read (think designers). CodeIgniter has a configuration option to rewrite short tags automatically.
Thanks for commenting.
Whoops – didnt allow the php I wrote:
–?php echo base_url()?– preferred over –=base_url()?–
Where “–” = brackets.
@Shawn: “You could adjust your asset_url() to point to the live server so that even when developing on your local server you’ll be able to see the images.”
Yes, I’ve seen instances w/ sites using user-gen content where having that would be nice — ie: a config to define solely the image asset path. Yeah, true, that’s a case where I see the benefit.
True. True.
Loving this tutorial. Exactly what I needed.
And really, this stuff should be in the core I think.
Hi, Shawn, very nice tutorial, I am loving it.
But when I try with SWFs, I found Codeigniter seems to have some problem in SWF. I made a SWF file using flex,and when I embedded in the codeigniter view, the background color block appears and the page is always in loading status, but nothing comes out.
Do you know how to deal with that?
@Larry
Try to load each of the important files separately by command line. CodeIgniter shouldn’t cause any trouble with this. If you can individually load each of the elements then you shouldn’t have any issues.
hi, Shawn, I don’t get your meaning. What shall I do to load each of the important files separately by command line?
I have a structure like:
- WebProject
– system
– application
– assets
– swf
– ToBeEmbedded.swf
I followed your steps and found it’s working really fine with other kind of assets, but just swfs are not coming out.
Do I need extra configs or steps?
Thanks a lot.
hi, Shawn, I just make it! Thanks for your help!
Hi Shawn,
I appreciate the post. FYI, it looks like the code snippets are being filtered.