Paulund
2012-09-17 #wordpress

How To Create A Theme Options Page For Wordpress

If you have ever used a Wordpress premium theme then you would have seen the custom theme options page that are available. The theme options page that is found under the appearance menu which allows the admin of the Wordpress site to change some of the settings on the theme. Most premium themes will come with options to change the colours of fonts, backgrounds, change images or font types...anything that allows you to style the Wordpress theme. Some of the most common fields to change are:

  • Theme Options - To edit the theme logo, change the stylesheet, upload a new favicon, Add Google analytics code, enter your feedburner URL and add custom CSS.
  • Styling Options - Change the background colour or change the background image.
  • Fonts - Change the font on all your header tags or the main content text.
  • Social - Providing you theme with your social media profiles will make it easier to link to them in parts of your theme or display your latest tweets.

Option pages can also be used on plugins to change settings and to customise the plugin.

How To Build A Theme Option Page

When creating an option page there are a few things you need to setup.

  • Add Menu - If you want to display the menu under the appearance menu or if you want to give the options page it's own menu.
  • Add Sections - These are sections of settings you are adding to the options page.
  • Register Settings - Settings are the different fields you are adding to the options page, they need to be registered with the settings API.
  • Display Settings - The settings API will be used to call a function to display the setting.
  • Validate Setting - When the user saves the settings field the input will need to be validated before stored in the options table.
  • Feedback Messages - When the settings are saved you need to be able to feedback to the user if the settings were saved successfully or if there was an error during validation.

To help us perform all these tasks there is a Wordpress API called the Settings API. This API allows admin pages to handle setting forms semi-automatically. With the API you can define pages for the settings, sections for the settings and fields for the settings. This works by registering setting fields to be displayed within sections and page will display these sections. Wordpress uses the Settings API by default on existing admin pages, this means that by using the Settings API you can add to existing pages by registering new settings. All validation must be performed by the developer of the settings pages but the Settings API will control the creation of the form and storing the values in the form in the options table.

Add Menu To Wordpress Admin

When adding a menu to the Wordpress admin screen you have loads of flexibility you have the option of adding brand new menu items or adding the menu as a sub menu. To add a top level menu just use the following function add_menu_page().

<?php add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position ); ?>

  • $page_title - The title used on the settings page.
  • $menu_title - The title used on the menu.
  • $capability - Only displays the menu if the user matches this capability.
  • $menu_slug - The unique name of the menu slug.
  • $function - This is the callback function to run to display the page.
  • $icon_url - Display a icon just for the menu.
  • $position - This allows you to choose when the menu item appears in the list.

If you prefer to have the menu under the appearance parent menu you can use the following code snippet.

<?php 
add_action('admin_menu', 'add_appearance_menu');

function add_appearance_menu(){
     add_submenu_page( 'themes.php', $page_title, $menu_title, $capability, $menu_slug, $function); 
}
?>

Or you can use the function add_theme_page() which will add a sub-menu under the appearance menu.

add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function);

Registering The Settings

To start off we need to register the settings group we are going to store the settings page values. This will use the Settings API to define the group of settings, we will then add the settings to a group. When you store the settings in this group they are stored in the wp_options database table so you can get these values out at a later date. The wp_options table is a key value pairing stored in the database. This is what you should use when storing long term data on your Wordpress site. If you are storing a lot of data it's best practice to turn the data into an array and store it under one key, instead of storing all the values over multiple keys. This means that if you have a settings page to change the site logo, background colour, font, font size etc, you won't have an option for each of these but you will group them into an option group. The reason you do this is to increase on database efficiency by not adding too many rows to the options database. To register settings on the Settings API you need to use the function register_setting().


<?php register_setting( $option_group, $option_name, $sanitize_callback ); ?> 

The parameters you pass into this are: - Option Group - The name of the group of settings you are going to store. This must match the group name used in the settings_field() function.

  • Option name - The name of the option which will be saved, this is the key that is used in the options table.
  • Sanitize Callback - This is the function that is used to validate the settings for this option group.

Add Sections To Settings

Once the settings are registered we can add section groups to the Settings API. This will allow us to organise the settings on the page, so that you can add styles to display these differently on the page. The benefit of adding sections on your Settings API is so that we can call the function do_settings_sections() as this will display all the settings under this one section. To create you own settings all you have to do is use the function add_settings_section().


<?php add_settings_section( $id, $title, $callback, $page ); ?>

The parameters you need to use on this function are: - Id - String to use for the ID of the section.

  • Title - The title to use on the section.
  • Callback - This is the function that will display the settings on the page.
  • Page - This is the page that is displaying the section, should match the menu slug of the page.

Add Fields To The Sections

The last important function we need to use to add settings to the page is the add_settings_field() function, this is used as part of the Settings API to define fields to a section. The function will need to know the page slug and the section Id before you can define the settings to use. All the settings which you setup here will be stored in the options table under the key used in the register_settings() function.


<?php add_settings_field( $id, $title, $callback, $page, $section, $args ); ?>

To use this function you need to add the following parameters. - ID - ID of the field

  • Title - Title of the field.
  • Callback - Function used to display the setting. This is very important as it is used to display the input field you want.
  • Page - Page which is going to display the field should be the same as the menu slug on the section.
  • Section - Section Id which the field will be added to.
  • $args - Additional arguments which are passed to the callback function.

Example Of Using The Settings API

There is a lot of information to take in above to create this settings page so it can seem a bit complicated but once you get your head around the structure the Settings API uses it's actually quite easy to understand. The best way to understand how this all works is to show you with an example.

Create A Theme Option Page With A Textbox Field

In this example we will create a theme option page and add a textbox on the page to add additional text to the index.php. Just add the following to your functions.php file to create a theme options page. First we start off by creating the menu item under the appearance menu by using the add_theme_page() function on the admin_menu action.


/**
 * Theme Option Page Example
 */
function pu_theme_menu()
{
  add_theme_page( 'Theme Option', 'Theme Options', 'manage_options', 'pu_theme_options.php', 'pu_theme_page');  
}
add_action('admin_menu', 'pu_theme_menu');

As you can see above we set the callback function to the theme options page to be pu_theme_page so we need to create this function to display our page. Here we create a form to submit to the options.php so that we can save in the options table, we call settings_fields() to the get the settings in register_settings() and use the do_settings_sections() function to display our settings.


/**
 * Callback function to the add_theme_page
 * Will display the theme options page
 */ 
function pu_theme_page()
{
?>
    <div class="section panel">
      <h1>Custom Theme Options</h1>
      <form method="post" enctype="multipart/form-data" action="options.php">
        <?php 
          settings_fields('pu_theme_options'); 
        
          do_settings_sections('pu_theme_options.php');
        ?>
            <p class="submit">  
                <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />  
            </p>  
            
      </form>
      
      <p>Created by <a href="http://www.paulund.co.uk">Paulund</a>.</p>
    </div>
    <?php
}

With the page ready to display the settings we can register the settings and create the sections. On the admin_init action we call a function pu_register_settings in here we define the settings, sections and fields for the sections.


/**
 * Register the settings to use on the theme options page
 */
add_action( 'admin_init', 'pu_register_settings' );

/**
 * Function to register the settings
 */
function pu_register_settings()
{
    // Register the settings with Validation callback
    register_setting( 'pu_theme_options', 'pu_theme_options', 'pu_validate_settings' );

    // Add settings section
    add_settings_section( 'pu_text_section', 'Text box Title', 'pu_display_section', 'pu_theme_options.php' );

    // Create textbox field
    $field_args = array(
      'type'      => 'text',
      'id'        => 'pu_textbox',
      'name'      => 'pu_textbox',
      'desc'      => 'Example of textbox description',
      'std'       => '',
      'label_for' => 'pu_textbox',
      'class'     => 'css_class'
    );

    add_settings_field( 'example_textbox', 'Example Textbox', 'pu_display_setting', 'pu_theme_options.php', 'pu_text_section', $field_args );
}

The callback function on creating sections can be used to add addition information that will appear above every section, on this example we are just leaving it blank.


/**
 * Function to add extra text to display on each section
 */
function pu_display_section($section){ 

}

The callback function on the add_settings_field() function is pu_display_setting, this is the function that is going to echo the display of any input's on the page. The parameter to this function is the $args value on the add_settings_field() we can use this to add things like id, name, default value etc. We want to get any existing values from the wp_option table to display any values which previously typed in by the user, do to this we get the values from the table by using the get_option() function.


/**
 * Function to display the settings on the page
 * This is setup to be expandable by using a switch on the type variable.
 * In future you can add multiple types to be display from this function,
 * Such as checkboxes, select boxes, file upload boxes etc.
 */
function pu_display_setting($args)
{
    extract( $args );

    $option_name = 'pu_theme_options';

    $options = get_option( $option_name );

    switch ( $type ) {  
          case 'text':  
              $options[$id] = stripslashes($options[$id]);  
              $options[$id] = esc_attr( $options[$id]);  
              echo "<input class='regular-text$class' type='text' id='$id' name='" . $option_name . "[$id]' value='$options[$id]' />";  
              echo ($desc != '') ? "<br /><span class='description'>$desc</span>" : "";  
          break;  
    }
}

Finally we can validate the values added to the form by creating the validation callback function pu_validate_settings. All this does at the moment is loop through the inputs passed to it and checks if it's a letter or a number. The return of this function is what will be added to the database.


/**
 * Callback function to the register_settings function will pass through an input variable
 * You can then validate the values and the return variable will be the values stored in the database.
 */
function pu_validate_settings($input)
{
  foreach($input as $k => $v)
  {
    $newinput[$k] = trim($v);
    
    // Check the input is a letter or a number
    if(!preg_match('/^[A-Z0-9 _]*$/i', $v)) {
      $newinput[$k] = '';
    }
  }

  return $newinput;
}

If you copy all the snippets above into your functions.php file you will see this options form under the appearance menu.

Using Theme Options Within Your Theme

Now that you understand how to create a theme options page you need to be able to use this value in your theme so you can change the settings. All the settings are stored in the wp_options table with Wordpress it's very easy to get these values out all you have to do is use the get_option() function.


<?php
$options = get_option( $option_name );
?>

The option name is the name you put on the register_settings() function. So in our example above you will use this code.


<?php
$options = get_option( 'pu_theme_options' );
?>

The $options variable will now store an array of the values from the theme options, which you can display the value of the textbox we put on the page by using this snippet.


<?php
$options = get_option( 'pu_theme_options' );
echo $options['pu_textbox'];
?>

Conclusion

That's the basics that you need to understand to use the Settings API, now you can take this information and create your own theme options page. Experiment with different input types you can add to the form, experiment with different validation methods you want to use. In future tutorials I will post how you can use some of the inbuilt WordPress third party applications to create a better user experience on your theme options panel. This will include things like colour pickers, date pickers, jQuery UI features etc. As you can see we have created a settings option page in just over 100 lines of code, so it's not a hard thing to do but that are a few steps to it and the features can be expanded on. For this reason people have created theme option frameworks to allow you to easily create a theme option page with much higher level of complexity with the options. But like many other frameworks I always recommend you learn the basics before using a framework, this is why it's important to understand how the Settings API works before using or creating a settings page framework.

WordPress Theme Customiser

If all the settings you are making in the theme options page are just for cosmetic changes like font family, font size, background colours etc then you should look into using the new WordPress theme customiser. Created in WordPress version 3.4 it allows you to create a number of fields in the admin area, this will allow your visitors to make changes to the theme and see these changes in real time in the preview window. WordPress Theme Customiser