Welcome Guest, Not a member yet? Register   Sign In
Creating javascript files with access to CodeIgniter functions like base_url()
#1

[eluser]aidehua[/eluser]
(I'm new to CodeIgniter so stop me if I'm saying or doing something stupid...)

I have a view called 'page_elements/header' which contains the parts of my HTML pages that come before the content -- that's to say stuff like <head>, <title>...</title>, <link rel="stylesheet"... />, </head>, and the opening <body> tag.

Within the Controller, I pass some variables for the title text and the stylesheet href, like this:

Code:
$data['title']='Lovely little form';
$data['stylesheet']='style_form';
$this->load->view('page_elements/header',$data);

Then, in the view, I have this:

Code:
<html>
<head>
<title><?= $title?></title>
</head>
<link rel='stylesheet' href='<?=base_url()?>css/<?=$stylesheet ?>.css' type='text/css' />

So far so good. Then I wanted to be able to add [removed] tags to the header view, so I added

Code:
$data['javascripts']=array('script1','script2');

to the controller, and

Code:
<? if(isset($javascripts)):?>
<? foreach ($javascripts as $script): ?>
[removed][removed]
<? endforeach; ?>
<? endif; ?>

And that is fine too.

But then I wanted to have a javascript file which would have access to the CI base_url() function. Obviously if I wrote the script directly in the view, there would be no problem, but by putting the script in a file outside the CI application flow, it no longer has access to things like base_url() which derive from the URL helper.

I thought of a couple of ways of getting round this.

One would be to leave the .js file where it is, but change its extension to .php, and then pass it the base_url() value in the querystring. But that didn't seem very tidy.

In the end I settled on giving JavaScripts that needed access to CI functions their own Controller class (I called it get_js.php)

Code:
<?  
class Get_js extends Controller{
    
    function Get_js(){
        parent::Controller();
    }
    
    function _remap($file_name=''){
        $this->index($file_name);
    }
    
    function index($file_name=''){
        if($file_name){
            $this->load->view("js_for_parsing/".$file_name);
            }
    }
}
?>

So, then, in the view which creates the JavaScript ('js_for_parsing/somescript.php'), I can get the base_url():

Code:
<?$this->load->helper('url');?>
function somefunction(){
var baseurl = '<?= base_url() ?>';
// do whatever....
}

Finally, I adapted the original controller which calls the 'header' view so that it can distinguish between 'ordinary' Javascript files, which live in the /javascript folder, and Javascript files which need CI functions, which are called through the Get_js Controller class:

Code:
$data['javascripts']=array('someOrdinaryJS',array('someJSwhichNeedsCIfunctions',1));
$this->load->view('page_elements/header',$data);

And adapted the code in the 'header' view so that it can distinguish between the two sorts of [removed]

Code:
<? if(isset($javascripts)):?>
<? foreach ($javascripts as $script): ?>
    <? if(!is_array($script)): ?>
        [removed][removed]
    <? else: ?>
        <? if($script[1]): ?>
        [removed][removed]
        <? else: ?>
        [removed][removed]
        <? endif ?>
    <? endif ?>    
<? endforeach; ?>
<? endif; ?>

Which outputs the following HTML [I've changed 'p' to 'q' in 'script' because otherwise it's auto-removed by this wiki]:

Code:
<scriqt type="text/javascript" src="http://[base_url]/javascript/someOrdinaryJS.js"></scriqt>
<scriqt type="text/javascript" src="http://[base_url]/get_js/someJSwhichNeedsCIfunctions"></scriqt>

That seems to work.

Now: somebody tell me I could have achieved all of that with 2 lines of code... Smile
#2

[eluser]geshan[/eluser]
use a templating library like ocular, http://code.google.com/p/ocular/ and just print base_url in the template file or the view

Code:
[removed]
var base_url = &lt;?php echo base_url(); ?&gt;
</scirpt>

then access the base_url variable later in other files. Or use an object oriented approach but you will need a link between php and JS somehow.
#3

[eluser]mattpointblank[/eluser]
I used the method of placing javascript in a dynamic PHP file which can then access base_url() etc. I found this a little kludgy so geshan's method above seems smarter, although I don't know what you need the library for.
#4

[eluser]aidehua[/eluser]
[quote author="mattpointblank" date="1257175482"]I used the method of placing javascript in a dynamic PHP file which can then access base_url() etc.[/quote]

Yes, I tried simply placing the JavaScript in a file within [CIroot]/javascripts, and calling it myscript.php rather than myscript.js.

But since it was being called directly by a <scriqt type="text/javascript" src="/myscript.php"></scriqt> tag, rather than through the CI URI system, the PHP code within myscript.php wouldn't have access to base_url() and other CI functions, objects, etc.

Or that's what I thought. Was I wrong?

Anyway, as you say, Geshan's answer looks simple. (Though I'm also not sure what you need the library for.)

The wiki has munched Geshan's code a bit, but I guess he's saying I ought to use this in my header.php view (with p replaced by q in my <scriqt> tags):

Code:
<scriqt>
//Set the base url
var base_url = &lt;?php echo base_url();?&gt;
</scriqt>
<scriqt type="text/javascript" src="/javascripts/myexternalscript1.js"></scriqt>
<scriqt type="text/javascript" src="/javascripts/myexternalscript2.js"></scriqt>

My external JavaScript file(s) will now have access to base_url as a JavaScript variable, and so don't need to try and access it as a PHP/CI function. About 100 times easier than my original round-the-houses approach...

Thanks, guys Smile
#5

[eluser]Phil Sturgeon[/eluser]
You really dont need to make it this complicated. This is how I do it on PyroCMS which is perfectly portable.

Code:
<scr1pt type="text/javascript">
    var APPPATH_URI = "&lt;?php echo $this->config->item('asset_dir');?&gt;";
    var BASE_URI = "&lt;?php echo BASE_URI;?&gt;";
[removed]
        
&lt;?php echo css('style.css').css('layout.css', '_theme_');?&gt;
    
&lt;?php echo js('jquery/jquery.js'); ?&gt;
&lt;?php echo js('facebox.js').css('facebox.css');?&gt;
        
&lt;?php echo js('front.js'); ?&gt;

The other option is to get Apache parsing your JavaScript but that can be slow as hell.

That is done by adding the following into .htaccess:

Quote:AddHandler x-httpd-php5 .js
#6

[eluser]aidehua[/eluser]
Thanks Phil.

I've not seen those css() and js() functions which you call in the example you give. Is there documentation for them?

I'm guessing they're doing something like:

Code:
&lt;? echo js('jquery/jquery.js'); ?&gt;

OUTPUT: <scr1pt type="text/javascript" src="jquery/jquery.js></scr1pt>

Is that right?
#7

[eluser]Phil Sturgeon[/eluser]
Something like that. The link is in my signature. :-)
#8

[eluser]mattpointblank[/eluser]
[quote author="aidehua" date="1257177598"][quote author="mattpointblank" date="1257175482"]I used the method of placing javascript in a dynamic PHP file which can then access base_url() etc.[/quote]

Yes, I tried simply placing the JavaScript in a file within [CIroot]/javascripts, and calling it myscript.php rather than myscript.js.

But since it was being called directly by a <scriqt type="text/javascript" src="/myscript.php"></scriqt> tag, rather than through the CI URI system, the PHP code within myscript.php wouldn't have access to base_url() and other CI functions, objects, etc.

Or that's what I thought. Was I wrong?[/quote]

I just included the javascript.php file itself (as a view), which contained the opening/closing [removed] tags.
#9

[eluser]geshan[/eluser]
I just suggested the library(Ocular) to make the templates better organized and inclusion of javascript and css whenever necessary. thanks.
#10

[eluser]CroNiX[/eluser]
another easy solution is just to rename your js scripts with php instead of js extension. Then for first line of js file output correct php 'text/javascript' headers. You can now use any php within your js file. Same works for css (using appropriate header there too).




Theme © iAndrew 2016 - Forum software by © MyBB