13 min read

In this article, Yannick Lefebvre, author of WordPress Plugin Development Cookbook, Second Edition will cover the following recipes:

  • Creating a new shortcode with parameters
  • Managing multiple sets of user settings from a single admin page

WordPress shortcodes are a simple, yet powerful tool that can be used to automate the insertion of code into web pages. For example, a shortcode could be used to automate the insertion of videos from a third-party platform that is not supported natively by WordPress, or embed content from a popular web site. By following the two code samples found in this article, you will learn how to create a WordPress plugin that defines your own shortcode to be able to quickly embed Twitter feeds on a web site. You will also learn how to create an administration configuration panel to be able to create a set of configurations that can be referenced when using your newly-created shortcode.

Creating a new shortcode with parameters

While simple shortcodes already provide a lot of potential to output complex content to a page by entering a few characters in the post editor, shortcodes become even more useful when they are coupled with parameters that will be passed to their associated processing function. Using this technique, it becomes very easy to create a shortcode that accelerates the insertion of external content in WordPress posts or pages by only needing to specify the shortcode and the unique identifier of the source element to be displayed.

We will illustrate this concept in this recipe by creating a shortcode that will be used to quickly add Twitter feeds to posts or pages.

How to do it…

  1. Navigate to the WordPress plugin directory of your development installation.
  2. Create a new directory called ch3-twitter-embed.
  3. Navigate to this directory and create a new text file called ch3-twitter-embed.php.
  4. Open the new file in a code editor and add an appropriate header at the top of the plugin file, naming the plugin Chapter 2 - Twitter Embed.
  5. Add the following line of code to declare a new shortcode and specify the name of the function that should be called when the shortcode is found in posts or pages:
    add_shortcode( 'twitterfeed', 'ch3te_twitter_embed_shortcode' );
  6. Add the following code section to provide an implementation for the ch3te_twitter_embed_shortcode function:
    function ch3te_twitter_embed_shortcode( $atts ) {
    extract( shortcode_atts( array(
    'user_name' => 'ylefebvre'
    ), $atts ) );
    if ( !empty( $user_name ) ) {
    $output = '<a class="twitter-timeline" href="';
    $output .= esc_url( 'https://twitter.com/' . $user_name );
    $output .= '">Tweets by ' . esc_html( $user_name );
    $output .= '</a><script async ';
    $output .= 'src="//platform.twitter.com/widgets.js"';
    $output .= ' charset="utf-8"></script>';
    } else {
    $output = '';
    }
    return $output;
    }.
  7. Save and close the plugin file.
  8. Log in to the administration page of your development WordPress installation.
  9. Click on Plugins in the left-hand navigation menu.
  10. Activate your new plugin.
  11. Create a new page and use the shortcode [twitterfeed user_name='WordPress'] in the page editor, where WordPress is the Twitter username of the feed to display:
  12. Save and view the page to see that the shortcode was replaced by an embedded Twitter feed on your site.
  13. Edit the page and remove the user_name parameter and its associated value, only leaving the core [twitterfeed] shortcode in the post and Save.
  14. Refresh the page and see that the feed is still being displayed but now shows tweets from another account.

How it works…

When shortcodes are used with parameters, these extra pieces of data are sent to the associated processing function in the $atts parameter variable. By using a combination of the standard PHP extract and WordPress-specific shortcode_atts functions, our plugin is able to parse the data sent to the shortcode and create an array of identifiers and values that are subsequently transformed into PHP variables that we can use in the rest of our shortcode implementation function. In this specific example, we expect a single variable to be used, called user_name, which will be stored in a PHP variable called $user_name. If the user enters the shortcode without any parameter, a default value of ylefebvre will be assigned to the username variable to ensure that the plugin still works. Since we are going to accept user input in this code, we also verify that the user did not provide an empty string and we use the esc_html and esc_url functions to remove any potentially harmful HTML characters from the input string and make sure that the link destination URL is valid.

Once we have access to the twitter username, we can put together the required HTML code that will embed a Twitter feed in our page and display the selected user’s tweets.

While this example only has one argument, it is possible to define multiple parameters for a shortcode.

Managing multiple sets of user settings from a single admin page

Throughout this article, you have learned how to create configuration pages to manage single sets of configuration options for our plugins. In some cases, only being able to specify a single set of options will not be enough. For example, looking back at the Twitter embed shortcode plugin that was created, a single configuration panel would only allow users to specify one set of options, such as the desired twitter feed dimensions or the number of tweets to display. A more flexible solution would be to allow users to specify multiple sets of configuration options, which could then be called up by using an extra shortcode parameter (for example, [twitterfeed user_name="WordPress" option_id="2"]).

While the first thought that might cross your mind to configure such a plugin is to create a multi-level menu item with submenus to store a number of different settings, this method would produce a very awkward interface for users to navigate. A better way is to use a single panel but give the user a way to select between multiple sets of options to be modified.

In this recipe, you will learn how to enhance the previously created Twitter feed shortcode plugin to be able to control the embedded feed size and number of tweets to display from the plugin configuration panel and to give users the ability to specify multiple display sizes.

Getting ready

You should have already followed the Creating a new shortcode with parameters recipe in the article to have a starting point for this recipe. Alternatively, you can get the resulting code (Chapter 2/ch3-twitter-embed/ch3-twitter-embed.php) from the downloaded code bundle.

How to do it…

  1. Navigate to the ch3-twitter-embed folder of the WordPress plugin directory of your development installation.
  2. Open the ch3-twitter-embed.php file in a text editor.
  3. Add the following lines of code to implement an activation callback to initialize plugin options when it is installed or upgraded:
    register_activation_hook( __FILE__,
    'ch3te_set_default_options_array' );
    function ch3te_set_default_options_array() {
    ch3te_get_options();
    }
    Introduction to WordPress Plugin
    [ 6 ]
    function ch3te_get_options( $id = 1 ) {
    $options = get_option( 'ch3te_options_' . $id,
    array() );
    $new_options['setting_name'] = 'Default';
    $new_options['width'] = 560;
    $new_options['number_of_tweets'] = 3;
    $merged_options = wp_parse_args( $options,
    $new_options );
    $compare_options = array_diff_key( $new_options,
    $options );
    if ( empty( $options ) || !empty( $compare_options
    ) ) {
    update_option( 'ch3te_options_' . $id,
    $merged_options );
    }
    return $merged_options;
    }
  4. Insert the following code segment to register a function to be called when the administration menu is put together. When this happens, the callback function adds an item to the Settings menu and specifies the function to be called to render the configuration page:
    // Assign function to be called when admin menu is
    constructed
    add_action( 'admin_menu', 'ch3te_settings_menu' );
    // Function to add item to Settings menu and
    // specify function to display options page content
    function ch3te_settings_menu() {
    add_options_page( 'Twitter Embed Configuration',
    'Twitter Embed', 'manage_options',
    'ch3te-twitter-embed', 'ch3te_config_page' );
  5. Add the following code to implement the configuration page rendering function:
    // Function to display options page content
    function ch3te_config_page() {
    // Retrieve plugin configuration options from
    database
    if ( isset( $_GET['option_id'] ) ) {
    $option_id = intval( $_GET['option_id'] );
    } elseif ( isset( $_POST['option_id'] ) ) {
    $option_id = intval( $_POST['option_id'] );
    } else {
    Introduction to WordPress Plugin
    [ 7 ]
    $option_id = 1;
    }
    $options = ch3te_get_options( $option_id ); ?>
    <div id="ch3te-general" class="wrap">
    <h3>Twitter Embed</h3>
    <!-- Display message when settings are saved -->
    <?php if ( isset( $_GET['message'] ) &&
    $_GET['message'] == '1' ) { ?>
    <div id='message' class='updated fade'>
    <p><strong>Settings Saved</strong></p></div>
    <?php } ?>
    <!-- Option selector -->
    <div id="icon-themes" class="icon32"><br></div>
    <h3 class="nav-tab-wrapper">
    <?php for ( $counter = 1; $counter <= 5; $counter++ )
    {
    $temp_options = ch3te_get_options( $counter);
    $class = ( $counter == $option_id ) ? ' nav-tabactive'
    : ''; ?>
    <a class="nav-tab<?php echo $class; ?>" href="<?php
    echo
    add_query_arg( array( 'page' => 'ch3te-twitterembed',
    'option_id' => $counter ), admin_url(
    'options-general.php' ) ); ?>"><?php echo $counter;
    ?><?php if ( $temp_options !== false ) echo ' (' .
    $temp_options['setting_name'] . ')'; else echo '
    (Empty)'; ?></a>
    <?php } ?>
    </h3><br />
    <!-- Main options form -->
    <form name="ch3te_options_form" method="post"
    action="admin-post.php">
    <input type="hidden" name="action"
    value="save_ch3te_options" />
    <input type="hidden" name="option_id"
    value="<?php echo $option_id; ?>" />
    <?php wp_nonce_field( 'ch3te' ); ?>
    <table>
    <tr><td>Setting name</td>
    <td><input type="text" name="setting_name"
    value="<?php echo esc_html(
    $options['setting_name'] ); ?>"/>
    </td>
    </tr>
    <tr><td>Feed width</td>
    <td><input type="text" name="width"
    Introduction to WordPress Plugin
    [ 8 ]
    value="<?php echo esc_html( $options['width']
    ); ?>"/></td>
    </tr>
    <tr><td>Number of Tweets to display</td>
    <td><input type="text" name="number_of_tweets"
    value="<?php echo esc_html( $options['height']
    ); ?>"/></td>
    </tr>
    </table><br />
    <input type="submit" value="Submit" class="buttonprimary"
    />
    </form>
    </div>
    <?php }
  6. Add the following block of code to register a function that will process user options when submitted to the site:
    add_action( 'admin_init', 'ch3te_admin_init' );
    function ch3te_admin_init() {
    add_action( 'admin_post_save_ch3te_options',
    'process_ch3te_options' );
    
  7. Add the following code to implement the process_ch3te_options function, declared in the previous block of code, and to declare a utility function used to clean the redirection path:
    // Function to process user data submission
    function process_ch3te_options() {
    // Check that user has proper security level
    if ( !current_user_can( 'manage_options' ) ) {
    wp_die( 'Not allowed' );
    }
    // Check that nonce field is present
    check_admin_referer( 'ch3te' );
    // Check if option_id field was present
    if ( isset( $_POST['option_id'] ) ) {
    $option_id = intval( $_POST['option_id'] );
    } else {
    $option_id = 1;
    }
    // Build option name and retrieve options
    $options = ch3te_get_options( $option_id );
    // Cycle through all text fields and store their
    Introduction to WordPress Plugin
    [ 9 ]
    values
    foreach ( array( 'setting_name' ) as $param_name )
    {
    if ( isset( $_POST[$param_name] ) ) {
    $options[$param_name] = sanitize_text_field(
    $_POST[$param_name] );
    }
    }
    // Cycle through all numeric fields, convert to int
    and store
    foreach ( array( 'width', 'number_of_tweets' ) as
    $param_name ) {
    if ( isset( $_POST[$param_name] ) ) {
    $options[$param_name] = intval( $_POST[$param_name]
    );
    }
    }
    // Store updated options array to database
    $options_name = 'ch3te_options_' . $option_id;
    update_option( $options_name, $options );
    $cleanaddress = add_query_arg( array( 'message' =>
    1,
    'option_id' => $option_id,
    'page' => 'ch3te-twitter-embed' ),
    admin_url( 'options-general.php' ) );
    wp_redirect( $cleanaddress );
    exit;
    }
      // Function to process user data submission 
function process_ch3te_options() {
// Check that user has proper security level
if ( !current_user_can( 'manage_options' ) ) {
wp_die( 'Not allowed' );
}

// Check that nonce field is present
check_admin_referer( 'ch3te' );

// Check if option_id field was present
if ( isset( $_POST['option_id'] ) ) {
$option_id = intval( $_POST['option_id'] );
} else {
$option_id = 1;
}

// Build option name and retrieve options
$options = ch3te_get_options( $option_id );

// Cycle through all text fields and store their
values
foreach ( array( 'setting_name' ) as $param_name )
{
if ( isset( $_POST[$param_name] ) ) {
$options[$param_name] = sanitize_text_field(
$_POST[$param_name] );
}
}

  1. Find the ch3te_twitter_embed_shortcode function and modify it as follows to accept the new option_id parameter and load the plugin options to produce the desired output. The changes are identified in bold within the recipe:
    function ch3te_twitter_embed_shortcode( $atts ) {
    extract( shortcode_atts( array(
    'user_name' => 'ylefebvre',
    'option_id' => '1'
    ), $atts ) );
    if ( intval( $option_id ) < 1 || intval(
    $option_id ) > 5 ) {
    $option_id = 1;
    }
    $options = ch3te_get_options( $option_id );
    if ( !empty( $user_name ) ) {
    $output = '<a class="twitter-timeline" href="';
    $output .= esc_url( 'https://twitter.com/' .
    $user_name );
    $output .= '" data-width="' . $options['width'] .
  2. Save and close the plugin file.
  3. Deactivate and then Activate the Chapter 2 - Twitter Embed plugin from the administration interface to execute its activation function and create default settings.
  4. Navigate to the Settings menu and select the Twitter Embed submenu item to see the newly created configuration panel with the first set of options being displayed and more sets of options accessible through the drop-down list shown at the top of the page.
  1. To select the set of options to be used, add the parameter option_id to the shortcode used to display a Twitter feed, as follows:
     [twitterfeed user_name="WordPress" option_id="1"]

How it works…

This recipe shows how we can leverage options arrays to create multiple sets of options simply by creating the name of the options array on the fly. Instead of having a specific option name in the first parameter of the get_option function call, we create a string with an option ID. This ID is sent through as a URL parameter on the configuration page and as a hidden text field when processing the form data.

On initialization, the plugin only creates a single set of options, which is probably enough for most casual users of the plugin. Doing so will avoid cluttering the site database with useless options. When the user requests to view one of the empty option sets, the plugin creates a new set of options right before rendering the options page.

The rest of the code is very similar to the other examples that we saw in this article, since the way to access the array elements remains the same.

Summary

In this article, the author has explained about the entire process of how to create a new shortcode with parameters and how to manage multiple sets of user settings from a single admin page.


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here