views:

654

answers:

3

I'm developing web application using CodeIgniter. All this time, I put the custom js code to do fancy stuffs inside the view file. By doing this, I can use site_url() and base_url() function provided by CodeIgniter.

Today I want to separate all custom js code from view file into an external js file. Then it hit me, I cannot use site_url() and base_url() in the external js file. So, I had to move the js code back into view file.

I want to ask opinion, example, and best practice for this kind of problems. Do you put the custom js code inside the view, or in external js file? If you put it in external file, how do you get around the needs for site_url() and base_url() (beside of course put the absolute url that I want to avoid).

+7  A: 

I typically keep mine in an external file, but place a single line within my template (view) that declares a javascript variable called "baseurl" that can later be used by my external javascript.

<script type="text/javascript">
  var baseurl = "<?php print base_url(); ?>";
</script>
<script type="text/javascript" src="/js/scripts.js"></script>

Now my scripts.js file has access to the base_url() value via its own baseurl variable.

Jonathan Sampson
+1 for a great trick passing `base_url()` to external js file. Now it's left the `site_url()`, maybe I can use same trick, store it to js variable.
Donny Kurnia
@Donny: I would :)
Jonathan Sampson
Yes, it works. My code need to do AJAX request to some different url, so I just save all required url into a variable: `var url_1 = "<?php echo site_url('controller/method1'); ?>";` and so on.
Donny Kurnia
@Donny: Glad to hear that it works. Please consider accepting the answer if you found it helpful :)
Jonathan Sampson
Thanks for this trick! One thing to remember is to wrap your php print statement in quotes like: var baseurl = "<?php print base_url(); ?>"
Bala Clark
@nandasunu: Can't believe I forgot those. I've updated the answer. Thanks for pointing that out!
Jonathan Sampson
I have, but I guess yesterday my internet connection failed on me silently.
Donny Kurnia
A: 

Donny, if you start passing through every URL separately you will just be giving yourself a ball-ache. Why not just pass through base_url() and contcat the controller/method on the end?

You lose the ability to swap around index_page and url_suffix settings but they shouldnt really change all that often anyway.

Phil Sturgeon
Phil, I just want to make sure that if I change the `url_suffix` or `index_page` config, all url still working. That's why I insisted to use `site_url()` with controller name and method + required uri segment written as parameter instead of just concat it. I split the external js code by module, and typically I just need about 4 url max per module, so storing it into javascript global variable is enought and working well in my case.
Donny Kurnia
Additional info, for self purpose, I write all required library and variable name as a comment inside the external js file, so by reading it, I will know what library should be loaded and what variable should be initialized before loading this js file.
Donny Kurnia
+1  A: 

I would do it in a different way - js should be external, obviously, but why not take full advantage of the fact that you have an MVC framework that's perfectly suited to handle all of your javascript magic?

Here's my recipe for Javscript (and CSS) goodness with CI:

  1. Grab a copy of Minify - if you don't know it already, your life will be better. Not in a "Love at first sight / I just discovered jQuery / xkcd / unit testing" kind of way, but at least in a "Dude, prepared statements eradicate SQL injection" kind of way.

  2. Second, create a CI controller that encapsulates Minify (shouldn't be too hard, just remember to set the correct HTTP header and pass the parameters on)

  3. Optionally activate caching to make everything run blazingly fast (Minify has caching built in, but if you're already caching your CI content, you might as well use the same method here.

  4. Optionally define some groups for Minify, to make script loading even nicer

  5. Optionally add the baseurl and siteurl variables (and whatever other values you may need) to the javascript output

  6. And presto, you should now be able to load your scripts by calling the Minify-wrapper:

    <script type="text/javascript" src="/min/g=js"></script>

It's crazy fast, it's gzipped, takes just one request rather than many, it gives you full CI control over your scripts, and it even makes your source code cleaner.


Oh, and if you want to be extra nice to your source-code-peeping visitors, you could automatically add something like this to the output:

// Javascript compressed using Minify by Ryan Grove and Steve Clay
// (http://code.google.com/p/minify/)
// Human-readable source files:

// http://www.yourdomain.com/js/core_functions.js
// http://www.yourdomain.com/js/interface.js
// http://www.yourdomain.com/js/newsticker.js
// http://www.yourdomain.com/js/more_magic.js

(...)

At least that's what I do.

Jens Roland
Thanks for your suggestion. Yes, I'm looking forward to do minify on-the-fly, but haven't got time to do it in mean time. I might implement your way in my next project.
Donny Kurnia
It's really not that difficult, Minify does all the magic for you. If you're using more than 5-6 different scripts, it will be worth it. But point taken, I should probably just build it as a cookie-cutter CI library.
Jens Roland