Function Documentation

WordPress Function Documentation Progress

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

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: Getting the Current Hook

WordPress 2.5 adds the ability to get the current hook name. This is useful for when you have a function for a filter which needs to return different output by the hook name.

A little bit of History

I didn’t agree with the idea, but the patch put forward was clean and neat. The implementation really moves the progress of the WordPress 2.5 Plugin API forward. The reasoning behind the implementation is that there are several times where a single function needs to be used for different hooks but still do somewhat different things depending on each hook.

My suggestion was to create two functions for each hook, but after some time debating I eventually supported the idea. While I didn’t supply the patch, or at least not the patch that was committed to core, I do think debating the idea made for a better feature.

How to get the Current Hook

The current hook can be retrieved using the current_filter() function. It will return a string that has the name of the hook within the context of the function that is called within the hook.

To further explain, lets say that Hook_A has three functions and the second function calls Hook_B, which has one function. When the one function in Hook_B calls current_filter(), it will return ‘Hook_B’. When the three functions in Hook_A call current_filter(), it will return ‘Hook_A’.

It will always be this way since, PHP does not do multithreading to allow for current_filter() to process two hooks at the same time. So it can always be assumed that the value in current_filter() will always return the current filter that the function was hooked into.

Example Plugin

The example plugin strips tags in the ‘wp_title’ hook and in the ‘wp_content’ hook, but also calls wpautop for ‘wp_content’ hook.

add_filter('wp_title', 'myplugin_sanitize');
add_filter('wp_content', 'myplugin_sanitize');

function myplugin_sanitize($content) {
    $content = strip_tags($content);

    if( 'wp_content' == current_filter() )
        $content = wpautop($content);

    return $content;
}

So we reduced what would be two functions into one and reduced the footprint of the total plugin code.

For filtering it is useful to sanitize something for everything except for a few areas or allow for different hooks to have different allowable items, but not for others. While it is possible to write several functions for each one, it is better (arguably) to have everything in one function for maintainability.

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