Hey all,
I’ve released the first preview release of Rooster, a Digg API wrapper written in Java. The source code is available, and it’s released under the MIT license.
You can read more on the Rooster page.
Today I released WP Anti-Wares. It’s a plugin designed to find malicious code in themes. It’s in very early stages of development, and I’d love to get some feedback on it.
You can find out more on it’s page.
The below scrolling graph is only using a little JavaScript, and a little CSS. It’s just generating a random number every half a second, and plotting the number on the graph. Of course you can query your server using a little AJAX to get some actual numbers, like page hits. I’ve tried this on Firefox, and Internet Explorer, and it works fine in both.
Much of the look can be customized in CSS. The width of the bar, the size of the graph, etc. Want to put a picture in the background of the graph? No problem. It’s easy to configure though the CSS.
Take note that the canvas DIV tag has an empty set of DIV tags inside of it. That’s because IE will crash on the insertBefore if there aren’t any children already inside the outer container.
You can see the full source code here.
Recently a plugin author released a cool little plugin that creates a more dynamic “About Me” style page. When the plugin is activated, it will create a physical page in the database. The content of that page would have some PHP function calls for the author’s plugin. This plugin also required the Exec-PHP plugin to be installed, so that the PHP function calls in the page could be executed.
There is a better way though! A better way than actually creating a page with PHP code in it, and requiring the Exec-PHP plugin. The author’s plugin could simply create a fake page. A page that doesn’t actually exists in the database, but is viewable, and indexable by search engines.
Here is the code for making this happen.
05a627619342696d1f71437222ce763a000
Using the above code, when someone visits the URL http://site.com/about-me (or http://site.com/?page_id=about-me), your plugin
takes over. It then creates a new fake post, and adds it to the $wp_query vars. When the single.php template is loaded, that one single fake post will be displayed.
This example will just show a fake post with the title About Me, and the content of the post will be “Hi there! You are viewing my fake post!”.
You can easily change the GetContent() method to whatever you want. Whatever is returned by the method will be the fake post’s content.
Enjoy!
To copy the code from above.
There are times when you have a series of controller classes that all have similar functionality, so it makes sense to put that logic into a single class, and have your controllers extend that class. That’s the purpose of the AppController class, which CakePHP will automatically load when the script app_controller.php is found in the /app directory.
There are times though when you have different classes of controllers. Some controllers that are used on your site’s front end, and other controllers that are used on the site’s backend. These two types of controllers might have radically different functionality from each other, but similar logic between themselves.
That’s when it makes sense to have different base classes that the controllers extend from, not just a single AppController class. The problem is CakePHP only auto-loads the app_controller.php script. You can’t for instance put a script named admin_controller.php in the /app directory, and expect CakePHP to load it automatically. But there is a solution.
We know that CakePHP will auto-load the app_controller.php script, so if you want to have other base controller classes loaded too, simply include them in the app_controller.php script. Like this:
<?php // File /app/admin_controller.php class AdminController extends Controller { // Logic here } ?>
<?php include(APP . DS . 'admin_controller.php'); class AppController extends Controller { // Logic here } ?>
Now when CakePHP auto-loads the app_controller.php script, your admin_controller script will be loaded too. Your controllers are now free to extend the AdminController or AppController classes.
Enjoy!
The Post Tools plugin is designed to make some post editing task easier. Task like inserting videos in your post, mp3 sound files, password
protecting portions of your post, writing the post in different languages, etc.
The plugin works by inserting special Post Tools tags in your post. The tags look like this:
<pt:mp3player what=”http://www.mysite.com/some_song.mp3″ />
That tag will be replaced with a Flash MP3 player that’s loaded with the song specified by the what attribute in the <pt:mp3player /> tag.
The plugin comes with 14 different tags for you to use, but you can also easily add your own. The secret behind the Post Tools plugin, is when
it finds a pt: tag in your post, it looks for a PHP function with the name of the tag, prefixed with posttools_. For the MP3 example
above, the Post Tools plugin will look for a PHP function named posttools_mp3player(). The tag is replaced by the return value of that function.
To make adding your own tags easier, any PHP scripts found in the /tools sub directory are loaded automatically. So it’s easy to create your own scripts, with your own PHP functions in them, and just drop them into the /tools directory.
Lets start by writing a simple Post Tools tag. What we want is for the tag <pt:sayhi /> to be replaced by the phrase “Hello There!”. Start by creating a new document in your favorite plain text editor. This is going to be a PHP script, so it needs to start with the <?php tag, and end with the ?> tag. Like this:
<?php ?>
Now save this file as my_tags.php in the /tools directory. Now it’s time to create your tag function. That’s really simple.
<?php function posttools_sayhi() { return 'Hello There!'; } ?>
And that’s it! When the Post Tools plugin finds the tag <pt:sayhi /> in your post, it will get the return value from the posttools_sayhi() function, and replace the tag with that value.
While that’s nifty and all, the tags are useless if you can’t pass arguments to them. For that Post Tools always passes an array of arguments as the first parameter to your tag function.
Lets change our tag so that it says hello to someone specific. Like <pt:sayhi who=”Sean” />. Now when that tag is used in a post, we want it
to say, “Hello There Sean!”. Here’s how we change our tag function.
<?php function posttools_sayhi($args) { return 'Hello There ' . $args['who'] . '!'; } ?>
As you can see, the parameter $args is an array of attributes. The indexes of the array are the name of the attributes passed to the tag. In this case our tag was passed one attribute: who=”Sean”. So the $args array will contain an index named ‘who’, with the value ‘Sean’.
But we’re not done yet. Sometimes your tags don’t get attributes passed to them, but instead they wrap some text, like the PHP tag:
<pt:php> echo 'Hello There!'; </pt:php>
For instances like that, Post Tools passes the text between the tags as the second parameter to your tag function. Lets create a simple tag that reverses the text between the tags. We’ll call it reverse, and it’ll be used like this:
<pt:reverse> Hi. This text will be reversed. </pt:reverse>
Now we need to create the function for the tag. That will look like this:
<?php function posttools_reverse($args = null, $text) { return strrev($text); } ?>
And when someone views your post, the tag will be replaced with ‘.desrever eb lliw txet sihT .iH’. Of course your tags can contain both text and arguments. We can change our reverse tag a little bit to specify whether the text should also be made upper case.
<pt:reverse case="upper"> Hi. This text will be reversed. </pt:reverse>
<?php function posttools_reverse($args = null, $text) { $text = strrev($text); if (isset($args['case']) && $args['case'] == 'upper') { $text = strtoupper($text); } return $text; } ?>
Hopefully I’ve made it clear out easy it is to create your own tags to be used with Post Tools. If nothing else, you can look at the code inside the /tools/basic.php to see how the default tag functions work.
Enjoy!
If you’re looking to write a WordPress plugin, the best place to go for information is the WordPress codex.
Although you can find a wealth of information in the codex, not everything is covered. Some of the best practices for writing WordPress plugins are developed with experience.
This tutorial will cover some of those minor issues that can help you improve your plugin.
Use do_action(), not function_exists()
A lot of plugins require users to make minor changes to their blog’s theme. Usually those changes manifest themselves as function calls placed in one or more of the theme files.
In the past developers recommended placing the function call in the theme by using code like this.
<?php if (function_exists('my_plugin')) my_plugin(); ?>
There is an easier way though, and it’s by using the do_action() function. When you create a function for your plugin that’s meant to be used in the theme, create it like this.
add_action('my_plugin', 'my_plugin_function'); function my_plugin_function() { // Do something here }
Then tell your users to add this code to their theme files.
<?php do_action('my_plugin'); ?>
That looks a little cleaner than the function exists method, and may not confuse PHP noobs as much. The secret here, is when an action is triggered with the do_action() function, and the callback function doesn’t exists, nothing will happen. That’s what we want. If the person deletes you plugin, we don’t want their site crashing because of a function call in the theme, for a function that doesn’t exists anymore.
Don’t hardcode the plugin directory
Sometimes your plugin needs to know where it lives, or more specifically, the full path to the directory that it’s stored in. I personally find it easy to define a value at the start of the plugin that stores the full path to the plugin’s directory.
define('MYPLUGIN_PATH', ABSPATH . 'wp-content/plugins/my-plugin');
ABSPATH is a core WordPress constant that contains the absolute path to the WordPress root directory. There’s a problem with the way I defined my plugin’s absolute path: People might install the plugin in a different directory. Not a directory different than /plugins, but a directory different than /my-plugin.
Even if my ZIP file specifically has the /my-plugin directory, people might change the name of the directory for their own purposes. Maybe they already have a plugin that’s using the same directory name. That’s why you shouldn’t hardcode the plugin’s base directory, and instead you should discover the directory using WordPress’s plugin_basename() function.
define('MYPLUGIN_PATH', ABSPATH . 'wp-content/plugins/' . dirname(plugin_basename(__FILE__)));
The combined use of the dirname() function, and the plugin_basename() function, will give me just the name of the directory my plugin is stored in, within the /plugins directory. So dirname(plugin_basename(__FILE__)) will return ‘my-plugin’.
Now users are free to give my plugin’s directory a different name, and the plugin or blog won’t crash.
Avoid double loading of JavaScript libraries
Your plugin may need to use JavaScript, and you may decide to use a popular library like Prototype, or script.aculo.us.
There’s nothing wrong with that, and I encourage you to use ready made libraries like that, instead of reinventing the wheel.
The only problem with using popular libraries, is your plugin may not be the only plugin activated that uses one of them. In fact, many other plugins could be using them too, and each one of them is trying to include the JavaScript in the document’s <head> section.
To avoid including the library again, which adds bloat to the document, making it take longer to download, consider using a bit of JavaScript like this.
[javascript]
if (!document.getElementsByClassName) {
document.write(’
}
[/javascript]
The method document.getElementsByClassName is a Prototype method. With the above code, I’m checking for it’s existence, which would mean Prototype has already been included in the document. If the method doesn’t exists, I use JavaScript’s document.write() to add a <script> tag to the document, which will include the Prototype library.
With that method, I can be sure I’m not adding Prototype to the document again.
Use classes
PHP has supported classes for a long time now, and you should put them to use in your plugins. The big issue with writing a WordPress plugin, is function name clashing. If you create a function named init(), well there’s a really good chance that another plugin has defined a function with the same name. That’s a problem, and it’ll cause the blog to crash.
The most obvious way to deal with the problem is to prefix your function names with a string that’s unique to your plugin, like this.
function mygreatplugin_init() { // Do something }
That can get old though, especially if your plugin has a lot of functions. Your other option is to use classes to encapsulate your functions, which is the closest thing PHP has to namespaces.
class MyGreatPlugin { function init() { // Do something } } MyGreatPlugin::init();
Now you can give you function names anything you want without worrying about name clashes. Just call your functions as static class methods.
Final
Check back here often. I’ll be adding more tips & tricks as I think of them.
The Sidebar Widgets plugin for WordPress is incredibly useful, since it allows bloggers to add and remove content from their blog sidebar using
a drop & drop interface. Making your plugin widget ready is really very simple.
Making your plugin work with the Sidebar Widgets plugin takes less than 8 lines of code. Here are the very simple steps to “wigitizing” your plugin.
Step 1:
You need to register a callback function with the Sidebar Widgets plugin. This is the function that will be called by the widgets plugin
when it’s time to show your plugin’s content in the sidebar. Here is the code to register the function.
add_action('plugins_loaded', 'my_init'); function my_init() { if (!function_exists('register_sidebar_widget')) { return; } register_sidebar_widget('My Great Plugin', 'my_plugin_function'); }
That’s all there is to it. The add_action() line adds a callback function to be executed after all the plugins have been loaded. In our
example, that function is defined on the next line, and we’re calling it my_init().
The first thing the function needs to do is check that the Sidebar Widgets plugin is installed and activated. We do that with these lines.
if (!function_exists('register_sidebar_widget')) { return; }
If the widgets plugin is not installed and activated, your function will simply return. The next line of the function registers our callback
function with the widgets plugin. That line looks like this.
register_sidebar_widget('My Great Plugin', 'my_plugin_function');
The first parameter to the register_sidebar_widget() function is the name of your plugin, or how you want it displayed on the drag & drop
page. The second parameter is the callback function.
Step 2:
If you haven’t already, create the callback function to display content. There’s no need to create a special function just for the widgets plugin. If your plugin already has a function for displaying content, you can simply use that as the callback function. My Flickr Spinnr plugin
has a function named flickrspinnr(). Before I wigitized the plugin, users would add code to their theme that looked like this:
<?php if (function_exists('flickrspinnr')) flickrspinnr(); ?>
Because I already had a function to display the spinnr, I used that same function as the callback function registered with the widgets plugin.
That looked like this.
register_sidebar_widget('Flickr Spinnr', 'flickrspinnr');
Now my Flickr Spinnr plugin works with or without the Sidebar Widgets plugin. If a person isn’t using the widgets plugin, they can simply add the function call to their theme. If they are using the widgets plugin they can drag & drop a widget onto their sidebar.
Step 3:
Your plugin may have configuration options. You can register a callback function with the widgets plugin to display your configuration
menu when users click the settings icon on the widget. That code looks like this:
register_widget_control('My Great Plugin', 'my_plugin_menu');
This code should go inside the my_init() function, right after you register the main callback function with the widgets plugin. The first
parameter is the title for the control menu, and the second is the function that will be called when a user clicks the settings icon on
the widget.
This function takes two optional parameters, which are the width and height of the admin menu. Personally I leave these blank, and let
the widgets plugin figure it out, but you can specify the values.
register_widget_control('My Great Plugin', 'my_plugin_menu', 250, 175);
Creating the admin menu is pretty simple. An example looks like this.
function my_plugin_menu() { if (isset($_POST['my_plugin_username'])) { update_option('my_plugin_username', $_POST['my_plugin_username']); } $username = get_option('my_plugin_username'); ?> <p style="text-align:left"><label for="my_plugin_username">Your Username: <input style="width: 200px;" id="my_plugin_username" name="my_plugin_username" type="text" value="<?php echo $username; ?>" /></label></p> <?php }
Final
The Sidebar Widgets plugin will pass one parameter to your plugin’s callback function, which is an array of parameters. The array looks
like this.
array([before_widget] => '', [after_widget] => '', [before_title] => '', [after_title])
Your plugin should respect the bloggers wish to have content displayed before and after the plugin content, and before and after the plugins title, if there is one.
Here is the completed plugin code (minus the plugin header information).
<?php add_action('plugins_loaded', 'my_init'); function my_init() { if (!function_exists('register_sidebar_widget')) { return; } register_sidebar_widget('My Great Plugin', 'my_plugin_function'); register_widget_control('My Great Plugin', 'my_plugin_menu'); } function my_plugin_menu() { if (isset($_POST['my_plugin_username'])) { update_option('my_plugin_username', $_POST['my_plugin_username']); } $username = get_option('my_plugin_username'); ?> <p style="text-align:left"><label for="my_plugin_username">Your Username: <input style="width: 200px;" id="my_plugin_username" name="my_plugin_username" type="text" value="<?php echo $username; ?>" /></label></p> <?php } function my_plugin_function($args) { echo $args['before_widget']; echo $args['before_title'] . 'My Great Plugin' . $args['after_title']; echo 'Hello World!'; echo $args['after_widget']; } ?>
Have fun!
Filters and actions are at the heart of creating plugins for WordPress. They give the plugin developer near total
control over the ins-and-outs of everything happening within the blog.
Even though they do a lot, they are not difficult to use. Writing a WordPress plugin is not difficult.
Creating a filter or hook starts with one simple line of code:
add_filter('the_content', 'my_filter');
The add_filter() function registers a callback function with WordPress. In the example above, we are telling
WordPress to call the function my_filter() when the “the_content” action is taking place. The action “the_content”
takes place each time a blog post is being sent to the browser. There are many of these “tags” that you
will use when creating filters and actions, and we’ll get to those in a minute.
Before we go any future, it’s important to know the difference between an action, and a filter. Actions are
simply events that take place at certain points in WordPress’s execution. These events are given names, which
I’ll call tags for the rest of this tutorial. When you register a callback function with an action tag, you’re
telling WordPress to execute your function when that event takes place. For instance the “wp_head” tag is
triggered inside the <head></head> section of the document. If you need a function to be called
at the specific point, you register the function with the “wp_head” tag.
Filters are basically the same as actions, but what makes them different is they are designed to filter data before
being displayed, or before being saved to the database. For instance, if you need the title of every post to be
fully capitalized — even if the post wasn’t saved that way — you can register a callback function using the
“the_title” tag. When your callback function is called by WordPress, it will pass the title of the post as a
parameter to the function. Inside your function you would upper case the string, and then return that string.
Lets get into a little code to make it a little more clear. Here is a sample from a plugin that ucwords()
all blog post titles, even if the titles weren’t saved that way.
add_filter('the_title', 'my_callback_function'); function my_callback_function($title) { return ucwords($title); }
What’s going on here is very simple. Just before each blog title is sent to the browser, WordPress first
passes the post title through the my_callback_function() function. This gives you a chance to filter
the title before being displayed. In our function, we are taking the post title, applying PHP’s ucwords()
function to it, and returning the new title.
It’s important to note that WordPress expects a value to be returned from your filter function. If we
didn’t return a value from the my_callback_function() function, your blog posts would have no title displayed!
Lets look at another filter tag, the “the_content” tag. This tag is used to filter the content of each
blog posts before being displayed. Here is an example of it’s use.
add_filter('the_content', 'my_filter'); function my_filter($content) { $content = str_replace('Google', '<a href="http://www.google.com">Google</a>', $content); $content = str_replace('Yahoo', '<a href="http://www.yahoo.com">Yahoo</a>', $content); return $content; }
You can probably guess what’s going on here: All occurrences of the words “Google”, and “Yahoo” in your blog posts, will be
replaced with clickable links to those websites.
If we forgot to return the new $content value, the content for all our posts would disapear! So make sure
you always return a value from your filters, unless you a very specific reason for not doing so.
Now lets look at some actions. Just like filters, actions can have parameters passed to them from WordPress,
but WordPress doesn’t expect any value to be returned by your callback function. Actions are just the way
WordPress tells you plugin, “Hey, I’m displaying the header now. Okay, now I’m displaying the footer.”
Lets look at an example.
add_action('wp_head', 'my_action'); function my_action() { echo '<script type="text/javascript">alert(\'Welcome to my blog!\')</script>'; }
When someone visits your blog, a little JavaScript will popup giving them a welcome message. If someone was to
view your blog’s source code, they would see something like this.
<html>
<head>
<title>Your Blog's Title</title>
<script type="text/javascript">alert('Welcome to my blog!')</script>
</head>
<body>As you can see, by echoing a string when the blog’s head is being creating, your echoed content is inserted into
the head. Many plugins take this approach to insert their own required JavaScript into the head of the document,
or even CSS data.
Lets look at another example.
add_action('wp_head', 'my_head_function'); add_action('wp_footer', 'my_footer_function'); function my_head_function() { global $start_time; $start_time = microtime(true); } function my_footer_function() { global $start_time; $end_time = microtime(true); $final_time = $end_time - $start_time; echo '<!-- It took ' . $final_time . ' seconds to display your blog -->'; }
If you create a plugin with this code, refresh your blog, and view the source, you’ll see something that looks
like this at the very bottom of the HTML code.
<!-- It took .012 seconds to display your blog -->
Of course it takes more than code to create a plugin. You can put the above code into a file, and save it
in your /plugins directory, and it will do nothing. You need to tell WordPress that a file is a plugin by adding
a comment header. Here is an example.
<?php /* Plugin Name: My Timer Plugin Plugin URI: http://www.mysite.com/my-timer-plugin Author: Jane Doe Author URI: http://www.mysite.com Version: 1.0 Description: Puts an HTML comment in the footer of your blog, that displays how long it took to display your blog. */
Now that you know a little about filters and actions, lets put them them both together in a real plugin.
/* Plugin Name: My Timer Plugin Plugin URI: http://www.mysite.com/my-timer-plugin Author: Jane Doe Author URI: http://www.mysite.com Version: 1.0 Description: Puts an HTML comment in the footer of your blog, that displays how long it took to display your blog. */ add_action('wp_head', 'my_head_function'); add_action('wp_footer', 'my_footer_function'); add_filter('the_content', 'my_content_filter'); function my_head_function() { global $start_time; $start_time = microtime(true); } function my_content_filter($content) { global $start_time; $content .= '<br />Timer: ' . microtime(true) - $start_time; return $content; } function my_footer_function() { global $start_time; $end_time = microtime(true); $final_time = $end_time - $start_time; echo '<!-- It took ' . $final_time . ' seconds to display your blog -->'; } ?>
Here is what our plugin does: Once WordPress starts generating the head section of the blog document, a timer
is started. As each blog post is being displayed, the total time up to that point is added to the bottom of
the blog post. Finally, the total time it took to display your blog is added to the blog footer as an HTML
comment.
That’s all it takes. Save the file to your /plugins directory, using any name you like, and activate the plugin
from the WordPress admin area.
When I first decided to write tutorials on headzoo.com, I knew right away that I would need to highlight programming code in them. Using <pre> or <code> tags is okay for most situations, but nothing looks better than syntax highlighted code.
I didn’t have to spend any time thinking about how to highlight the code. The solution is simple — GeSHi!
I already use GeSHi based plugins on my blog to highlight code in posts, and used it when writing my own pastebins, so the choice was obvious. The only thing I needed to do was built a CakePHP component to to put GeSHi to use on my site. Fortunately this is a very simple task.
Before you begin, you’ll need to download the GeSHi library, which you can get from http://qbnz.com/highlighter. Download the archive file, uncompress it, and place the geshi directory inside your /app/controllers/components directory.
Now it’s time to create the component. Create new file, and save it as /app/controllers/geshi.php. Here is the source code for the component.
<?php include_once(dirname(__FILE__) . '/geshi/geshi.php'); class GeshiComponent extends Object { var $geshi; function GeshiComponent() { parent::Object(); $this->geshi =& new GeSHi('', ''); $this->geshi->set_header_type(GESHI_HEADER_DIV); } function parse($content) { return preg_replace_callback('~\\[(.*)\\](.*)\\[/\\1\\]~isU', array(&$this, 'replaceCallback'), $content); } function replaceCallback($matches) { $this->geshi->set_source(str_replace('<br />', '', $matches[2])); $this->geshi->set_language($matches[1]); return $this->geshi->parse_code(); } } ?>
I’ve stripped out the comments to keep the code compressed. To use the controller, add this line to your /app/app_controller.php script.
var $components = array('Geshi');
Note: You don’t have to put this in your app_controller.php script. You can put it in a specific controller. I choose to use the app_controller.php script, so that the GeSHi component is available to all my controllers.
Using the GeSHi in one of your controllers is this simple:
$this->set('tutorial', $this->Geshi->parse($tutorial));
Now a fully highlighted string will be available in the $tutorial variable in your view file. The only thing left to do, is tell the GeSHi component which parts of your content are code, and which is plain text/HTML. You do that with [code] [/code] tags. Simply wrap the programming code you want highlighted with those tags, replacing ‘code’ with the name of the programming language. For instance, [php] [/php], [sql] [/sql], etc.
The set code from above looks like this in my database:
$this->set('tutorial', $this->Geshi->parse($tutorial));
The parse() method for the GeSHi component uses preg_replace_callback to find the code between those tags, and then parses the code with GeSHi’s own parse() method.
That’s it, I hope someone finds this tutorial helpful.
Recent Comments