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.

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

wp-config.php Settings: Part 2

About WP_MEMORY_LIMIT

In WordPress 2.5, a new hard coded setting is added, which allows for increasing the memory limit. Few people always seem to have a problem where PHP exhausts all of the memory (usually 8MB) and PHP crashes, bringing down WordPress in the process.

By default, the memory is increased to 32MB, which is conservative or liberal depending on your hosts setting. Dreamhost has 128MB for PHP5, which is pretty crazy, but if a PHP program takes up all of that, then there is something seriously wrong with the application. WordPress should be able to run within 32MB on small and medium sized blogs with just the default caching.

This won’t solve all of the problems, because some hosts do not have memory limit setting enabled. In order for the increase to work, --enable-memory-limit had to be set during PHP installation and ini_set() has to be enabled (not part of the disabled_functions PHP INI setting). Nothing that WordPress, nor the user has control over. If --enable-memory-limit was not used, then the host can't even increase the memory limit. Some hosts do disable the ini_set() function for security and PHP configuration purposes.

However, the good news is that unless you screwed up your PHP installation (and should reinstall and upgrade anyway) or on a crappy host, you should be okay and the increase will take affect.

Note: Don't worry about the constant lowering the memory limit, because it won't try to set the memory limit if the defined constant is less than what is already set in PHP.

Setting WP_MEMORY_LIMIT

In your wp-config.php file, insert the following:

define('WP_MEMORY_LIMIT', '32MB');

Just basically copy the above and the memory limit will be attempted to be set to '32MB'. You can change '32MB' to any number of MiB in the format of a number, followed immediately by 'MB'. So other examples are '16MB' (PHP5 default), '64MB'

define('WP_MEMORY_LIMIT', '16MB'); // PHP5 default
define('WP_MEMORY_LIMIT', '67MB'); // Larger Blogs using default object cache. Just in case.

Criticisms

WordPress continues to work on improving the amount of memory that is required. It is impossible to optimize the WordPress Object Cache on large blogs and may never be. It is with that reasoning that the above addition is justified. If 32MB isn't enough, just increase the memory limit and let the WordPress team know it failed.

January 31, 2008 Posted by | Advanced User Manual | , , , | 1 Comment

Replacing WordPress Object Caching

The WordPress Object Cache changed in WordPress 2.5 and removed a lot of file support from the code. This means that the Object Cache in WordPress 2.5 is completely dependent on memory and will not be saved to disk for retrieval later. The constant WP_CACHE also changed its meaning.

WP_CACHE Constant

In WordPress versions prior to 2.5 release, there were two constants that were used. One always enabled the cache and the other always disabled the cache. However, confusion was caused by both the constant values being booleans. In WordPress 2.5, those old constants were removed and a new one is used instead.

Normally, the WP_CACHE constant does not exist in wp-config.php. If it does exist, then it means that there is a file in wp-content folder named advanced-cache.php. This file, if it exists will be included (not to be confused with required, meaning that if it isn't there and you remove it, it won't halt the WordPress execution) and a function called wp_cache_postload(), if it exists.

The way to disable the WordPress cache is to define another cache, also in the wp-content folder, called object-cache.php. However, the functions that are used by WordPress still need to be defined in the file. Mostly, if you return false, then WordPress will just retrieve from the database, which will decrease performance.

When you write a plugin which uses advanced-cache.php, make sure you include code which writes the WP_CACHE constant to the wp-config.php file for the user, in case they don't have enough experience manipulating files themselves.

Note: the value inside of WP_CACHE is not important, what is important is that the constant is defined. So in theory, you can use:

define('WP_CACHE', '');

But in practice, it is better to set the value to true instead:

define('WP_CACHE', true);

advanced-cache.php File

In theory, the advanced-cache.php file is useful if you wish to save the output of the WordPress pages through the use of wp_cache_postload() function. There are other purposes that can be handled through the wp_cache_postload() function, but that is up to you the plugin developer to decide.

This file is optional, only the next file is required to replace the internal WordPress Object Cache.

object-cache.php File

You are replacing a file that has definitions used by WordPress, so you must also define those functions in your file and handle the cache using whatever method that you will be using the same way that the internal WordPress cache does.

This means that when wp_cache_get() is called, if the cached object does not exist, then you return false. If it does exist, then you return the object. The same way with other replaced functions.

What you would put in this file is Memcache implementation, or file based caching, or some other custom solution. The full implementation should go in this file and there can only be one caching implementation used at a time.

January 30, 2008 Posted by | Writing Plugins Series | , , , | 1 Comment

wp-config.php Settings: Part 1

The wp-config.php file contains all of the major settings that WordPress will use during execution. There are differences between the settings in the wp-config.php file and those that are set in the database. The major difference is that you have to manually change the settings in the wp-config.php file and the ones in the database you don't always have to manually change.

The wp-config.php requires user proficiency in FTP and editing PHP files to edit correctly. If you do not know what you are doing, then there are plenty of resources to teach you or you can get someone else to do it. The instructions on editing and adding settings will be basic and the file consists of mostly string and boolean values.

The article will be split into two sections, on this blog: settings that are set when WordPress is installed and settings which have to be manually added and changed by the user. These settings will be split up into multiple parts, the first one being the introduction and will be combined (excluding this paragraph), when all parts are finished.

Installation Settings

These settings you can set during the installation and not worry about them, unless you move your WordPress folder to a new host. WordPress will write these settings for you, so you don't actually have to create the file, but if you do, then WordPress will use the settings during installation and during execution. You can find all of these settings in wp-config-sample.php file and can copy and rename to fill out the information, if you desire.

The settings covered in WordPress 2.5:

  • Database Settings
  • Base WordPress Folder
  • Locale
  • Database Table Prefix
  • Secret Key

Manual Settings

These settings are added by you, the user and will be used by WordPress in different areas, if they exist. You can mostly find these settings in wp-settings.php, but other files have other special hard coded settings that will be used. The areas covered are below.

  • Debugging
  • Plugin Directory
  • Memory Limit
  • Blog ID
  • Language Directory
  • Cookies
  • External Cache
  • List others when found

The behavior of the WordPress caching plugins has changed, as well as what the constants mean. More on the caching changes later.

January 29, 2008 Posted by | Advanced User Manual | , | Leave a comment

Writing Plugins: Including an Uninstaller

I think the central issue is that, plugin developers think writing an uninstaller is difficult, but it is not. I’ve been doing it for quite a while in my private WordPress plugins. It was quite easy. I think that the few plugins which do implement it, do so in a way that over complicates it for other novice users.

  1. Activation Step

    The core simple concept is to have an option that tells your plugin whether the plugin should be uninstalled or not. If you add options anyway, then this isn’t to difficult.

  2. Deactivation Step

    The second concept is to check that option during the deactivation and then if it is set to true, then you remove everything that you added in the activation step.

  3. Plugin Option Administration

    I think this is where novice plugin authors get tripped up and most other people. If you already have an options page, then it should be simple to add a checkbox that states whether the user wants to uninstall the plugin when it is deactivated.

    If you don’t have an options page, then let me walk you through that.

Activation Step

The code is pretty much uniform for all of my plugins and most plugins that I see.


function myplugin_activation()
{
    $option = get_option('myplugin_option');

    if( false === $option )
    {
        // Install tables and setup options

        $option = array();
        $option['uninstall'] = false;
        // Other options
        
        add_option('myplugin_option', $option);
    }
}

register_activation_hook(__FILE__, 'myplugin_activation');

And that implements the entire step for adding the uninstall option. Not to difficult, I don't think. If you have any questions, then feel free to ask.

Deactivation Step

The deactivation step is as easy as the activation step (and I think the only difficult part is creating the administration page).

What you do is get the options and test to see if the options exist (should always exist, but you never know if the user deleted your options for you). Then you test to see if the uninstall option is true and remove everything.


function myplugin_deactivation()
{
    $options = get_option('myplugin_option');

    if( is_array($options) &amp;&amp; $options['uninstall'] === true)
    {
        delete_option('myplugin_option');
        // Remove other tables and installed items.
    }
}

register_deactivation_hook(__FILE__, 'myplugin_deactivation');

That is it! Quite easy, I believe. The hard part is creating the administration page, until you get used to doing them.

Administration Page Alternative

You do have an alternative, if you don't want to create an administration page. What I've done, was test to see if an constant is defined and if it is, I run the uninstall in the deactivation hook. This will require manual work on the user's part, and instructions on your part. Quite frankly this is only useful for testing of your uninstaller, and for personal projects where you don't really need an administration page. However, if you plan on placing your plugin in the open, it will be a good idea to use the other method.


function myplugin_deactivation()
{
    if( defined('UNINSTALL_MYPLUGIN') )
    {
        delete_option('myplugin_option');
        // Remove other tables and installed items.
    }
}

register_deactivation_hook(__FILE__, 'myplugin_deactivation');

Administration Step

The administration creation is not difficult, just time consuming. When you have it set up, it is fairly straight forward. I would also suggest that if you are just going to include the uninstaller option that you have your plugin page in the plugin page.

I'll post the administration creation step in a later step. If you need more information then the WordPress codex has all that you need for creating administration pages.

January 24, 2008 Posted by | Writing Plugins Series | , , , | Leave a comment

Writing Plugins: Writing Maintainable Procedural Plugins

  1. Don’t use Globals.

    Okay, so WordPress uses globals and that is okay, so why can’t you use globals? If you know what you are doing then by all means, ignore this suggestion, because this does not apply to you. For all of the others, the suggestion to put logic in functions applies.

    If you place variables in main(), then they automatically become global to the execution process. If you don’t use naming convention practice, then your global variable could clash with another plugin.

    It is not that you shouldn’t use globals, with procedural programming, there is no way around using globals. However, declare and set the globals up in functions, instead of setting them at the top of the plugin execution path.

  2. Use naming conventions

    And whatever you do, don’t start your functions with “wp_”. Choose a function prefix that no one (that you know of) uses yet, which could be your company or your name (although, it just doesn’t seem right to start functions using human names, since author information is better located elsewhere), the plugin name, or something you just make up.

    As long as you use it throughout the plugin, call it whatever. Consistency is key, and with naming conventions and coding standards, no one can tell you that you are wrong, as long as you are consistent. Most developers do conform to the WordPress coding standards, but use whatever naming convention pleases you.

  3. Split duplicated logic into functions.

    Are you writing the same lines of code, over and over again? How about you split that chunk of code into its own function and call that function in different places. The goal is to only write code once and reuse it in many different locations.

    This also allows you to fix a bug in one location and not have to track where similar lines of code is located. It saves time, reduces the chances of defects, and increases the maintainability of the code. Also, since most of the time, when code is split it usually increases the ability of others to grasp the full purpose of one of your functions.

    For completeness, it will be pointed out, that by splitting logic into functions does increase the overhead (where opcode caching is not used), so it will decrease the performance of your plugin. Not by much, however, it is something to look at when optimizing and is a counter suggestion to this suggestion for optimization.

    However, the optimization arguments, that I’ve seen have not convinced me that the sacrifice of maintainability and clarity is worth a few milliseconds (if even that). If your plugin is hurting, it is most likely not, because you one or two large functions into four or five smaller ones.

  4. Keep the branches and functions to a minimum

    I’ve seen plugins where there were foreach loops within if statements within foreach loops within if statements. Besides optimization complaints, I would probably say that the function needs to be simplified somewhere, so that someone like me would even want to read it to understand what it was trying to do.

    There are metrics that will inform you of how difficult a function or method is, but any function more than 25 lines is pushing the barrier of complexity. The other index for branches, is a little bit more difficult to recommend. However, try not to have more than 5 branches or like the above example. Most of the time, something like that can be split into its own function and called, if only for the sake of sanity when reading through the function.

    By keeping the complexity of functions to a minimum you increase the chances of a user coming and finding an issue and making a modification that won’t break anything. You also increase the odds that you won’t create something so complex that even you don’t understand what is happening, “Yeah, it works, just don’t breath on it!” Statements like that, should be avoided, because something will break, and you won’t be able to fix it.

  5. Keep the base plugin file length short.

    Again, this recommendation is arguable, so you can choose to have all of your functions in one file or split them into multiple logically named files. It is up to you. The argument for why you should keep functions in a single file is for optimization and there is enough optimization evidence for having PHP functionality in one file. However, I believe in maintainability, and I don’t like scrolling up and down in one massive file.

    My recommendation is that when your plugin becomes large enough, that you split it into logical portions. Usually, what I will see for classes, is a block that checks for whether the class exists and if not then it will define the class. I think just having the class in its own file and using require_once() makes more sense. You gain nothing in optimization over require_once(), because opcode caching won’t cache the class until it knows it needs it and the if statement will prevent it from doing so.

    My base plugin usually only have the activation, deactivation, and init hooks and everything else is in other files. I also split my administration files into their own files separate from other plugin functionality.

  6. Have HTML, place them in their own template file.

    I admit I do place HTML into functions myself, as it is quick and easy method. I think placing HTML in functions is not hackish or dirty at all, since it is practically the same as placing them in its own file.

    Where I don’t do this, is for administration HTML, because it is much bigger than a snippet of HTML and requires other actions. You must protect your administration files, so test for ABSPATH before outputting HTML.

January 22, 2008 Posted by | Writing Plugins Series | , , , , , | Leave a comment

How to Patch the WordPress Core

This document will combine several external sources into one long informative document. Some of the contents will describe how to create a patch, how to create a Trac ticket, and finally what can be done to move the process along to get the patch into the core of WordPress.

Disclaimer: Some of the contents in this article are from the codex, since this blog is GPL also, no violations were made. Other contents are inspired by external sources, which are not GPL, but none of non-GPL contents were used to prevent plagiarism and so that GPL license could be applied to all of the contents in this article.

The Process

The process to get a patch into the core can be a long one. However, you do have to complete some steps and stay on top of the patch to ensure several objectives before it can be committed. Be aware however, that without a Trac ticket, there is no hope for your patch ever getting into the core. If the commit team does not know of your patch and does not have access to your patch and purpose, then they won’t apply it. Be sure to create a Trac ticket and upload the patch file. The WP-Hackers list is not for posting patches to, even if it is likely that a helpful person will probably create the ticket and add the patch for you.

Lets say you are using WordPress and something that you didn’t expect happens. You then check the forums and try to get help there first. After confirming that the issue is a bug in WordPress, you can decide two things. You can either file a Trac ticket, and after you can choose to provide a patch which fixes the issue. The last part is optional, but it would move the issue ahead of the queue to be in the next release if there is a patch for the ticket.

For the sake of this article, lets say you decide to provide a patch along with the ticket. The following can also apply, if you decide to provide a patch for an existing ticket with no patch.

  1. Checkout WordPress Trunk Repository.
  2. Make changes to the core.
  3. Save the changes to a file, in the form of a diff.
  4. Create the ticket (if it doesn’t exist already) and fill in the details.
  5. Upload the patch
  6. Stick around to keep on track of any comments, suggestions, and to keep the commit team interested.

Now that the process is available, lets go step by step through the each process in more detail.

1. Checkout the WordPress Repository

“Checkout” is a term to describe the process of downloading the contents of a repository. In this case, it is the WordPress repository and the “trunk” folder. In Windows, this is a very easy process, made possible by TortoiseSVN. Windows does not come with Subversion, like most Linux distributions do, so you will need to install TortoiseSVN manually.

You can download TortoiseSVN from the web site and after you download it. Click on the installation to install it. After you install it, it will ask you to restart. After you have restarted, you can begin using the functionality.

How TortoiseSVN works, is it adds a context menu to the right click. So if you right click on a folder, it will have new options. One of these options is “SVN Checkout”, but you should only do that in an empty folder that you created.

  1. Create a new folder, call it “WordPress”
  2. Right click on the folder name or if in the folder view, then right click in the window.
  3. In the menu, click on “SVN Checkout”
  4. When the box comes up, type in “http://svn.automattic.com/wordpress/trunk&#8221;

That now describes the process of checking out the WordPress repository in Windows, using TortoiseSVN.

The WordPress.org has a section for downloading WordPress using Subversion. That page also describes how to create patches for WordPress using the command line.

2. Making Changes to the Core

You can use any editor to change the files in the repository. Subversion does not have or need any special editor, so you can use your favorite or Notepad.

When you make changes to the files in that folder that you used to checkout the WordPress repository, they will show up differently (on Windows). On Linux, you can use the command “svn status” to find which files you changed.

Unless you are a member with commit access, which is only a handful of people, you will not be able to commit the changes. Therefore, it will be futile to try to click on “SVN Commit” on Windows or type “svn commit” on Linux command line.

3. Creating a Patch File

Creating a patch file on Windows involves has two options. Either creating a patch for a single file, or creating a patch which includes more than one file. The steps are similar for both, but there are several differences when creating a patch for a few files.

  1. Single File

    1. Right clicking on a file.
    2. Hover over the “TortoiseSVN” menu text
    3. Click on “Create patch”
    4. Click “Ok” because there will only be one file and that is the file you right clicked on.
    5. Save the file using the file extension of either “.diff” or “.patch”
  2. Multiple Files

    1. Right click on the folder area, not on a file, in the folder where wp-settings is located.
    2. Hover over the “TortoiseSVN” menu text
    3. Click on “Create patch”
    4. Choose the changed files you want to be part of the patch.
    5. Click “Ok”
    6. Save the file using the file extension of either “.diff” or “.patch”

When saving patch files, save them with the file extension of either “.diff” or “.patch”, so that Trac and display the DIFF on the site. It helps with the ability to review the changes and it is difficult to read diff files to understand the context of the changes if you don’t.

4. Create a Trac Ticket

  1. Go to WordPress Trac site
  2. Log in or create a new account and then log in.
  3. Click on “New Ticket”
  4. Fill in a descriptive title which summarizes the defect or feature and will provide interest in the ticket.

    The title is what the community sees and how the figure out if the ticket is worth checking or not. If a bad or non-descriptive title is given, then it might be passed over as being uninteresting and hinder someone who might otherwise be interested from providing a patch sooner.

  5. Fill in as much details about the ticket defect or feature request as possible.

    The more details, the more chances of someone providing a patch that fixes the defect or can create a patch for a feature request. For defects, have as much system information as needed (no passwords) and for features, describe the purpose as well as the feature details. The more details, the better off and the sooner the ticket might have a resolution.

  6. Choose the correct component, version (if defect), and do not set the milestone (unless you are going to immediately provide the patch).

5. Uploading the Patch

In the Trac ticket page, click on “Attach File” and upload the patch. After adding the patch, add “has-patch” to the keyword field and save the keyword.

6. Keeping on Top of the Patch

Your patch will not get into the core of WordPress until someone with commit access adds it. This can take anywhere from a couple of hours to a few weeks to a few months or in the worse case, never. It can be disheartening to create a patch, spending all of that time and then never have your patch committed. There are several reasons for this, so don’t get mad yet.

  1. Commit team might have higher priorities to complete first.

    The commit team has several priorities and areas they are interested in first. They should also be given enough time to review the patch, review the ticket, and whether the severity warrants the resolution of the defect or feature. It might be that a member of the commit team is taking the time to clean up the patch code, so that it is up to WordPress standards.

  2. Defect or feature does not provide enough rationale or interest from the commit team.

    There have been several times, when developers just aren’t interested or know enough of the problem to realize whether the patch provides the best solution. If that is the case, then provide explanations and rationale for why the patch should be committed. Keep on top of the issue, whether it is a defect or feature, because sometimes the commit team forgets that there is a patch and what the issue is. They might have been wanting to commit the patch, but it left their minds as other issues more important were bought up before they could.

  3. Clearly define, explain and demonstrate your problem or feature request.

    The more details the commit team has on the defect or feature, the better they can decide whether the patch (if any) is worthy of inclusion in the core or some extraneous problem that can be solved using a plugin. Do not be mad, if the commit or community members state that the solution could be better solved using a plugin. Also provide further rationale and explanations that might be needed to provide reasoning to why the patch should be included.

    If the solution adds extra configuration options, then you can pretty much count on your patch never being committed. The WordPress commit team does not like patches and solutions which add extra options. Any patch would need to make due without them. A solution would to use apply_filters() to pull in options, that would allow for plugins to be made instead of adding additional options to in the administration.

  4. Carefully consider, and take into account advice and feedback given on trac.

    Be aware, that if your patch is not committed in a reasonable amount of time for a defect, that it might be that you didn’t provide the best solution for the problem. If that is the case, then take in account the suggestions made by the community and commit team alike. If you disagree with the community members, then explain why your method is better and debate the issue. The WordPress community wants to have the best and better solution in the core, and not something they don’t agree with. Debating the point might also provide the rationale for the commit team to bring your patch into the core.

    There are quite a few veterans in the WordPress community that have some pull (karma, if you will), so their opinion/reasoning might trump yours. Use the recommendation that every suggestion should be considered, no matter who the person is that is making the suggestion. The goal is to have the best solution, so work with the community and commit team, so that the best solution can be bought into the core.

  5. Write easily understandable, documented code.

    The requirement standards for new functions inclusion into the core has been increased. New functions MUST be documented using the Inline Documentation standards. Not having that documentation may hinder the inclusion depending on the severity of the defect. For features, document the code, even if you are unsure that it will be included into the core. That way, the patch won’t be rejected, even if the commit member wants to include it.

    Follow the WordPress coding standards as much as possible to get the code included in to the core. You might want to profile the code to make sure that it doesn’t create any unwarranted bottlenecks in the code. Simple is better, try not to create complex code where simplified code would work. It is difficult to give an example, but most people will know it when they see it.

  6. Consider writing a plugin instead.

    There are moments, when the only way to prove whether or not a feature request should be added to the core, is by proving that enough people want to have the feature. If it is possible to make a plugin, then the suggestion will be that you make one. If enough people use the plugin, then you can come back with the proof to have the feature added. If the feature is not possible without modification of core files, then create a patch which allows for your plugin to work that implements the rest of the functionality.

  7. Appropriate tags in Trac help attract attention.

    After you add a patch, add the keyword “has-patch” in the keyword field of the Trac ticket. This will tell developers and the WordPress community that the ticket is ready to be reviewed for possible inclusion into the core.

    If enough time has past and you are wanting to know why the patch still hasn’t been committed, then add “dev-feedback” to the keyword field (remember, commas are not used to separate keywords, spaces are).

References

  1. “How does code make it into WordPress.” WordPress codex.

January 21, 2008 Posted by | Quality Assurance Series | , , | 2 Comments

Writing Plugins: Directory Structure

If you plugin is fairly simple and small, you can contain your plugin in one file and have translations in the same directory. However, if you ever plan to extend your plugin and create more complex and feature complete, then you’ll want to rethink the single file method.

The only reason you would not use this method, is if you have optimization in mind and include all the library code in one file to prevent file access overhead. However, in most instances, if your library is massive, it is probably better to have the files separated for maintainability.

Separate Translated Files (.mo) Directory

It would serve your plugin better, if translated files were in their own directory, that way, when you setup the plugin textdomain, you can reference that one directory for WordPress to look into. Also, it would allow for easy management and cleaner plugin root structure.

Third Party or External Library Directory

For third party libraries that are used, it is better to place them all in another folder and could call it third-party/. This will create a separate from your plugin's code and code that is external from your code. When people go to file bug reports you don't want them to file bug reports with you that they should be filing with the respective library maintainer.

Using that name will give a hint that the files are not maintained by you and should have the defects filed elsewhere. It may not stop everyone from reporting the defects to you, but if you keep notes, it should be more informative to most WordPress power users.

Library Directory

The idea is to have at most two files in the root, a readme and your base plugin file. The readme to inform users on how to use your plugin, how to uninstall your plugin, and other information about your plugin. Your base plugin file has the WordPress required comment with your plugin data, so that WordPress knows about your plugin and can activate it. The base file will set up all of the plugin variables and include the required files.

The rest of your library will be contained in a folder in your plugin's directory. You can use one file for optimization or for maintainability, separate the functionality out into logically named files.

Public CSS/JavaScript Directory(-ies)

If you plugin also has public CSS and JavaScript files, it is better to have them in their own directory. It allows for quick access to all of the individual files for CSS and JavaScript. It creates a separation, so that users know where to look for your CSS and JavaScript. Another advantage is for permissions, but those might need to be set by the user.

Others?

The idea is to create a separation of content, so that your plugin is more maintainable for both yourself and others. It is a suggestion and developers have their own style. I have no complaints other than you should be consistent. That is not to say that if you have one plugin with directories like the above that all of your plugins should be that way. No, it is to say that if you use directories for one thing, then you should split all of your content into directories.

January 20, 2008 Posted by | Writing Plugins Series | Leave a comment

Follow

Get every new post delivered to your Inbox.