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).
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.
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:
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.
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)
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.
Optionally define some groups for Minify, to make script loading even nicer
Optionally add the baseurl and siteurl variables (and whatever other values you may need) to the javascript output
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.
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.
Related
What is the difference between following two ways of including a javascript file:
1. Including javascript file directly in the main php page, as:
In main.php : <script type="text/javascript" language="javascript" src="custom-script.js"></script>
versus
2. Including javascript file in a php subpage, which further is included in the main php page, as:
In main.php : <?php include('subpage.php'); ?>
and In subpage.php : <script type="text/javascript" language="javascript" src="custom-script.js"></script>
The only probable difference would be placement of the code which include the js file and hence the difference might be visible on final output HTML, if the functions are dependent in multiple js files.
Note: The placement of the code does matter in execution of the functions dependent on the js
It makes no difference in the end. Either way, the JS file is included by the client's browser.
This is not going to make any difference to the browser.
There is no difference, unless using the sub page makes the <script> tag appear further down the page, in which case the browser won't execute it until it reaches that point.
As far as the browser is concerned, everything is "one page", it is not aware of any includes or divisions across PHP scripts.
It makes no difference to the browser.
However for architecture style is better to have all JS inside separated php file that is included elsewhere.
This way you'll have much better control what you are including (one place control). If you want to add another script later on, you can just add it to subpage.php (better to name this something like javascript-includes-header.php) and you will have another script included on all pages. Same goes for removing a script or if you figure out that script include order is important.
During a site scraping, I discovered several scraped functions in JavaScript that I need to modify because the code uses a relative path:
/UserControl/bla
I need to modify it to use absolute path:
www.domain-name.com/UserControl/bla
The problem is, those functions written in a separate file included by the scraped page. So far I can only stream that file using the PHP function file_get_contents(), change the part I need using preg_replace, and insert that script in the head section of the scraped HTML. I don't have access to modify the included JavaScript file because it's on a server I don't have access to.
Is that the right way to do this?
What I do in this cases is to declare JavaScript global variables with the objective to be constant values, then, I can access this variables from my included JS files, for example:
<script>
Globals = {
absoluteUrlPrefix: "<?= getAbsoluteUrlPrefix(); ?>"
};
</script>
<script src="myjsfile.js"></script>
on myjsfile.js
...
var absoluteUrl = Globals.absoluteUrlPrefix+"/UserControl/bla";
...
preg_replace is an option, if it's just to show the web pages on your machine, you could also insert a base-path tag:
http://www.w3schools.com/tags/tag_base.asp
I'm working with my JS files, what i have now is a unique php file with JS header, if a variable is set it includes the real js file, which is fine.
The "home" page has the script tag for the php-js file:
<head>
<script type="text/javascript" language="javascript" src="bootstrap.php"></script>
</head>
the bottstrap.php file has something like:
if(isset($hostData) && !empty($hostData)) {
include('bootstrap.js');
}else {
echo "document.write('<center><bold>PLEASE DO SOMETHING...!</bold></center>');";
}
all that seems to be fine, however when viewing the source code (CTRL+U) the browser shows the "bootstrap.php" part as a link, if clicked it obviously redirects to http://mydomain/bootstrap.php and the js code can be easily seen, which is exactly what i don't want...
So my question is, is there any php-way to know if the file is being loaded from browser's "rendering view" or being loaded from browser's "source code view" ???
Any help is truly appreciated =)
In short, no. You can't hide your script source from your users. The best you can do is obfuscate it using tools like YUICompressor.
There's no way you can hide the javascript code. It needs to be executed by the client, and even if you try to hide it by formatting your code badly, tools like firebug can easily introspect the code and pull out the code.
To be honest I don't think you can actually hide it like that. I'm assuming the best thing you've got to go on is the useragent string but I'm assuming if you "view source" in a browser it would still send the regular headers.
The only way I can think of adding the JS include without it appearing when in view source mode is to actually load the external file via javascript (you could even break the path of the js file into variables so it isn't really human readable) which I would not advise.
If someone wants to get at your javascript they will there no is way of avoiding it.
and the js code can be easily seen, which is exactly what i don't want...
You don't want the JS to be seen, but you do want to use it???
There IS something wrong with your code though if you want the js file to be used in your page.
You need to include / require the file:
<script type="text/javascript" language="javascript" src="<?php include bootstrap.php ?>"></script>
Otherwise the browser will load the contents of the bootstrap file, but you want to run the code inside it (which can only be done at the server).
Also:
change:
include('bootstrap.js');
to
echo bootstrap.js;
EDIT
by re-reading your question (and other answers) that's exactly what you want: make your JS code invisible (correct me if wrong).
The answer to that is: No cannot be done.
You can try to obfuscate the code but it will take someone who wants to see it seconds to 'decode'.
Try using the $_SERVER["HTTP_referer"], which have the url that called this file.
I'm really sorry for disappearing from here...
The best solution I decided to implement is quite simple: don't show ANY URL or PHP files within JS code; so during last months I've used a unique PHP file to do all necessary database queries, a stored procedure generates dynamically all the URL's needed from JS.
In that way URL's vary every time and what I've named "poor logic" goes free for users to view/copy I don't mind that while server data is secure.
THANKS ALL FOR YOUR VALUABLE ANSWERS!!!
I know we can get some path with <?php bloginfo('something');?> into php files, but is it some equivalent for javascript file loaded with the enqueue_script function ?
Did wordpress change some shortcode into those files ?
EDIT : I think I did not clearly express my needs. So i want to know if wordpress had some shortcode who, placed into a js file who is loaded with the enqueue method, will be replaced by the template path. Typically i need to make some ajax call form a .php file from my template and want to avoid hard linking file
No javascript files won't be parsed as php, and as such won't process any shortcodes or php.
Why not just make your links relative. Often I find subdomaining my dev copy, removes any problems when moving a site live and broken links.
You could cheat and link to a php file, which then passes header information as Javascript. Doesn't seem very elegant though. See here.
Or you could just declare the variable in a little bit of inline Javascript and pick it up in the external JS file.
<script type="text/javascript">
var siteURL= '<?php bloginfo('url');?>';
</script>
<script type="text/javascript" src="yourscript.js"></script>
Then in yourscript.js just reference the variable 'siteURL'
You have to register scripts using wp_register_script(). Then by placing wp_enqueue_script before wp_head() it will load them in for you. The idea of using wp_enqueue_script is that you don't need to enter them all in manually, and you can load other scripts depending on whether a certain script has been loaded.
I have about 7 Javascript files now (thanks to various jQuery plugins) and 4-5 CSS files. I'm curious as to what's the best practice for dealing with these including where in the document they should be loaded? YSlow tells me that Javascript files should be--where possible--included at the end. The end of the body? It mentions that the delimeter seems to be whether they write content. All my Javascript files are functions and jQuery code (all done when ready()) so that should be OK.
So should I include one CSS and one Javascript file and have those include the rest? Should I concatenate all my files into one? Should I put Javascript my tags at the very end of my document?
Edit: FWIW yes this is PHP.
I would suggest using PHP Minify, which lets you create a single HTTP request for a group of JS or CSS files. Minify also handles GZipping, Compression, and HTTP Headers for client side caching.
Edit: Minify will also allow you to setup the request so that for different pages you can include different files. For example a core set of JS files along with custom JS code on certain pages or just the core JS files on other pages.
While in development include all the files as you normally would and then when you get closer to switching to production run minify and join all the CSS and JS files into a single HTTP request. It's really easy to setup and get working with.
Also yes, CSS files should be set in the head, and JS files served at the bottom, since JS files can write to your page and can cause massive time-out issues.
Here's how you should include your JS files:
</div> <!-- Closing Footer Div -->
<script type="application/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"></script>
</body>
</html>
Edit: You can also use Cuzillion to see how your page should be set up.
Here's what I do: I use up to two JavaScript files and generally one CSS file for each page. I figure out which JS files will be common across all of my pages (or enough of them so it's close - the file containing jQuery would be a good candidate) and then I concatenate them and minify them using jsmin-php and then I cache the combined file. If there are any JS files left over that are specific to that one page only, I concatenate, minify, and cache them into a single file as well. The first JS file will be called over a number of pages, the second only on that one or maybe a few.
You can use the same concept with CSS if you like with css-min, though I find I usually only use one file for CSS. One thing extra, when I create the cache file, I put in a little PHP code in the beginning of the file to serve it as a GZipped file, which is actually where you'll get most of your savings anyways. You'll also want to set your expiration header so that the user's browser will have a better chance of caching the file as well. I believe you can also enable GZipping through Apache.
For the caching, I check to see if the file creation time is older than the amount of time that I set. If it is, I recreate the cache file and serve it, otherwise I just get the existing cached file.
You haven't explicitly said that you've got access to a server-side solution, but assuming you do, I've always gone with a method involving using PHP to do the following:
jquery.js.php:
<?php
$jquery = ($_GET['r']) ? explode(',', $_GET['r']) : array('core', 'effects', 'browser', 'cookies', 'center', 'shuffle', 'filestyle', 'metadata');
foreach($jquery as $file)
{
echo file_get_contents('jquery.' . $file . '.js');
}
?>
With the snippet above in place, I then call the file just like I normally would:
<script type="text/javascript" src="jquery.js.php"></script>
and then if I'm ever aware of the precise functionality I'm going to need, I just pass in my requirements as a query string (jquery.js.php?r=core,effects). I do the exact same for my CSS requirements if they're ever as branched.
I would not recommend using a javascript based solution (like PHP Minify) to include your css as your page will become unusable if the visitor has javascript disabled.
The idea of minifying and combining the files is great.
I do something similar on my sites but to ease development I suggest some code which looks like this:
if (evironment == production) {
echo "<style>#import(/Styles/Combined.css);</style>"
} else {
echo "<style>#import(/Styles/File1.css);</style>"
echo "<style>#import(/Styles/File2.css);</style>"
}
This should let you keep your files separate during dev for easy management and use the combined file during deployment for quicker page loads. This assumes you have the ability to combine the files and change variables as part of your deploy process.
Definitely look into including your js at the bottom and the css at the top as per YUI recommendations as keeping the JS low has a tangible affect on the appearance of the rest of the page and feels much faster.
I also tend to copy+paste all of my jquery plugins into a single file: jquery.plugins.js then link to
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js">
for the actual jquery library.