Meta boxes are one of the main ways in which I extend WordPress. Meta boxes allow you to add additional pieces of information associated with content items in WordPress.  For example, if you create a “countries” post type then you may want to associate a flag image with that country. A “flag” meta box would allow you store a flag image associated with each country.

I was working on a site yesterday that has a LOT of additional bits of information and meta boxes. For the users there is an order in which it makes sense to fill out all the additional fields. A bit like when writing a post, you would probably enter the title first and then the content and then assign categories. It was like that but with a whole bunch of things to fill in.

Unfortunately WordPress gives you very limited options for ordering meta boxes. You can order the fields inside meta boxes, and there is a “priority” that you can set on meta boxes to be high, default or low, but other than that you can’t organise meta boxes for your users to make their content-creation workflow easier.

However, individual users CAN drag and drop meta boxes around to re-order them, and they can make them visible/invisible.  Those orderings and visibility settings are stored in WordPress for each user. So I wondered if I could tap into that function and, if the user had not moved the boxes around, specify a default ordering.

I couldn’t find a simple filter that would let me intercept the ordering, but I did find that these values are stored in the wp_usermeta table. With a little help from the source code of the Global Meta Box Order plugin, I worked out that I could filter the options at a higher level to provide defaults.

There were a few gotcha’s along the way, and I had to reverse engineer the settings to make it work, but the code below works and provides default meta box order and hiding for users.

To use it you’ll need to add this code to your own plugin or to your theme’s functions.php, and work out, either using your browser’s developer tools or by configuring a custom order and then examining the usermeta in the database, what the new values should be.

This code only sets defaults for users who’ve not customised the order or visibility of meta boxes. Once a user customises the order or visibility their personal settings are saved and override the defaults.

UPDATE: I’ve found that there is actually a “default_hidden_meta_boxes” filter in WordPress core. This could be used to simplify the code below. This is left as an exercise for the reader! 😉