How To get a WordPress Widget ID for Multiple Instances

Supporting Multiple Widget Instances

Just recently I was developing a WordPress widget, and as I began coding of all my use cases I realized that I needed to be able to support multiple widget instances.  Supporting multiple widget instances is not a big deal, unless you plugin depends on knowing the widget id from the front-end.  By this I mean after your page has loaded, you need to perform client-side scripting that depends on knowing the id of each widget instance.

Where is the Widget’s Instance ID stored?

/** @see WP_Widget::widget */
function widget($args, $instance) {
    echo $this->id;
}

Continue reading “How To get a WordPress Widget ID for Multiple Instances”

Include Builtin scripts from WordPress using wp_enqueue_script()

Since we already showed you how to Include Javascript and CSS files through your WordPress Plugin, this post will be about how to include builtin scripts from WordPress. Why would we use these pre-registered scripts?

Two Reasons Why to use Builtin scripts from WordPress

There are two main reasons why using the pre-registered scripts is beneficial. First, this method will help to prevent jQuery conflicts. Second, it is a lot easier to use dependencies. Here is a list of all default scripts included and registered by WordPress. First lets look at an example to help prevent jQuery conflicts: if your plugin uses jQuery 1.9.2 and WordPress uses jQuery 1.11 then some features, like the drag and drop, might not work. So instead of doing this: Continue reading “Include Builtin scripts from WordPress using wp_enqueue_script()”

How to Change the Title of your First Submenu Page

There is a little thing you should know about WordPress’s add_submenu_page() function.  After creating your menu page using the add_menu_page(), you decide you would like a submenu page as well. So you use the add_menu_page() and add_submenu_page() functions, as below.

add_menu_page(
     __('My Plugin', 'text-domain'),
     __('My Plugin', 'text-domain'),
     'manage_options',
     'plugin-menu-page',
     'plugin_menu_page_callback'
);

add_submenu_page(
     'plugin-menu-page',
     __('Settings', 'text-domain'),
     __('Settings', 'text-domain'),
     'manage_options',
     'plugin-submenu-page',
     'plugin_submenu_page_callback'
);

As you look at your screen, you notice that the menu page and first submenu page have the same title. Why is this?

Menu_Page_Same_Title

Basically, when you use the add_menu_page() function to create a custom menu page and then use the add_submenu_page() function, WordPress casts the first submenu page to the top menu page. So, in order to get rid of this, just cast your first submenu page to the top menu. I know this sounds confusing at first, but look at the code below to see what I mean.

add_menu_page(
     __('My Plugin', 'text-domain'),
     __('My Plugin', 'text-domain'),
     'manage_options',
     'plugin-menu-page',
     'plugin_menu_page_callback'
);

add_submenu_page(
     'plugin-menu-page',
     __('General', 'text-domain'),
     __('General', 'text-domain'),
     'manage_options',
     'plugin-menu-page',
     'plugin_menu_page_callback'
);

add_submenu_page(
     'plugin-menu-page',
     __('Settings', 'text-domain'),
     __('Settings', 'text-domain'),
     'manage_options',
     'plugin-submenu-page',
     'plugin_submenu_page_callback'
);

As you can see, there are three function calls instead of the two used before. The first one is used to create the top menu. The second one, or the first add_submenu_page() function call, tells WordPress that the first submenu page will be a duplicate of the menu page but with a different title in the menu bar (i.e. “General”). The reason why the titles are different while the content remains the same, is because the menu slug (i.e. “plugin-menu-page”) and the callback function (i.e. “plugin_menu_page_callback”) in the first add_submenu_page() function call are the same as the add_menu_page() function call. Finally, the third function is technically the first real sub menu page that has its own content.

By following these steps, your plugins menu page will end up looking like the image below.

Menu_Page_Different_Title

Script Localization with JQuery in WordPress

Today, most plugin developers use JQuery to perform client-side tasks.  This adds a lot of functionality to your WordPress plugin, but what if you want to pass server-side data to these client-side files?

After your JQuery files have been included to a page, then you can use the wp_localize_script() function to pass your server-side data to these files.  All data is passed as a string, but you can convert it to a number if needed.  If you don’t know how to include files to a WordPress page, then check out this post, Include Javascript and CSS files through your WordPress Plugin.

<?php
     wp_enqueue_script( 'some_handle' );
     $passed_data = array( ’name' =>  ‘Kyle Benk' , ‘job_status' => ‘Wordpress Developer' );
     wp_localize_script( 'some_handle', ‘passed_data', $passed_data );
?>

You can then use this data in your JQuery script file like so:

$(document).ready(function(){
     console.log(“Name: “ + passed_data.name + “ Job Status: “ + passed_data.job_status);
});

How else can you use script localization with JQuery to your advantage? Here is an example of passing a translated string:

<?php
     wp_enqueue_script( 'some_handle' );
     $passed_data = array( ’string' => __( 'Some string to translate' ));
     wp_localize_script( 'some_handle', ’passed_data', $passed_data );
?>
$(document).ready(function(){
     console.log(“Translated String: “ + passed_data.string);
});

If your console outputs an undefined variable error for your passed data, then it means your wp_localize_script() function did not send the data properly. Most commonly this is because you are calling the wp_localize_script() function before the script has been included. So, make sure you enqueue the script before trying to localize it. To check for this error use this JQuery code:

if (typeof(passed_data) != "undefined" && passed_data !== null) {
     console.log(“Variable is set");
} else {
     console.log(“Undefined or null variable");
}

Include Javascript and CSS files through your WordPress Plugin

So, you are writing your plugin and realize that you need to include a Javascript or CSS file on a page. You think back to your HTML days and use:

<link rel="stylesheet" type="text/css" href="<?php echo $your_plugins_url; ?>css/your_css_file.css" />

or

<script type="text/javascript" src="<?php echo $your_plugins_url; ?>js/your_js_file.js"></script>

While technically it is possible to include files using HTML script and link tags on a standalone site, they are not best practice on a WordPress site. The main benefits of using WordPress’s core functions instead of generic HTML are:

  • Files are included to the generated page at the right time according to the script dependencies.
  • Files will only be included if it has not been already included and if all the dependencies have been registered.
  • Script localization is very easy, just call wp_localize_script() on your included files.  Check out Script Localization with JQuery in WordPress for more information.

Continue reading “Include Javascript and CSS files through your WordPress Plugin”

uninstall.php for WordPress Plugins

Every WordPress plugin you develop should always have an uninstall.php.  The purpose of this file is to erase all your plugin’s data when the user deletes it.  You don’t want to be the developer of a plugin that never deletes any of its data. So, start by adding an uninstall.php to your top directory and add this code to it.

<?php

/* if uninstall not called from WordPress exit */

if ( !defined( 'WP_UNINSTALL_PLUGIN' ) )
    exit ();

/* Delete all existence of this plugin */

global $wpdb;

/*
Drop Table if you created one

$table_name = 'your_table_name';

$wpdb->query('DROP TABLE `' . $table_name . '`');
*/

$blog_option_name = 'your_blog_option_name';
$site_option_name = 'your_site_option_name';
$post_meta_data_name = 'your_post_meta_data_name';
$user_meta_data_name = 'your_user_meta_data_name';

if ( !is_multisite() ) {

    /* Delete blog option */

    delete_option($blog_option_name);

    /* Delete post meta data */

    $posts = get_posts(array('posts_per_page' => -1));

    foreach ($posts as $post) {
        $post_meta = get_post_meta($post->ID);
        delete_post_meta($post->ID, $post_meta_data_name);
    }

    /* Delete user meta data */

    $users = get_users();

    foreach ($users as $user) {
        delete_user_meta($user->ID, $user_meta_data_name);
    }
}

else {

    /* Delete site option */

    delete_site_option($site_option_name);

    /* Used to delete each option from each blog */

    $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );

    foreach ( $blog_ids as $blog_id ) {

        switch_to_blog( $blog_id );

        /* Delete blog option */

        delete_option($blog_option_name);

        /* Delete post meta data */

        $posts = get_posts(array('posts_per_page' => -1));

        foreach ($posts as $post) {
            $post_meta = get_post_meta($post->ID);
            delete_post_meta($post->ID, $post_meta_data_name);
        }

        /* Delete user meta data */

        $users = get_users();

        foreach ($users as $user) {
            delete_user_meta($user->ID, $user_meta_data_name);
        }

    restore_current_blog();
    }
}
?>

Continue reading “uninstall.php for WordPress Plugins”