Adding an admin or settings page to WordPress

A few weeks ago in my Google Maps Shortcode for WordPress tutorial I covered how to create a basic shortcode. All of the settings required for the Google Maps API where included as configurable attributes for the shortcode. It was discussed in the comments that perhaps it would be better to set some of those options globally. One option discussed was modifying the wp-config.php file, this I don’t think is a great idea. It would mean that it could be potentially overwritten by upgrades and is not easily set by a novice user. The most appropriate way is to setup an Admin page for the shortcode.

This tutorial will pick up where the last one ended, so you’ll need to have read up on it first. It’s available here

Getting Started

The first thing we’ll need to do is add a menu item to the Admin section. To do this we use the add_action function. The add_action function allows us to hook into WordPress events and execute our own code at defined points. The name of the action we’ll be using is ‘admin_menu’, which as you may guess gets triggered when rendering the Admin menu. The add_action function can take up to 4 arguments, but we’re only interested in the first 2. The name of the action and the name of our function we want called. We’ll add this to the init method of our GoogleMap_Shortcode class

static function init() {
    add_shortcode('map', array(__CLASS__, 'render_shortcode'));
    add_action('wp_footer', array(__CLASS__, 'enqueue_map_javascript'));
    add_action('admin_menu', array(__CLASS__, 'add_google_map_admin_menu'));
}

static function add_google_map_admin_menu() {  	
}

Adding a settings page

Now when the Admin menu is being rendered our add_google_map_admin_menu function will be called. It’s sole purpose is to add the settings page using the add_options_page function and add the Google Maps JavaScript. We’re going to leave the menu item under Settings and use a function to output the HTML for the page itself.

static function add_google_map_admin_page() {
}

static function add_google_map_admin_menu() {      
    add_options_page('Google Map Options', 'Google Map', 'manage_options', 'settings.php', array(__CLASS__, 'add_google_map_admin_page'));
    add_action( 'admin_print_scripts', array(__CLASS__, 'enqueue_map_javascript'));
}  
blank

Rendering the settings page

Our add_google_map_admin_page function will be called whenever the user navigates to the settings page from the menu, this is where we will output our form elements and handle the form submit. We could of course use an external file and use an include or require, but for this small example rendering the HTML is perfectly acceptable.

There are 2 sections to this function, the POST conditional to save our form submission and the actual HTML that is visible to the user.

static function add_google_map_admin_page() {  
    if ( $_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['api_key']) ){   
    }
    // GET HTML
    ?>  
    <div class="google-map-options">
        <h1>Google Map Options</h1>      
    </div> 
    <?php
}
header

The POST conditional is going to retrieve the ‘api_key’ value from the $_POST variable and use the update_option function to save it to the database. The HTML section just outputs a simple form and executes our ‘map’ shortcode so the user can see that everything is working.

static function add_google_map_admin_page() {
    if ( !current_user_can( 'manage_options' ) )  {
        wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
    }
    
    if ( $_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['api_key']) ){
        $api_key = $_POST['api_key'];
        update_option( 'GOOGLE_MAP_API_KEY', $api_key );
    }
    // GET
    ?>
    <div class="google-map-options">
        <h1>Google Map Options</h1>
        <form name="options" method="POST" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
            <label for="api_key">Google Map API Key<span class="required">(*)</span>: </label>
            <input type="text" name="api_key" value="<?php echo get_option( 'GOOGLE_MAP_API_KEY', '' ); ?>" size="70">
            <input class="button-primary" type="submit" name="save" />                    
            <br/>
            <small>You can sign up for a API key <a href="https://developers.google.com/maps/signup" target="_blank">here</a></small>                
        </form>
        <br />
        <?php echo do_shortcode('[map]'); ?>
    </div>
    <?php
}

By default the get_option function returns false if the option is not set. So in the above code where we are displaying the current value, we provide it with a default value of ”.

Finishing up

Now all that is left is to update the original code to use the GOOGLE_MAP_API_KEY option instead of the static $api_key. This is done using the get_option again, this time specifying no default value. This means that if the key is not set, it’s value will be false and our existing logic will continue to work as normal. We also need to update the shortcode attributes to not read the api key from the shortcode attributes.

$api_key = get_option( 'GOOGLE_MAP_API_KEY' );
extract( shortcode_atts( array(
    'id' => 'map-canvas-1',
    'class' => '',
    'zoom' => '18',
    'coords' => '53.339381, -6.260405',
    'type' => 'roadmap',
    'width' => '480px',
    'height' => '480px'
), $atts ) );
admin

Using the updated API key

The only difference between this shortcode and the previous one, is that now the api_key attribute can be dropped. Simple add the following to any post to have the map appear.

[map id="map-2" coords="52.339381, -4.260405"]

[map id="map-3" coords="52.339381, -4.260405" zoom="5" type="satellite"]
post

Troubleshooting

If the Google Map is not appearing, but the HTML tags are being rendered this might be because jQuery is not loaded. You can use the following code to ensure that it is loaded correctly

function enqueue_jquery() {
    wp_enqueue_script( 'jquery' );
}
add_action( 'wp_enqueue_scripts', 'enqueue_jquery' );

Here’s the updated full class.

Author: Jonathan Schnittger
A battle hardened software developer with a mixed and colorful background, who can't come up with a decent author bio
  • Yusri Mathews

    Could you use the same principle for adding options to the front-end?

    • Jonny Schnittger

      Do you mean If you wanted to be able to configure additional information for inclusion in say a themes header like an extended description or maybe contact details for the footer? Yes, you would just have the get_option(‘contact-phone-number’, ”); in the appropriate theme file

  • FoxPc

    Hello Jonny and thanks for this tutorial. tried to change the width and the height from the shortcode but it’s not working.
    [map id="map-2" coords="52.339381, -4.260405" width="300" height ="300"]