Subscribe

174

Fans

ON FACEBOOK

Search

Email

  • Memphis, TN 38103 U.S.A. Otto 240cf86e-5cad-11dc-8314-0800200c9a66

Facebook

Amazon

Buy Otto a Beer

Currency:

Amount:

Website(Optional):

Get Otto a Gift

My Amazon.com Wish List
Text

9 Feb 2010-02-09 11:24

Don’t include wp-load, please.

Time for Otto’s general griping: WordPress plugin programming edition.

Here’s a practice I see in plugins far too often:

  1. Plugin.php file adds something like this to the wp_head:
    <script src='http://example.com/wp-content/plugins/my-plugin/script.js.php'>
  2. Script.js.php has code like the following:
    <?php
    include "../../../wp-load.php";
    ?>
    ... javascript code ...
    

The reason for this sort of thing is that there’s some option or code or something that the javascript needs from the database or from WordPress or whatever. This PHP file is, basically, generating the javascript on the fly.

Usually, the case for this turns out to be something minor. The code needs the value from an option, or some flag to turn it on or off. Or whatever.

Problem is that finding wp-load.php can be a bit of a chore. I’ve seen extreme efforts to find and load that file in plugins before, including searching for it, examining the directory structure to make decent guesses, etc. This sort of thing has existed even before wp-load.php came around, with people trying to load wp-config.php themselves and such.

But the real problem is simpler: This is always the wrong way to do it.

Why this is wrong

  1. You don’t have the first clue where wp-load.php actually is. Both the plugin directory and the wp-content directory can be moved around in the installation. ALL the WordPress files could be moved about in this manner, are you going to search around for them?
  2. You’ve instantly doubled the load on that server. WordPress and the PHP processing of it all now have to get loaded twice for every page load. Once to produce the page, and then again to produce your generated javascript.
  3. You’re generating javascript on the fly. That’s simply crap for caching and speed and such.

The right way? Well, there’s two options.

Right Way the First

Generate your options separately, put them in using wp_print_scripts.

Examine this pseudo-code:

add_action('wp_print_scripts','myscript');
function myscript() {
?>
<script type="text/javascript">
  var plugin_option= <?php echo json_encode(get_option('plugin_option')); ?>;
</script>
<?php
}
wp_enqueue_script('myscript','...myscript.js',...);

Basically, the plugin option value is inserted directly into the page. The myscript.js file that loads shortly afterwards can use this value however it likes.

Why this is better:

  1. No searching for wp-load.php.
  2. The javascript is static, only your options are variable. No added load on the site.
  3. Static scripts mean you get great speed from caching.

Sidenote: Note the use of json_encode? You should always use this when producing javascript variables from PHP variables. It handles quoting and escaping and everything for you. It can even turn PHP arrays into javascript arrays nicely! Handy for storing all your options in one place.

What if you have a ton of plugin options though? What if you really WANT to generate that javascript on-the-fly?

Right Way the Second

Generate the javascript from a call to WordPress itself, not to a separate file.

Examine this pseudo-code:

add_filter('query_vars','plugin_add_trigger');
function plugin_add_trigger($vars) {
    $vars[] = 'plugin_trigger';
    return $vars;
}

add_action('template_redirect', 'plugin_trigger_check');
function plugin_trigger_check() {
	if(intval(get_query_var('plugin_trigger')) == 1) {
	?>
function javascript_code() {
...
}
<?php
	exit;
	}
}

That code does something a little clever. Basically it’s adding a new query variable to be used as the “trigger”. When the trigger gets pulled, a bunch of javascript is generated, then the code *exits*, stopping WordPress from proceeding any further.

So, with that code in a plugin, a call to http://example.com/?plugin_trigger=1 will now produce your javascript code. This is running entirely within the content of a WordPress call, so you get all the WP functions and database access with which you can generate your code as well.

Thus, you can happily put your

<script src="http://example.com/?plugin_trigger=1">

code into the page and it’ll load up that “file” just fine.

Why this is better:

  1. No searching for load.php
  2. … Well, okay, there is no other reason. The load problem still exists, and your caching issues still exist. You’re programmatically generating code here, after all. It’s not a particularly good practice to do. Still, sometimes this is easier and faster to develop, even if it’s never actually “necessary”.

Also see that while I’m using the number 1 there as the value I’m checking for, that value can be anything you like. If you want to be a smartass about it and have all sorts of different things that could be generated, you can do them all with that one trigger. It’s still a generally bad idea because of the added load, but hey, maybe you have a legitimate reason. I’ve seen one or two valid reasons to do this before.

Wrap up

Also note all of the above also applies to “generating” CSS code. It’s just as unnecessary. Usually more so.

So please, stop including wp-load. It’s just wrong. Let WordPress load itself, and make your plugin do the output it needs to produce in the right places.

Tags: , , , , ,
Shortlink:

Posted in Geekery, General Spew, Hackery, Programmery | 47 Comments » -

32 Tweets

47 Comments

Leave a Reply

Connect with Facebook

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Additional comments powered by BackType