I was wondering : You are an administrator : when you re-order the layout of your meta-box, in a page, or in a post, this layout is saved with your user profil : for example you drag the category box before the publish box...

Is it possible to save this layout for other users (editors, authors..) ?

Is it possible to organize your layout for every kind of users, without logging with their account ?

Thanks for you help !

  • Was any of this answer useful, did they solve your issue. If so, choose the answer that helped you and accept that answer by clicking on the checkmark next to it. Thank you Commented Oct 23, 2014 at 18:49

4 Answers 4


This is a rough outline but something like this should work:

  1. Assume there is a some "master" user with a known user ID-- your administrator or a user created for this purpose.
  2. When meta boxes are displayed, user settings are checked to see if boxes have been moved around.
  3. You can interrupt that check with a filter on get_user_option_{$option}.

Put that together:

function force_user_option_wpse_124330($option) {
  return get_user_option('meta-box-order_post', 1); // 1 is the known user ID

I have serious misgivings about doing this at all. It could well cause confusion for your users. Even if that sketch of filter works, or you can make it work, I'd consider disabling the metabox dragging for any but the "master" user.

You will have to do something very similar for other pages with meta boxes that you want to hijack.


You could setup a different default layout by hooking into do_meta_boxes, take a look here:

Or you could use the global variable $wp_meta_boxes to do so:

Although the last two links are about dashboard widgets, there is little to none difference in how it is done for meta boxes on edit screens. Doing it with either method would be of course setting this up programmatically. You'd still have to disable the dragging and dropping I guess.


You can use the sorting behavior of ordering the metaboxes.

add_meta_box( $id, $title, $callback, $post_type, $context, $priority, $callback_args );

There are priorities ($priority) to display. My Idea is to give all of them same priority but keep their id's in sorted manner.

For example: If I want *c_meta_box* to be displayed before *b_meta_box* then i will register my meta boxes something like this.

add_meta_box('a_c_meta_box','C META BOX','c_meta_box_cb','post','normal','default');
add_meta_box('b_b_meta_box','B META BOX','b_meta_box_cb','post','normal','default');

Notice: How i have changed the id's of the boxes and added a_ and b_ to sort them. You can add numbers too. Giving all of them same $priority but sorted id's.

I know this is not the perfect solution but it works in this scenario.

For trouble shooting you can use this code to see look at the global $wp_meta_boxes like this:

global $wp_meta_boxes;
    echo "<pre>";
    echo "</pre>";

Further References: Widget API Codex

NOTE: After making changes on existing metaboxes hit Publish Button once to save the meta box's changed id's.


I agree that this is sort of bad practice as you're taking control out of users' hands and may confuse them, but I also understand that many users don't use this feature and/or are hopelessly bad with technology and end up screwing up the interface for themselves (for instance by collapsing meta boxes... different usermeta option for that but identical idea). We also know that hardcoding this stuff is bad practice but sometimes you really just need to get that shit done:

add_filter('get_user_option_meta-box-order_post', 'override_post_meta_box_order');

function override_post_meta_box_order($order) {
    $order['normal'] = "comma,separated,list,of,meta,boxes";
    $order['side'] = "you,get,the,idea";

    return $order;

You can find out what values to use here by peeking into your database or error_log(print_r($order,true)) or whatever.

A MUCH better way would be to get these values from another account, like your admin account, which you can then use to control and modify the meta box order. @s_ha_dum's answer goes for exactly this except that you get an infinite loop in it, as every call to get_user_option() goes through your filter, which in turn calls get_user_option(), etc... You need to have a base case, which checks if the requested user is 1 then actually return the user option. You can't simply check get_current_user_id() though because that will still return the current user viewing the page, even if you're calling get_user_option('meta-box-order_post', 1). I'm sure there's a way but briefly looking I couldn't figure out how to avoid this infinite loop.

Actually one way around it would be to directly query $wpdb for this value instead of using the WordPress function get_user_option().

EDIT: With the bug fixed, @s_ha_dum's answer is better, as it doesn't hard-code the order but lets a designated user control it: https://wordpress.stackexchange.com/a/124337/41534

  • Well, I did say it was untested. :) I believe it should work better now.
    – s_ha_dum
    Commented Feb 19, 2014 at 4:56
  • Aha I forgot about remove_filter()! Clever.
    – tobek
    Commented Feb 19, 2014 at 19:24
  • Thanks for catching that. It bugs me when my stuff doesn't work :)
    – s_ha_dum
    Commented Feb 19, 2014 at 19:26
  • No problem. I'm using that code now in production by the way, and it works like a charm.
    – tobek
    Commented Feb 19, 2014 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.