This tutorial will go through the creation of a version of the Hello World plugin which will:
data/other/
pathCreate the following files/folders:
- hello_world.php - hello_world (directory) - .htaccess (with one line: Deny from all) - admin.php - common_functions.php - lang (directory) - .htaccess (with one line: Deny from all) - en_US.php
Here is where we register the plugin. We shall start out by defining some useful constants (this will be cleaner than defining global variables like $thisfile
and referencing them later - just give the constants informative names):
<?php // === Constants === define('HELLO_WORLD', basename(__FILE__, '.php')); // Plugin ID define('HELLO_WORLD_PLUGINPATH', GSPLUGINPATH . HELLO_WORLD . '/'); // Path to the plugin's assets folder define('HELLO_WORLD_CONFIGFILE', GSDATAOTHERPATH . 'hello_world_config.json'); // File name for the plugin's user-configuration file
Next, we load the internationalized strings that are in the plugin's /lang
directory (which we will define soon):
// === Internationalization === i18n_merge(HELLO_WORLD) || i18n_merge(HELLO_WORLD, 'en_US'); // Loads English language file by default
We will define a number of helpful functions in a separate file, common_functions.php
, and load them at this point:
// === Load functions === require_once(HELLO_WORLD_PLUGINPATH . 'common_functions.php');
Then we register the plugin. Note that this uses one of the assumed functions that we will define, hello_world_i18n
, where there will be language-dependent strings (namely for the plugin name and description):
// === Plugin, Hook and Filter Registration === register_plugin( HELLO_WORLD, // Plugin id hello_world_i18n('PLUGIN_NAME'), // Plugin name '0.1.0', // Plugin version 'You', // Plugin author 'http://www.you.com', // Author website hello_world_i18n('PLUGIN_DESCRIPTION'), // Plugin description 'theme', // Page type - on which admin tab to display 'hello_world_admin' // Main function (administration) );
Lastly, we register the plugin hooks - in this case, one for loading a sidebar menu item, and another for the theme footer:
// Echoes message in footer add_action('theme-footer', 'hello_world_footer'); // Creates sidebar link add_action('theme-sidebar', 'createSideMenu', array(HELLO_WORLD, hello_world_i18n('PLUGIN_SIDEBAR')));
This is the full file:
<?php // === Constants === define('HELLO_WORLD', basename(__FILE__, '.php')); define('HELLO_WORLD_PLUGINPATH', GSPLUGINPATH . HELLO_WORLD . '/'); define('HELLO_WORLD_CONFIGFILE', GSDATAOTHERPATH . 'hello_world_config.json'); // === Internationalization === i18n_merge(HELLO_WORLD) || i18n_merge(HELLO_WORLD, 'en_US'); // === Load functions === require_once(HELLO_WORLD_PLUGINPATH . 'common_functions.php'); // === Plugin, Hook and Filter Registration === register_plugin( HELLO_WORLD, // Plugin id hello_world_i18n('PLUGIN_NAME'), // Plugin name '0.1.0', // Plugin version 'You', // Plugin author 'http://www.you.com', // Author website hello_world_i18n('PLUGIN_DESCRIPTION'), // Plugin description 'theme', // Page type - on which admin tab to display 'hello_world_admin' // Main function (administration) ); // Echoes message in footer add_action('theme-footer', 'hello_world_footer'); // Creates sidebar link add_action('theme-sidebar', 'createSideMenu', array(HELLO_WORLD, hello_world_i18n('PLUGIN_SIDEBAR')));
The PHP files in the /lang
directory just need to define an $i18n
array of internationalized strings. Once we've merged the plugin's language strings with i18n_merge
, these strings will be available via i18n('hello_world/STRING_NAME', true)
, which we will alias hello_world_i18n('STRING_NAME')
<?php // en_US.php $i18n = array(); $i18n['PLUGIN_NAME'] = 'Hello World Plugin (Extended)'; $i18n['PLUGIN_DESCRIPTION'] = 'Echoes "Hello World" (or a message of your choice) in theme footers.'; $i18n['PLUGIN_SIDEBAR'] = 'Hello World description'; $i18n['ADMIN'] = 'Hello World Admin Panel'; $i18n['HELLO_WORLD'] = 'Hello World!'; $i18n['SAVE'] = 'Save Configuration'; $i18n['CONFIG_SAVE_SUCCESS'] = 'Configuration saved!'; $i18n['CONFIG_SAVE_ERROR'] = 'Error saving configuration!';
The first functions that we need to define are hello_world_i18n
(i18n
alias), hello_world_admin
(displays the administration panel) and hello_world_footer
(echoes the message into the theme footer). The latter two will just be stubs that get filled in later:
// Alias for getting i18n strings for this plugin function hello_world_i18n($key) { return i18n_r(HELLO_WORLD . '/' . $key); } // Administration panel function hello_world_admin() { // ... } // Hook for the theme footer function hello_world_footer() { // ... }
Now consider the operations that we want to have for the plugin data. The administrator will be able to create a custom message, save it, and then this message will be printed in the theme footer. So we shall create functions for saving this message into a file the data/other
folder. To future-proof this plugin, we will save the data as key⇒value
pairs, so the message will be a value with a designated key (ideally the key message
):
// Given an array of key=>value mappings, save that data to the configuration file function hello_world_save_config($config = array()) { $file = HELLO_WORLD_CONFIGFILE; $contents = json_encode($config); // Encodes the array into a valid JSON string return file_put_contents($file, $contents); // Saves the JSON string into the configuration JSON file } // Load plugin configuration from the JSON file as an array function hello_world_get_config() { $file = HELLO_WORLD_CONFIGFILE; $contents = file_get_contents($file); $json = json_decode($contents); // Decodes the string $config = (array) $json; // Converts the object into a PHP array return $config; }
When the plugin is first loaded, the configuration file might not exist. So let's create some utility functions that detect if the file exists, and which create some default data:
// Check that the configuration file exists function hello_world_config_exists() { return file_exists(HELLO_WORLD_CONFIGFILE); } // Create a default configuration file function hello_world_init() { $config = array('message' => hello_world_i18n('HELLO_WORLD')); return hello_world_save_config($config); }
Now we can expand on the administration panel. First we ensure that the configuration file exists:
// Administration panel function hello_world_admin() { // Initialize the configuration file $init = hello_world_config_exists() || hello_world_init(); // ... }
Then we will load the configuration data, and load the admin.php
file (which will use this data and display the admin panel):
// Administration panel function hello_world_admin() { // Initialize the configuration file $init = hello_world_config_exists() || hello_world_init(); // still more to add... // Show the admin panel page $config = hello_world_get_config(); include(HELLO_WORLD_PLUGINPATH . '/admin.php'); }
The admin panel will have a <form>
whose method is POST
and whose action is simply the same page. There will be a text field with the name message
, and the submit button in said form will have the name save-configuration
. So if we want to save the configuration, we will need to check if the $_POST
variable is populated with the save-configuration
key:
function hello_world_admin() { // Initialize the configuration file $init = hello_world_config_exists() || hello_world_init(); // Check if we need to save the configuration $save_changes = isset($_POST['save-configuration']); if ($save_changes) { $save_success = hello_world_save_config($data); } // Show the admin panel page $config = hello_world_get_config(); include(HELLO_WORLD_PLUGINPATH . '/admin.php'); }
Lastly, we need the footer hook to actually load the message:
// Hook for the theme footer function hello_world_footer() { $config = hello_world_get_config(); echo '<p>' . $config['message'] . '</p>'; }
This is the full file. It slightly expands on the administration panel by printing error messages and a introducing a placeholder for validating the submitted data:
<?php // === Functions === // Hook for the theme footer function hello_world_footer() { $config = hello_world_get_config(); echo '<p>' . $config['message'] . '</p>'; } // Alias for getting i18n strings for this plugin function hello_world_i18n($key) { return i18n_r(HELLO_WORLD . '/' . $key); } // Administration panel function hello_world_admin() { // Initialize the configuration file $init = hello_world_config_exists() || hello_world_init(); // Check if we need to save the configuration $save_changes = isset($_POST['save-configuration']); if ($save_changes) { // Validate and save the config $data = hello_world_validate_config($_POST); $save_success = hello_world_save_config($data); // Display a success/error status message for the admin hello_world_display_status_message($save_success); } // Show the admin panel page $config = hello_world_get_config(); include(HELLO_WORLD_PLUGINPATH . '/admin.php'); } // Load plugin configuration into an array function hello_world_get_config() { $file = HELLO_WORLD_CONFIGFILE; $contents = file_get_contents($file); $json = json_decode($contents); $config = (array) $json; return $config; } // Save array data to the configuration function hello_world_save_config($config = array()) { $file = HELLO_WORLD_CONFIGFILE; $contents = json_encode($config); return file_put_contents($file, $contents); } // Validate an array for saving it as a configuration object function hello_world_validate_config($data) { // Clean up the configuration array... $config = array( 'message' => $data['message'], ); return $config; } // Check that the configuration file exists function hello_world_config_exists() { return file_exists(HELLO_WORLD_CONFIGFILE); } // Create a default configuration file function hello_world_init() { $config = array('message' => hello_world_i18n('HELLO_WORLD')); return hello_world_save_config($config); } // Display the success/error status of a coonfiguration's saving function hello_world_display_status_message($status) { if ($status) { $class = 'success'; $message = hello_world_i18n('CONFIG_SAVE_SUCCESS'); } else { $class = 'error'; $message = hello_world_i18n('CONFIG_SAVE_ERROR'); } echo '<div class="' . $class . '">' . $message . '</div>'; }
Lastly we define the look of the administration panel. As stated above, it will have a <form>
with a message
input field, save-configuration
button, and will send the data from the form via POST
. All that is needed is to ensure the input field is populated with the last saved message:
<h3><?php echo hello_world_i18n('ADMIN'); ?></h3> <form method="post"> <input name="message" value="<?php echo $config['message']; ?>"> <button name="save-configuration"><?php echo hello_world_i18n('SAVE'); ?></button> </form>