Function Documentation

WordPress Function Documentation Progress

Writing WordPress Widget Best Practices

Don’t Nest Functions

It appears to be a neat trick, but that is all it is. A hack that you should avoid and just because you can do it and it works does not give reason to do so. There are many programming practices that you can use in PHP, but must not. The only exception was, if you were the only one that is going to see it and it was an exercise of academics. Aside from that, the common widget practice of nesting functions inside of functions should be halted.

Example of Wrong Widget Form

function myplugin_widget_init()
{

    function myplugin_widget_display($args)
    {
        
    }

    function myplugin_widget_control()
    {
        
    }

    // Register myplugin_widget_display() and myplugin_widget_control()
}

The problems with this code are listed below.

  1. Class structure would be the most logical alternative.

    The simple containment of the functions is easily accomplished using a class container. I’m unsure what the appeal of this form, but if the need to contain the three functions, than a class should have been used instead.

    I have an theory, that the first one to use this pattern knew what he/she was doing and thought it would be cool and didn’t realize that everyone else would use it as an example. Everyone else that came after noticed that it worked (mysteriously) and decided that it was easier than learning OOP. However, this theory is unproven, so whatever the reason, a class would have been a better and wiser choice.

  2. Prevents Opcode Caching optimization.

    PHP will not compile the two functions contained in myplugin_widget_init() until that function is called. By halting the compile process, some one using an Opcode Cache will not receive the boost. Furthermore, PHP will not know in most cases whether it will need to continue to cache the two functions, so at the best case the functions will be cached after the function is called and at the worst case, it will have to compile the two functions with each process.

  3. Causes fatal duplicated function definitions.

    In the event that myplugin_widget_init() is called twice, it will cause PHP to try to compile the contained functions twice. This will fail, because PHP already compiled the functions when the function was called the first time. The reason you won’t have a third call is that the second call will bring PHP and WordPress crashing down.

Widget Best Practice: Using the Object Pattern

class myplugin_widget
{
    function init()
    {
        // Register myplugin_widget::display() and myplugin_widget::control()
    }

    function display()
    {
        // Echo content
    }

    function control()
    {
        // Echo administration control
    }
}

I like keeping functionality contained together. Some plugins choose to dump all functionality into the same object, I would advise against this, but if it is easier for you, then just use functions instead until you learn OOP better.

Widget Best Practice: Using Functions

function myplugin_widget_init()
{
    // Register myplugin_widget::display() and myplugin_widget::control()
}

function myplugin_widget_display()
{
    // Echo content
}

function myplugin_widget_control()
{
    // Echo administration control
}

This code is far nicer looking and contained and has none of the disadvantages listed above.

Advertisements

February 4, 2008 Posted by | Writing Plugins Series | , , | 1 Comment

Shortcodes API

WordPress 2.5 adds the ability to register bbcode style formats in plugins for post content only. I have a plugin that converts language specific bbcodes to genshi style. It however parses the content manually. Using the new API, it only needs to register each language or a single name and use an attribute for each language.

The functions for plugins are add_shortcode() and remove_shortcode(). The functions exist in wp-includes/shortcodes.php and offer a basic functionality. Overall, the addition will decrease the hassles of plugin authors and unify the standard of replacing short tags that a lot of plugins use in their plugins. This will be a great boon for plugin authors.

How to Add a Shortcode

Lets say that we want to support the bbcode code ‘b’ and add support for it in post content. We would first register the ‘b’ short code with the function which which will replace the ‘[b]’ and ‘[/b’] with ‘<‘ and ‘>’ respectively.

function bbcodeplugin_b($attr, $content='')
{
    if( empty( $content ) )
    {
        return '';
    }

    return '<strong>'. $content .'</strong>';
}

add_shortcode('b', 'bbcodeplugin_b');

The first parameter catches any attributes that the user might have added between the “[b …]content[/b]” that will be caught and given to your plugin function.

In the example of using geshi, lets create a plugin short code which, in theory, will allow any number of languages to be converted to geshi styles.

function genshiplugin_genshi($attr, $content='')
{
    if( empty( $content ) )
    {
        return '';
    }

    return genshi_conversion_function_or_method($attr['lang'], $content);
}

remove_shortcode('genshi');

add_shortcode('genshi', 'genshiplugin_genshi');

In this example, we remove any plugin that might have registered their own and replace it with our function instead. If you are going to create something that is generally generic, then it is a good idea to choose something that either has your plugin name or in the case of the above example used a generic ‘code’, so that the user doesn’t have to go through all post content to replace the bbcode style to switch over to your plugin. However, if the user wants to use multiple methods, then let the user decide with an option.

Most Common Replacement

Many plugins replace a “tag” in the content with their own content or run a special filter and add forms or pictures or any number of special content. Many plugins build their own regular expressions to process the content to look for the content. With the short code API, this is no longer necessary.

If I wanted to replace every instance of “[myplugin]” with “My Plugin is Awesome”. I can use the above examples and just return the “My Plugin is Awesome”.

function myplugin_is_awesome($attr)
{
    return 'My Plugin is Awesome';
}

add_shortcode('myplugin', 'myplugin_is_awesome');

Adding Shortcode to more filters

The default filter (as of this writing, it might be added to more when 2.5 is released), is ‘the_content’, but you might want to apply the code to comments and excerpts or any other filter. As a warning, some plugins might register codes which might make it unsafe to be used in comments, so be careful with what is exactly registered and confirmed with comments.

add_filter('the_excerpt', 'do_shortcode');

Or if you don’t want to use short codes, add the following to a plugin.

remove_filter('the_content', 'do_shortcode');

How Fast is Shortcode?

The API is extremely optimized and fast for what it does. It is doubtful that it can be optimized any further and barring any defects, it probably will stay quick. It also appears that it doesn’t use the built-in plugin API, so that means that one function can exist for each shortcode. You won’t be able to run a ‘code’ shortcode tag through two or more filters, only one can exist for the short code. This decreases the time spent, but removes one of the best features in the Plugin API.

February 3, 2008 Posted by | Writing Plugins Series | , , , | 9 Comments

Speaking at WordCamp Dallas 2008

My talk has been accepted for inclusion on Sunday, March 30. The nice part is that if perhaps I stumble, enough people will be able to leave since I have the last session of the day. I have some experience speaking in front of people I’ve never seen before in my life, but I every time I stand in front of a crowd I think of two things. The first, is that I think I’ll kick major ass and I almost never do and the second that I’m nervous as hell. If I don’t wet myself in the first 10 minutes, then I think it’ll go great.

The talk is titled “Testing with WordPress” but is on automated testing and why developers should be helping out with the effort. I think it will be split into two parts, the first will be what automated testing is and why you should help out with the effort and the second part will be all code and showing how to help with the effort. It is fairly simple presentation, but I assume that powerpoint is an option.

I just have to practice and write enough test cases to present enough material for 30 minutes. I also have a project that I have to finish in order to reveal its purpose during the presentation. Actually, I plan on revealing the project sooner and still using the project during the session. It should be interesting to say the least, as it will be both my first conference, first WordCamp, and first time I’ll be talking in front of a large crowd.

Should be fun. WordCamp Dallas I mean. I’m still debating, whether I’ll be going to the WordCamp 2008 in San Francisco. I won’t be speaking there, but I think it would be nice to see the place and arrive a couple of days early to enjoy the sights and visit family. I’m only going to WordCamp 2008, if I have enough money to fly down there, but It is only a 7 hour drive to Frisco. In the worse case, I’ll be driving down to Frisco Friday after work, arrive around midnight, check into my hotel and crash, and arrive for the first day of sessions.

I plan on taking a lot of pictures, but I’m unsure if I’m going to rant at any point about WordPress. I hope not, because I enjoy living and dissing WordPress at an event strictly WordPress doesn’t seem like the most logical move, if you enjoyed breathing. I rant a lot, so I have to watch myself, both during my talk and during the other talks. I’m pretty mellow in person, so I doubt I’ll get into any trouble.

I’ll probably be the least well known person at the sessions, so I doubt anyone is going to say anything about what I’ve done with WordPress. I don’t intend on discussing what I’ve done with WordPress, unless someone asks. I’ll just be that guy who takes a lot of pictures and then bam, I’ll be speaking at the end of the day. All in all, it will be totally awesome and I look forward to giving my viewpoint out there.

February 1, 2008 Posted by | WordPress | | 2 Comments