
Wordpress - plugin coding standards

Carried away by writing plugins for Wordpress'a drew up the rules of good form ...
Naming convention
Where does the plugin begin - with the name :), therefore, let's work out the rules for naming plugins:
- We do not use stupid prefixes of the form wp_ or wp- - we already know that the files in the directory http://wordpress.org/extend/plugins/ are intended for wordpress'a
- If you want to highlight your plugin, add the original prefix / postfix (I use the prefix (a) - I really don’t know how informative this is)
- All class and function names must contain the name of your plugin - in order to avoid conflicts
Always create a directory with the plugin, even if it consists of one file, you may want to expand the functionality in the future, and you can’t get by with just one file, and create a directory - and this can lead to a stupor of users ...
readme.txt
Each plugin is required to have a readme.txt file , see the syntax description http://daringfireball.net/projects/markdown/syntax . You can verify your creation using the validator .
If for some reason you do not upload your plugin to the wordpress repository, then in any case create this file - many will say thanks.
Headline
This is an obligatory element of the plugin; no need to distort it much:
/ *
Plugin Name: Name Of The Plugin
Plugin URI: http: // URI_Of_Page_Describing_Plugin_and_Updates
Description: A brief description of the Plugin.
Version: The Plugin's Version Number, eg: 1.0
Author: Name Of The Plugin Author
Author URI: http: // URI_Of_The_Plugin_Author
* /
?>
Coding standards
I have not seen full-fledged standards from the developers - for this reason I use the Zend Framework'a standards , which I advise you. (in the examples I will not use comments for the PHP Documentator, in order to shorten the listing of sorts).
And yet - our plugin should not cause errors (even the Notice level ), so when developing, turn on error display:
error_reporting(E_ALL);
Dynamic file upload
Download the entire plug-in at once, then hang all the hooks and do nothing - this behavior of plug-ins is common, let's be smarter, for starters it’s advisable to remove all the functionality by class and file, and load the necessary files in the functions:
// add a content filter
add_filter ('the_content', array ('% PluginName%', 'the_content'), 1000);
class% PluginName% {
var $ some_variable;
/ **
* filter fo the_content
*
* @return void
* /
function the_content ($ content)
{
include_once 'class / Content.php';
$ Content = new% PluginName% _Content ();
return $ Content-> parseContent ($ content);
}
}
It is also advisable to hang hooks separately for each state - see the list :
if (is_admin ()) {
// hooks for the admin
} else {
// hooks for the front-end
}
// and so on ...
You can even do this:
if (is_admin ()) {
include_once '% PluginName% _admin.php';
} else {
include_once '% PluginName% _front.php';
}
// and so on ...
Variables and Namespace
Since the namespace in PHP is not yet implemented (meaning stable versions), a static class that combines all the functions for hooks will help us to cope with this task:
add_action ('% hook_name%', array ('% PluginName%', '% hook_name%'));
class% PluginName% {
var $ some_variable;
/ **
* some function description
*
* @return void
* /
function% hook_name% ()
{
// ...
}
}
Or the usual class:
// create the essence of our class
$ PluginName = new% PluginName% ();
add_action ('% hook_name%', array ($ PluginName, '% hook_name%'));
class% PluginName% {
var $ some_variable;
/ **
* some function description
*
* @return void
* /
function% hook_name% ()
{
// ...
}
}
// delete the variable as unnecessary
unset ($ PluginName);
When using the options table (these are the functions add_option , update_option , delete_option ), you should also use the prefix from the plugin name, so we will emulate the namespace of our options (for some reason the developers didn’t think of it before) ...
Following these tips we will avoid conflicts with other plugins ...
Plugin installation
To initialize the system, there is a register_activation_hook hook , using it you can make the necessary changes to the database (create tables, make changes to options, etc.). Believe me, the user does not always read readme.txt where it will be written that it is necessary after initialization to save the plug-in settings so that the default values are saved in the database ...
Plugin settings
Let's not break the beautiful Wordpress admin area - the plugin settings should be located in the corresponding menu - Settings » % Plugin Name% .
I also advise you to move the settings page to a separate file with an informative name (for example, % PluginName% _options.php or % PluginName% _settings.php ):
if (is_admin ()) {
add_action ('admin_menu', array ('% PluginName%', 'adminMenu'));
}
class% PluginName% {
function adminMenu ()
{
if (function_exists ('add_options_page')) {
add_options_page ('% PluginName%', '% PluginName%', 'manage_options','% PluginName% /% PluginName% _options.php ');
}
}
}
To make everything beautiful - use the styles specified in wp-admin / wp-admin.css - for this approach you will be thanked ...
Plugin deactivation
If during installation of the plug-in you make any changes to the database or to the file system, then it is advisable to clean these up after the plug-in is disabled, the register_deactivation_hook hook will help you with this .
Customization
Add CSS and JavaScript using the following construction:
// register our CSS file
wp_register_style ('% PluginName%', get_option ('siteurl'). '/wp-content/plugins/%PluginName%/%PluginName%.css');
// either
wp_enqueue_style ('% PluginName%', get_option ('siteurl'). '/wp-content/plugins/%PluginName%/%PluginName%.css');
// register our JS file (with dependencies)
wp_register_script ('% PluginName%', get_option ('siteurl'). '/wp-content/plugins/%PluginName%/%PluginName%.js', array ('jquery' ));
// either
wp_enqueue_script ('% PluginName%', get_option ('siteurl'). '/wp-content/plugins/%PluginName%/%PluginName%.js', array ('jquery'));
This method will work fine if these methods are in the hook on wp_head or admin_head , otherwise you will need to call the wp_print_styles or wp_print_scripts method yourself and pass them the name of the script for output ...
Also, do not forget about conflicts, read about them in article How to load JavaScript in WordPress plugins
If your plugin has a certain graphic design - and it is usually changed for a specific topic - then it is advisable to check for the presence of a CSS file for our plugin in the directory of the current topic:
if (file_exists (TEMPLATEPATH. '/% PluginName% .css')) {
wp_register_style ('% PluginName%', get_bloginfo ('template_directory'). '/%PluginName%.css');
} else {
wp_register_style ('% PluginName%', get_option ('siteurl'). '/wp-content/plugins/%PluginName%/%PluginName%.css');
}
When creating CSS, be very careful that your CSS file should not break the current design, so again, use either prefixes or hard binding:
.% PluginName% -sidebar {/*...*/}
#% PluginName% {/*...*/}
#% PluginName%> div {/*...*/}
Do not forget that the appearance of your plugin can be affected by the CSS file of the current theme - so I advise you to clean margins, paddings and borders ...
These simple tricks will make life easier for ourselves and designers ...
Multilingualism
Do not plan to do multilingualism, but then give others the opportunity to help you, prepare the plug-in for translation, for this it will be enough to create a localization file containing only your language, and use the following functions to display text:
__ ('String', '% PluginName%');
_e ('String', '% PluginName%');
_c ('String', '% PluginName%');
__ngettext ('String', 'Strings', $ c, '% PluginName%')
It is advisable to place the translation files in a separate language directory as well - so as not to clog the root directory of the plugin ...
For more information, see I18n for WordPress Developers
Documentation
If the user is required to make changes to the current topic - it is advisable to describe this process in great detail - and not as usual: "This code will display what you want."
By the way, “this code” should not cause errors if your plugin is disabled, so do not forget to frame the function calls with the following construction:
if (function_exists ('% FunctionName%')) {
% FunctionName% ();
}
?>
Remember - the end user is often not a programmer, and he needs to chew everything and put it in his mouth ...
Compatibility
Unfortunately, Wordpress positions itself as a system with support for PHP4, so if you use PHP5, it is better to inform the user in advance at the stage of plugin inclusion, or create a file to ensure compatibility (if you use only any specific functions):
// include in the plugin file
if (version_compare (phpversion (), '5.1.0', '<')) {
requery_once '% PluginName% _compatibility.php'
}
// what could be in the file
if (! function_exists ('array_diff_key ')) {
function array_diff_key ()
{
$ args = func_get_args ();
return array_flip (call_user_func_array ('array_diff',
array_map ('array_flip', $ args)));
}
}
In order not to reinvent the wheel - I advise you to look at the PEAR PHP_Compat package .
It is likely that you may also need support for older versions of Wordpress:
// include in the plugin file
if (version_compare (get_bloginfo ('version'), '2.6.0', '<')) {
requery_once '% PluginName% _compatibility.php'
}
conclusions
I will summarize.
The plugin directory may look like this:
\plugin-name
|--\languages
|--\library
|--\javascript
|--\css
|-- plugin-name.php
|-- plugin-name_admin.php
|-- plugin-name_front.php
|-- plugin-name_settings.php
|-- plugin-name_compatibility.php
|-- readme.txt
- the% PluginName% prefix is optional, and is even redundant with a large number of files
- languages - all translations will be here
- library - directory for third-party libraries
- javascript and css - contain javascript and css files for your plugin
- readme.txt - required
- the functionality is spread over several files (admin.php, front.php, single.php, etc.)
- version compatibility is provided (compatibility.php)
PS If you have something to add, or there is a link to useful resources on the topic - you are welcome in the comment ...
In preparing the material, the following resources were used:
To highlight the syntax of the code, the highlight.hohli.com resource is used.