Developing Post Types Plugin with WordPress

by Vladimir Prelovac | February 2009 | AJAX Content Management Open Source Web Development WordPress

In this article by Vladimir Prelovac, we are going to dig deeper into the WordPress engine and discover ways to modify various aspects of the backend to match our specific needs with the help of the Post Types plugin.

Although WordPress is made primarily for the purpose of handling a blog, this basic functionality can be easily expanded to handle almost anything you want. The WordPress backend is very flexible, and can be customized to accommodate a lot of different purposes. For example, you could create a job portal or an e-commerce quite easily with WordPress, and those are just some of the possibilities.

Specifically, you will learn how to:

  • Implement localization support for users of other languages
  • Customize menus and submenus to change the way the WordPress backend looks
  • Handle file and image uploads
  • Use custom fields to add custom hidden information to your posts

And you will do all of these by developing a Post Types plugin that provide pre-defined post templates to add a photo or a link quickly to your blog.

WordPress Plugin Development: Beginner's Guide

The concepts you will learn in this article will help you discover the not so obvious capabilities of the WordPress platform that allows you to transform it into software—capable of handling much more than just a blog.

Handling localization

Localization is an important part of WordPress development as not everyone using WordPress speaks English (WordPress comes in different languages too).

Localization involves just a small amount of the extra work on your side, since the translation itself is usually done by volunteers (people who like and use your plugin).

You only need to provide some base files for translation, and don't be surprised when you start getting translated files sent to your inbox.

WordPress uses the GNU gettext localization framework, which is a standardized method of managing translations, and we will make use of it in our plugin.

Time for action – Create plugin and add localization

We will start by defining our plugin as usual, and then add localization support.

  1. Create a new folder called post-types.
  2. Create a new post-types.php file with the following content:
    <?php
    // pluginname Post Types
    // shortname PostTypes
    // dashname post-types
    /*
    Plugin Name: Post Types
    Version: 0.1
    Plugin URI:
    http://www.prelovac.com/vladimir/wordpress-plugins/post-types
    Author: Vladimir Prelovac
    Author URI: http://www.prelovac.com/vladimir
    Description: Provides pre-defined post templates to quickly add a
    photo or a link to your blog
    */
    // Avoid name collisions.
    if ( !class_exists('PostTypes') ) :
    class PostTypes
    {
    // localization domain
    var $plugin_domain='PostTypes';
    // Initialize the plugin
    function PostTypes()
    {
    global $wp_version;
    $exit_msg='Post Types requires WordPress 2.5 or newer.
    <a href="http://codex.wordpress.org/Upgrading_WordPress">
    Please update!</a>';
    if (version_compare($wp_version,"2.5","<"))
    {
    exit ($exit_msg);
    }
    }
    // Set up default values
    function install()
    {
    }
    }
    endif;
    if ( class_exists('PostTypes') ) :
    $PostTypes = new PostTypes();
    if (isset($PostTypes))
    {
    register_activation_hook( __FILE__, array(&$PostTypes,
    'install') );
    }
    endif;
  3. Adding localization is fairly simple. First we need to add a function to our class that will load the translation file:
    // Localization support
    function handle_load_domain()
    {
    // get current language
    $locale = get_locale();
    // locate translation file
    $mofile = WP_PLUGIN_DIR.'/'.plugin_basename(dirname
    (__FILE__)).'/lang/' . $this->plugin_domain . '-' .
    $locale . '.mo';
    // load translation
    load_textdomain($this->plugin_domain, $mofile);
    }
  4. Since loading the file takes resources, we will load it only when the translation is actually needed by checking the current page ($pagenow) and the list of pages pages where we need translations ($local_pages array):
    // Initialize the plugin
    function PostTypes()
    {
    global $wp_version, $pagenow;
    // pages where our plugin needs translation
    $local_pages=array('plugins.php');
    if (in_array($pagenow, $local_pages))
    $this->handle_load_domain();
    $exit_msg='Post Types requires WordPress 2.5 or newer.
    <a href="http://codex.wordpress.org/Upgrading_WordPress">
    Please update!</a>';
  5. Finally, to use the available translations, we only need to enclose our text in the __() function:
    $this->handle_load_domain();
    $exit_msg=__('Post Types requires WordPress 2.5 or newer.
    <a href="http://codex.wordpress.org/Upgrading_WordPress">
    Please update!</a>', $this->plugin_domain);
    if (version_compare($wp_version,"2.5","<"))

What just happened?

We have added localization support to our plugin by using the provided localization functions provided by WordPress.

Currently, we have only localized the error message for WordPress version checking:

$exit_msg=__('Post Types requires WordPress 2.5 or newer.
<a href="http://codex.wordpress.org/Upgrading_WordPress">
Please update!</a>', $this->plugin_domain);

We have done that by enclosing the text in the __() function, which takes the text as localized, and enclosing our unique localization domain or context within the WordPress localization files.

To load localization, we created a handle_load_domain function.

The way it works is to first get the current language in use by using the get_locale() function:

// Localization support
function handle_load_domain()
{
// get current language
$locale = get_locale();

Then it creates the language file name by adding together the plugin dir, plugin folder, and the lang folder where we will keep the translations. The file name is derived from the locale, and the *.mo language file extension:

// locate translation file
$mofile = WP_PLUGIN_DIR.'/'.plugin_basename
(dirname(__FILE__)).'/lang/' . $this->plugin_domain .
'-' . $locale . '.mo';

Finally, the localization file is loaded using the load_textdomain() function, taking our text domain and .mo file as parameters.

// load translation
load_textdomain($this->plugin_domain, $mofile);

Optimizing localization usage

The translation file needs to be loaded as the first thing in the plugin—before you output any messages. So we have placed it as the first thing in the plugin constructor.

Since loading the translation file occurs at the beginning of the constructor, which is executed every time, it is a good idea to select only the pages where the translation will be needed in order to preserve resources.

WordPress provides the global variable, $pagenow, which holds the name of the current page in use.

We can check this variable to find out if we are on a page of interest. In the case of plugin activation error message, we want to check if we are on the plugins page defined as plugins.php in WordPress:

// pages where our plugin needs translation
$local_pages=array('plugins.php');
if (in_array($pagenow, $local_pages))
$this->handle_load_domain();

You can optimize this further by querying the page parameter, if it exists, as this will—in most cases—point precisely to the usage of your page (plugins.php?page=photo):

if ($_GET['page']=='photo')

Optimizing the usage of the translation file is not required; it's just a matter of generally loading only what you need in order to speed up the whole system.

How does localization work?

For localization to work, you need to provide .po and .mo files with your plugins. These files are created by using external tools such as PoEdit.

These tools output the compiled translation file, which can be then loaded by using the load_textdomain() function. This function accepts a language domain name and a path to the file.

In order to use translated messages, you can use the __($text, $domain) and _e($text, $domain) functions. The _e() function is just an equivalent of

echo __();

These functions accept two parameters, the first being the desired text, and the second, the language domain where the message will be looked for.

If no translation was found, the text is just printed out as it is. This means that you can always safely use these functions, even if you do not provide any translation files. This will prepare the plugin for future translation.

Quick reference
$pagenow: A global variable holding the name of the currently displayed page within WordPress.
get_locale(): A function which gets the currently selected language.
load_textdomain(domain, filepath): This function loads the localization file and adds it to the specified language domain identifier.
_(); _e(): These functions are used to find the output text using a given language domain.
More information about WordPress localization is available at: http://codex.wordpress.org/Translating_WordPress
.

Sign up for a Packt account to see the rest of this article

Now that you've read a few articles, you might want to consider signing up for a Packt account. It takes a matter of seconds, will give you access to all the articles on PacktPub.com, and once you've signed up you'll be returned here to carry on reading your article.

Furthermore, you'll gain access to nine free ebooks, and be offered a free trial of PacktLib, Packt's online library. Simply enter your details here, or log in to your existing account.

Log in

...or register

Great post, but... by
Forgive my inexperience, but the code gives me error this time:(

Post new comment

Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Sort A-Z