In this article, Yannick Lefebvre, author of Wordpress Plugin Development Cookbook, Second Edition will cover the following recipes:
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.
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.
add_shortcode( 'twitterfeed', 'ch3te_twitter_embed_shortcode' );
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; }
.
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.
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.
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.
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;
}
// 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' );
// 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 }
add_action( 'admin_init', 'ch3te_admin_init' );
function ch3te_admin_init() {
add_action( 'admin_post_save_ch3te_options',
'process_ch3te_options' );
// 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] );
}
}
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'] .
[twitterfeed user_name="WordPress" option_id="1"]
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.
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.