Themes can include plugins that can add a settings panel to the back-end, hook into other modules or even add new template tags to display content in a special way exclusive to the theme.
In this tutorial, we will look at the plugin file for the theme used on Mikael Stær's website (the developer of The Secretary). It covers installation and uninstallation functionality of themes, how to create a theme settings panel, and how to introduce a new template tag.
Note that some of the code used in this tutorial, such as the use of the Manager and Clerk class, is currently undocumented. The adventurous will have to look at the source code for now (look in the ../assistants/ folder).
Step 1
Create a file called plugin.php and upload it to your theme folder. It will be automatically included in both the front and back-end.
Step 2: Installation and Uninstallation functions
The Secretary allows themes to hook into the activation and deactivation processes, which is useful if, for example, the theme requires the usage of a new database setting. An uninstall function should always be provided, to “clean up” any changes or modifications made and return the system to its original state.
The install function is called when the user selects a theme by clicking “Use this theme” on the Themes page. The uninstall function is called when the user selects a new theme, thus deactivating the current one.
The theme used on mikaelstaer.com is called Nathan, so the install function is called install_nathan(). The theme pulls in the thumbnails of each image in each project and displays them on the front page. The number of thumbnails displayed is controlled by a setting which can be managed in the back-end:
function install_nathan() { global $manager; // Check if setting already exists if ( $manager->clerk->getSetting( "nathanNumberImages", 1 ) == "" ) { // No, it doesn't - create it $manager->clerk->addSetting( "nathanNumberImages", array( 10 ) ); } }
The uninstall function looks like this:
function uninstall_nathan() { global $manager; $manager->clerk->removeSetting( "nathanNumberImages" ); }
Step 3: The settings panel
Now, we must hook into the theme settings action, by defining a hook (placed at the top of the file).:
// function hook( string $action, string $function ) hook( "theme_settings", "nathanSettings" );
Next, the nathanSettings() function further hooks three functions into three different actions in the back-end: the first defines the form; the second defines the submit buttons for the form; and the third hooks into the actual submit action of the form, processing the data and saving it in the database.
function nathanSettings() { hook( "form_main", "nathanSettingsForm" ); hook( "form_submit_primary", "nathanSettingsFormSubmit" ); hook( "form_process", "nathanSettingsProcess" ); }
The functions look like this:
// Create the form fields function nathanSettingsForm() { global $manager; // Add a fieldset $manager->form->add_fieldset( "General Settings", "general" ); // Add a text field, named "numberImages". // Default value is the value of the setting. $manager->form->add_input( "text", "numberImages", "How many thumbnails to display?", $manager->clerk->getSetting( "nathanNumberImages", 1 ) ); $manager->form->close_fieldset(); } function nathanSettingsFormSubmit() { global $manager; // Add a save button $manager->form->add_input( 'submit', 'submit', 'Save', 'save' ); } function nathanSettingsProcess() { global $manager; // Save the new number in the database if ( $manager->clerk->updateSetting( "nathanNumberImages", array( $_POST['numberImages'] ) ) ) { // Output a success message $manager->message( 1, false, "Settings saved!" ); } else { // There was an error, output a failed message, with MySQL debug $manager->message( 0, true, "Settings could not be saved!" ); } }
Step 4: Night and Day template tag
The theme also changes colour depending on the time of day - a dark and light version, which is controlled by adding a class to the <body> tag. To do this easily, a template tag was created which is used in the layout files:
function nightAndDay() { $hour = date("H"); // Server time is reversed, from my end (Denmark) at least! if ( $hour >= 9 && $hour < 18 ) return "dark"; else return "light"; }
In the layouts, the body tag looks like this:
<body class="<?php echo nightAndDay(); ?>">
Everything all together
This is how the entire plugin file for mikaelstaer.com's Nathan theme looks:
<?php hook( "theme_settings", "nathanSettings" ); function install_nathan() { global $manager; if ( $manager->clerk->getSetting( "nathanNumberImages", 1 ) == "" ) { $manager->clerk->addSetting( "nathanNumberImages", array( 10 ) ); } } function uninstall_nathan() { global $manager; $manager->clerk->removeSetting( "nathanNumberImages" ); } function nathanSettings() { hook( "form_main", "nathanSettingsForm" ); hook( "form_submit_primary", "nathanSettingsFormSubmit" ); hook( "form_process", "nathanSettingsProcess" ); } function nathanSettingsForm() { global $manager; $manager->form->add_fieldset( "General Settings", "general" ); $manager->form->add_input( "text", "numberImages", "How many thumbnails to display?", $manager->clerk->getSetting( "nathanNumberImages", 1 ) ); $manager->form->close_fieldset(); } function nathanSettingsFormSubmit() { global $manager; $manager->form->add_input( 'submit', 'submit', 'Save', 'save' ); } function nathanSettingsProcess() { global $manager; if ( $manager->clerk->updateSetting( "nathanNumberImages", array( $_POST['numberImages'] ) ) ) $manager->message( 1, false, "Settings saved!" ); else $manager->message( 0, true, "Settings could not be saved!" ); } function nightAndDay() { $hour = date("H"); // Server time is reversed, from my end at least! if ( $hour >= 9 && $hour < 18 ) return "dark"; else return "light"; } ?>