You’re doing it wrong #1

Welcome to a new series of mine, You’re doing it wrong. Now, You may’ve guessed what this series is going to be about.. WordPress “Programmers” doing things wrong.

Right now, I’m writing a new theme for a website, utilising a few plugins,  one of them is WP125.

 Notice: Trying to get property of non-object in G:\www\nrtt\wp\wp-includes\general-template.php on line 366

Yep, You’re doing it wrong. First glance it looks like its caused by WordPress, but after a lot of debugging, Here’s a stacktrace:

#0 G:\www\nrtt\wp\wp-includes\general-template.php(367) stackTrace(Array ( ) )
#1 G:\www\nrtt\wp\wp-includes\script-loader.php(410) get_bloginfo(Array ( [0] => text_direction ) )
#2 unknown(unknown) wp_default_styles(Array ( [0] => CONVERTED OBJECT OF CLASS WP_Styles ) )
#3 G:\www\nrtt\wp\wp-includes\plugin.php(414) call_user_func_array(Array ( [0] => wp_default_styles [1] => Array ( [0] => CONVERTED OBJECT OF CLASS WP_Styles ) ) )
#4 G:\www\nrtt\wp\wp-includes\class.wp-styles.php(31) do_action_ref_array(Array ( [0] => wp_default_styles [1] => Array ( [0] => CONVERTED OBJECT OF CLASS WP_Styles ) ) )
#5 G:\www\nrtt\wp\wp-includes\functions.wp-styles.php(72) CONVERTED OBJECT OF CLASS WP_Styles->__construct(Array ( ) )
#6 G:\www\nrtt\wp\wp-content\plugins\wp125\adminmenus.php(8) wp_enqueue_style(Array ( [0] => thickbox ) )
#7 G:\www\nrtt\wp\wp-content\plugins\wp125\wp125.php(75) require_once(Array ( [0] => G:\www\nrtt\wp\wp-content\plugins\wp125\adminmenus.php ) )
#8 G:\www\nrtt\wp\wp-settings.php(566) include_once(Array ( [0] => G:\www\nrtt\wp\wp-content\plugins\wp125\wp125.php ) )
#9 G:\www\nrtt\wp\wp-config.php(109) require_once(Array ( [0] => G:\www\nrtt\wp\wp-settings.php ) )
#10 G:\www\nrtt\wp\wp-load.php(30) require_once(Array ( [0] => G:\www\nrtt\wp\wp-config.php ) )
#11 G:\www\nrtt\wp\wp-admin\admin.php(20) require_once(Array ( [0] => G:\www\nrtt\wp\wp-load.php ) )
#12 G:\www\nrtt\wp\wp-admin\edit.php(10) require_once(Array ( [0] => G:\www\nrtt\wp\wp-admin\admin.php ) )

Do you notice whats happening here?  A seasoned WordPress developer should.. But many will not, As it’s a huge problem amongst some plugins..

The issue at hand here, Is that the WP125 plugin, is running code as soon as its included, In this case, its registering styles and scripts as soon as the plugin is included. NOT a good thing to do.

A plugin should NEVER run any code as soon as its included*, All code should be placed inside actions.

Eg, Instead of this:

if(is_admin()){
 wp_enqueue_script('jquery');
 wp_enqueue_script('thickbox');
 wp_enqueue_style('thickbox'); 
}

It should be:

add_action('admin_head', 'wp125_enqueue_styles');
function wp125_enqueue_styles() {
 wp_enqueue_script('jquery');
 wp_enqueue_script('thickbox');
 wp_enqueue_style('thickbox'); 
}

*1: Obviously, there are some cases where running code is considered ok, but it should be avoided. I’m ignoring calls to add_action/add_filter as running code here, as thats the way things should happen.

There  is one more thing which should be noted as well.. another thing a plugin should NEVER do, Is enqueue Scripts and Styles for EVERY administration page, Only load them on the pages which require the script. So lets take that last semi-better-than-original  sniplet and convert it to something which is how ALL plugins should be registering their scripts and styles:

So, Now I’m going to introduce you to one more function which many developers seem to miss, the action admin_print_scripts-<slug>

This action is actually pretty simple, On every pageload of WordPress Administration, many dynamic hooks are fired, in particular interest today, is the admin_print_scripts-<slug> hook. This fires when WordPress decides its time to start printing the <script> and <link rel=”stylesheet” /> items into the head of the document. This is where plugins should be hooking their addition of styles and scripts, As well as printing any extra <head> content to fit into the WordPress admin pages for their plugin.

Without going into it in depth, I’m just going to give a chunk of code, The only thing worth noting, is if you’re not sure of the slug of your page, Quite handy is, that the add_menu_*() functions will return it.. So, Finally, Here we go:

//Add the Admin Menus
add_action('admin_menu', 'wp125_add_admin_menu');
function wp125_add_admin_menu() {
 load_plugin_textdomain('wp125', PLUGINDIR.'/'.dirname(plugin_basename(__FILE__)).'/translations', dirname(plugin_basename(__FILE__)).'/translations');
 $pages = array();
 $pages[] = add_menu_page(__("125x125 Ads", 'wp125'), __("Ads", 'wp125'), MANAGEMENT_PERMISSION, __FILE__, "wp125_write_managemenu");
 $pages[] = add_submenu_page(__FILE__, __("Manage 125x125 Ads", 'wp125'), __("Manage", 'wp125'), MANAGEMENT_PERMISSION, __FILE__, "wp125_write_managemenu");
 $pages[] = add_submenu_page(__FILE__, __("Add/Edit 125x125 Ads", 'wp125'), __("Add/Edit", 'wp125'), MANAGEMENT_PERMISSION, 'wp125_addedit', "wp125_write_addeditmenu");
 $pages[] = add_submenu_page(__FILE__, __("125x125 Ad Settings", 'wp125'), __("Settings", 'wp125'), MANAGEMENT_PERMISSION, 'wp125_settings', "wp125_write_settingsmenu");

 foreach ( $pages as $my_page )
   add_action('admin_print_scripts-' . $my_page, 'wp125_register_scripts_styles', 9); //Add it a little earlier.

 //Include menus
 require_once(dirname(__FILE__).'/adminmenus.php');
}

function wp125_register_scripts_styles() {
 wp_enqueue_script('jquery');
 wp_enqueue_script('thickbox');
 wp_enqueue_style('thickbox');
}

The main benefit of behaving yourself? Much less chance of screwing up another admin page’s styling or JavaScript :)

Stay tuned for the next edition of this, Where once again, WP125 will feature, along side TDO Mini Forms

See Attachment for a .diff of the changes made to the plugin. NOTE: This is as of version 1.3.6

7 thoughts on “You’re doing it wrong #1”

  1. Please keep this series going. The level of professional coding needs to be raised in the WP community, and this may just be one of the most effective ways to do it.

    1. Unfortunately you’re probably right. I’ll keep this series going everytime i have to modify a plugin for my needs.. Hopefully that wont be too often, But i think we both know it’ll never stop..

  2. You hit the nail on the head with the issue of overincluding. I keep repeating it over and over but every day see plugins that include their crap all over the place.

    Keep this going indeed!

Comments are closed.