Code Styling Project

It’s not a bug, it’s always a feature.
  • Deutsch
  • English
  • rss
  • Home
  • Blog
  • Imprint
  • Development
  • Manuals
  • Bugfixing

How to use Wordpress Metaboxes at own plugins

codestyling | 22. February 2009 | 02:38

Starting with WordPress Version 2.7 a new kind of metabox handling has been occured at Backend. You are now able to drag/drop or hide this Boxes. This makes daily work easier.

But there is currently insufficient documentation available, how this metaboxes can be used at your own plugin pages. I try here to explain the needed functions and have written a demo-plugin for download based on this articles information. Feel free to inspect it after reading the article, it may help you understand the concept.

Requirements

At the following article i will explicitely write about WordPress version 2.7 and higher. Older versions of WordPress are unsuitable for this because they lack of available functions. Some have been first introduced with 2.7 so i didn’t spend the time creating this backward compatible even it would be possible with a lot of costs.
I also skipped the gettext functionality for this demo because the plugin is a how to example and showcase. It’s much easier to understand, if it only contains the nessessary metabox stuff.

Function Description

As first step into this topic i will briefly show the available WordPress functions, here they are:

PHP
1
2
3
4
5
function add_meta_box($id, $title, $callback, $page, 
                      $context = 'advanced', $priority = 'default')
 
function do_meta_boxes($page, $context, $object)
 
timing: 0.035s

Function: add_meta_box

Using the function add_meta_box(…) you will register a new metabox at WordPress can be used by any page that matches with the given parameters.
The parameter $id is the unique identification for this registered metabox.
With the $title parameter you specifiy, what should be shown at the header of metabox. It is recommended that you use gettext based text here to permit a translation of your box title with language files.
The value $callback expects a callback function. It will be called by WordPress whever the content of this box has to be shown and should directly output the markup needed.
With the parameter $page you define the page, where this metabox is intended to be appearing. This implies also that your metabox can be shown at other plugin or core pages, if you know the exact parameter therefor.
The value $context will be used to define the context in which the box is intended to be appearing. In most cases this will be used to separate between content boxes and sidebar boxes.
Using $priority gives you the limited control in what order the boxes at the same context will be shown. Available values are: ‘high’, ‘core’, ‘default’, ‘low’.

Function: do_meta_boxes

If you call the function do_meta_boxes(…) the WordPress core generates and outputs all parameter matching metaboxes have been prior registered.
The value $object if free for use and intendend for programmers to handover additional informations into the metabox callbacks they may need to generate their content.

Metabox - content generation callback function

PHP
1
2
3
4
5
6
7
8
9
10
11
<?php function on_contentbox_1_content($data) {
	sort($data);
	?>
		<p>
			The given parameter at <b>sorted</b> order are: 
			<em><?php echo implode(' | ', $data); ?></em>
		</p>
	<?php
}
?>
 
timing: 0.034s

At this example you will find the parameter $object as Array of strings ($data parameter) passed over to be used inside content generation. You can freely pass any kind ob object into the callbacks, it’s mostly the choise of programmer.
If you think about the admin center page “Write Post” the passed object is there the post object itself ($post).

Metabox Registration - importance of when to execute

You can register our own metabox at 2 different points in time:

  1. WordPress tells you, that it is currently loading your plugins page
  2. during the output of your own plugin page

This difference of point in time determines if this box can be hidden using the Screen Options menu or not. Boxes that have been registered during load indication call of this plugin page can be hidden using the checkboxes. If you register your metabox during output of your plugin page content but prior to your call to do_meta_boxes(…), you can’t hide this box at this page it is always visible and no checkbox appears therefor.
You don’t have to deal with the mechanism how to get the checkboxes for hiding in place, the WordPress core does this automatical for you and provides the boxes at tab Screen Options without any further programming.

Javascript is nessessary to get show/hide and drag/drop

If you have implemented all your stuff until this point you may wonder, why the boxes can’t be dragged , why WordPress not remembers which have been switched off (hidden) and why it ignores the collapsed state. This is related to some Javascript Magic we have to introduce as next.

PHP
1
2
3
4
wp_enqueue_script('common');
wp_enqueue_script('wp-lists');
wp_enqueue_script('postbox');
 
timing: 0.034s

This named scripts have to be used inside your plugin page to get the effects and capabilities working. But the scripts do nothing, if they haven’t been initialized. This mostly will be done by inline javascript code like this:

Javascript
1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
	//<![CDATA[
	jQuery(document).ready( function($) {
		// close postboxes that should be closed
		$('.if-js-closed').removeClass('if-js-closed').addClass('closed');
		// postboxes setup
		postboxes.add_postbox_toggles('<?php echo $this->pagehook; ?>');
	});
	//]]>
</script>
 
timing: 0.005s

Example Screenshots of Demo-Plugin

Pictures are better than text. I have created 2 screenshots to illustrate what you can expect from this demo plugin, one as overview and an other with expanded Screen Options configuration:
 

Update: Modification for WordPress 2.8 new Metabox Model

The upcomming WordPress version 2.8 will change the handling of meta boxes while new column relations will be introduced. The following screenshot illustrates, what can be found now additionally at the settings tab slider:

That’s why it is necessary to handle this new behavoir. If this would not be changed, WordPress 2.8 versions won’t show any right sidebar for metabox content! It requires as first and new filter to be registered:

PHP
1
2
3
4
5
6
7
8
9
add_filter('screen_layout_columns', array(&$this, 'on_screen_layout_columns'), 10, 2);
...
//for WordPress 2.8 we have to tell, that we support 2 columns !
function on_screen_layout_columns($columns, $screen) {
	if ($screen == $this->pagehook) {
		$columns[$this->pagehook] = 2;
	}
	return $columns;
}
timing: 0.036s

Inside the filter method the array must be modified to stored the ammount of columns will be supported by this admin page (in this case 2 - content and right sidebar). But that’s not enough. While rendering (output) the metaboxes, we have to respect the current user choosen number of columns. Dependend on that number we must extend a HTML element with an additional class name:

PHP
1
2
3
global $screen_layout_columns;
...
<div id="poststuff" class="metabox-holder<?php echo 2 == $screen_layout_columns ? ' has-right-sidebar' : ''; ?>">
timing: 0.034s

After all this changes the demo plugin now works with WordPress 2.7 and also upcomming WordPress 2.8 version. The download file below has been adjusted and contains the modifications too. The source code also contains additional comments.

Download the example plugin

Based on the explanations and for your more deeply understanding i have build a short package with a full functional plugin that demonstrates all what has been written here. The code is under GPL and can be used or modified as you need it.
If you want to honor this work, please leave a remark at your source code or link to my page. It’s up to you doing so or not.

Here is the download of this demo plugin: howto-metabox-plugin.zip (1624 downloads)

Categories
English, WordPress (US)
Comments rss
Comments rss

« PHP function setlocale() … and numbers can be damaged WordPress 2.8 changes the metabox model for admin pages »

31 responses    Leave a comment

Ptah Dunbar

Ptah Dunbar

23.03.2009 | 23:21

Thank you for explaining this function. This saved me hours of reverse engineering WP to figure out how it all works. You are officially, awesome.

reply »

edebiyat

edebiyat

16.04.2009 | 01:30

this post very good

reply »

AussieDosh

AussieDosh

29.04.2009 | 13:21

Your example plugin is a very useful resource! The way that you have implemented your class is a good example of how to write an easy to maintain plugin. I am writing some of my own plugins at the moment and I decided to refactor my code after seeing your plugin.

Great stuff!

reply »

Romain

Romain

16.06.2009 | 23:03

Thanks for this very cool article. It helps a lot to figure the use of metaboxes out :-)

But what is the constant for? Why doesn’t the plugin work if it is changed?

reply »

Romain

Romain

16.06.2009 | 23:38

Saw it. I didn’t see that it was used in the local plugin. I thought the core would handle it.

reply »

remote

remote

28.06.2009 | 13:37

thak you very, very much for this most useful demo!

reply »

Paul

Paul

30.06.2009 | 07:34

Absolute Genius!
Total generosity.

Thanks!!

reply »

spg

spg

24.07.2009 | 15:39

Thanks a million!

reply »

Ade

Ade

09.08.2009 | 13:28

Heiko,

Thanks for a great write-up and download - I’ve been searching for this kind of information everywhere. :-)

Just a couple of questions though…

1. I notice that if a user clicks 1 Column in the Screen Layout option in the meta tab, the “sidebar” disappears and can’t be reloaded, even ona browser refresh. Something isn’t right there.

2. Do you know how to hook in to the Contextual Help tab? This would be a great thing to be able to do for plugin admin pages.

Thanks again!

Ade.

reply »

Ade

Ade

10.08.2009 | 15:16

Hi Heiko,

Me again :-)

OK, I figured out question #1 in my earlier comment. I just avoided setting up 2 columns by changing the value of $column in the on_screen_layout_columns function.

So, thanks to your excellent article, I’m almost there. The only problem I now have is the action hook for saving options entered in one of the metaboxes. In this line:

PHP
1
add_action('admin_post_save_howto_metaboxes_general', 'on_save_changes');
timing: 0.036s

is admin_post_save_howto_metaboxes_general a valid hook? I don’t think it is, which is why my options aren’t saving.

Any assistance you can offer is much appreciated!

Also, your language management plugin looks very interesting and I shall be trying it out on several bilingual sites I look after.

Thanks!

Ade.

reply »

Tony Dew

Tony Dew

16.11.2009 | 19:28

Wow! This is absolutely perfect! Thank you very much.

reply »

Upekshapriya

Upekshapriya

28.11.2009 | 04:53

Very helpful tutorial. However it has the same issue that I have found when implementing this in my own plugin - if I drag a box to a new position it doesn’t stay there but springs back to its original position after I’ve pressed the save button. I am using 2.8.4.

Do you know of a way to keep the positions of the boxes after save?

reply »

mohsen

mohsen

02.12.2009 | 16:57

Thanks thanks thanks for million times. You really helped me a lot. thanks again

reply »

Marco Cimmino

Marco Cimmino

17.02.2010 | 00:14

Good article I wonder few things:
1. can be initialized that all boxes are closed by default and they do not remember their states?
2. can be switched off the possibility to move the boxes?
3. what are the hidden fields you added? Seems some are required, some not.

reply »

chris

chris

31.05.2010 | 07:18

Thanks so much for putting this up - excellent tutorial, the best I’ve found for metaboxes (and plugin layout actually!) One question - what if you don’t want *any* of the metaboxes to be able to be turned off? If you move all the add_meta_box calls from on_load_page to on_show_page then the sidebox metaboxes no longer show! What’s up with that?

Thanks : )

reply »

Burner

Burner

11.06.2010 | 02:27

Hello. I have two questions:
1. How can you toggle a meta-box by default? In your example, the meta-boxes are open. I want to close 2-3 meta-boxes by default.
2. How can you start with 1 column layout selected? I want to start with 1 layout column and let the user to choose the 2 layout column.
Thanks.

reply »

strip that fat

strip that fat

25.07.2010 | 23:57

I know this is an old post, but it seems to work with wordpress 3.0 I been searching for a while to figure out how to do this.. Thanks.

Is there any real changes or best practices for wp 3.0 ? Or is it all the same since 2.8 ?

reply »

Radhe

Radhe

30.07.2010 | 12:32

Absolute Genius
For the past 2 days I was trying to reverse engineer dashboard.php, and suddenly you came along and saved me.
This tutorial is awesome and demo plugin is pure generosity for the WP developer community.

You ROCK.

reply »

ผลบอล

ผลบอล

19.01.2011 | 05:41

what if you don’t want *any* of the metaboxes to be able to be turned off? If you move all the add_meta_box calls from on_load_page to on_show_page then the sidebox metaboxes no longer show! What’s up with that?

reply »

codestyling

codestyling

25.05.2011 | 08:32

There is no preoblem with it. I moved sidebar 2 to on_show_page and it will be excluded from disabling but still shown. If you move it after you did disable it, it will diappeare for sure. Please enable it and move it afterwards to the show method. If it doesnt help, than something else running at your blog damages the functionality.

reply »

ketan mujumdar

ketan mujumdar

15.02.2011 | 08:40

More information abt metabox

http://techwithketan.wordpress.com/2011/02/09/adding-metabox-in-post/

reply »

estetik burun

estetik burun

14.04.2011 | 08:46

Very useful tutorial for me.

reply »

Christopher Ross

Christopher Ross

19.05.2011 | 14:13

Wonderful Helen! Absolutely wonderful. I struggled to simplify this process for several of my own plugins, now thanks to you the new releases will have a great new process. I really appreciate this sample.

reply »

Devcorn

Devcorn

24.05.2011 | 18:09

excellent article,

but one thing which, I would like to correct.. you don’t need to initialize jquery and other scripts. not sure if it is changed after 2.8. the initialize code break the toggle feature. please let me know if I am missing something.

reply »

codestyling

codestyling

25.05.2011 | 08:21

The jquery initialization has to be done always, please look at the main core pages too. It owrk perfectly at my single and multisite installations upto WP 3.1.2 with no feature break.
May be you have got a theme or plugin loading it’s own jquery version not only for frontend but also at any backend pages which is the most common mistake theme writers (and also plugin writers) do at the moment!
Please check it with firebug.

reply »

Devcorn

Devcorn

14.08.2011 | 18:02

If you call only

wp_enqueue_script(’dashboard’);

there is no need to call other scripts and also you don’t require to initialize Jquery. The code will be more optimized with less calls.

Thanks
DevCorn

reply »

Ryan

Ryan

24.06.2011 | 18:57

These boxes are a right nightmare.

I’ve written the code from other plugins, blank page.

Just copied and pasted all your code into my own plugin, blank page.

I have error reporting on too so there are no errors, just a nothing. It’s taking hours, a whole day but I’ll this working if it takes me a week lol

Thanks for the help

reply »

Ryan

Ryan

24.06.2011 | 19:14

Does anyone have an example that does not use the entire script within the plugins main page?

Most plugins I find don’t do it this way, this would be suitable for the most simple of plugins. Problem with more advanced plugins is the code is split up into various files its not easy getting to grips with how each developer has applied this.

I can make it work simply by adding the example to my plugins main file but if I put the code into a separate page I find it impossible to get working. Nothing shows in the content area at all.

I will pay someone to get this working for me.

reply »

cupcake

cupcake

23.10.2011 | 19:25

Good article I wonder few things:
1. can be initialized that all boxes are closed by default and they do not remember their states?
2. can be switched off the possibility to move the boxes?
3. what are the hidden fields you added? Seems some are required, some not.

reply »

ken shoufer

ken shoufer

03.12.2011 | 17:52

Thanks for the tutorial. The sample code still works as of version 3.2.1.

reply »

khushbu

khushbu

26.12.2011 | 09:26

Hi

Thanks ,Such a nice plugin.

i can’t see sidebar after activate this.

plz help me…

reply »

You can use these tags : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Navigation

  • Common
  • jQuery at WordPress
  • WordPress (US)

Search

Newer Posts ...

  • Codestyling Localization and PoEdit are compatible now
  • Codestyling Localization supports now BuddyPress and bbPress
  • jQuery 1.3.2 causes problems at IE 8
  • “Page Columnist” - Posts and Pages at Column Layout
  • WordPress 2.8 changes the metabox model for admin pages

Older Posts ...

  • PHP function setlocale() … and numbers can be damaged
  • WordPress Localization - Features and future Development
  • WordPress Category Tree Chaos at “Write Posts”
  • WordPress 2.6.1 loads too many script.aculo.us components
  • WordPress 2.6 and the Text/Diff fatal errors
rss Comments rss valid xhtml 1.0 design by jide powered by Wordpress get firefox