Using anonymous functions to build WordPress plugins
I work in WordPress a lot, so I invariably use plugins to add functionality. Sometimes, if you can't find exactly what you want, you have to roll your own.
Whenever I think "It'd be quick enough to knock up plugin to do that" I get the annoying feeling of having to rewrite the plugin starting point. Deciding on a unique namespace or function prefix, setting up the admin menus, hooking into content, the usual. It's not a huge job, but I hate writing things I've done before.
Yes, I could build a template with the common functions, but that'd still mean changing all th function names, admin menu hooks and so on. Still annoying.
So I put together a template that uses anonymous functions. All I have to do is change the name of the plugin in two places (in an $info
array and the initial comment) and that's it. I have an admin hook, admin menu, options namespace with save & load - it's all good to go. Because it uses anonymous functions, there are no conflicts; I can copy & paste the file 10 times if I want, and each copy will activate as a separate plugin.
Here's the template:
/* Plugin Name: Plugin base Plugin URI: http://www.example.com/ Description: Default plugin Version: 1.0 Author: David Author URI: http://www.example.com/ */ $plugin=function(){ // Set some global details here // Plugin name $info=array('name'=>'Plugin base'); // Options namespace (tied to filename) $info['ns']=md5(__FILE__); // Update options if($_POST[$info['ns']])update_option($info['ns'],$_POST[$info['ns']]); // Get latest options $info['opts']=get_option($info['ns']); // Define admin control panel $admin=function()use($info){ echo $info['name']; }; // Add to admin menu (must appear after function definition) add_options_page($info['name'],$info['name'],8,__FILE__,$admin); }; if(function_exists('add_action'))add_action('admin_menu',$plugin);
$p
contains all the internal functions. That's where the magic is; $p
defines everything on the fly. If multiple plugins are created this way, they're executed one after the other. $p gets overwritten each time and there are no conflicts.
You can even define functions that don't conflict with anything by dropping them into an array:
$info['fn']['test_function']=function($string){ return $string; }
These will be available in the scope of the $p
function and therefore available to all functions defined within. I won't lie - variable scope can get a bit messy, but as long as you're passing variables around you should be OK.
One disadvantage is that anonymous functions are only available in PHP 5.3. And I can't honestly argue that this is any better than using a class
definition. Although I use this, it's partly because it was an interesting exercise to put together - I didn't write it for maintenance by anyone else
Enjoy this article?
Grandpa Simspon