WordPress 3.8 introduced a new way to display posts in the former single-column layout using filters. A Filter is a function that processes data at certain points of the page lifecycle. As the name suggests, a filter may be employed to filter out and/or manipulate certain data before rendering it to the browser or saving data to the database. Using a combination of filters and action hooks, it is possible to not only set the number of columns, but also to arrange the order of meta boxes within a column. In today’s article, we’ll be building on what we learned in the Intro to WordPress Meta Boxes article to both force a single column layout as well as position the meta boxes within the column.
One Column Layout
Arranging meta boxes in a one column layout requires the use of two filters. They are screen_layout_columns and get_user_option_screen_layout_<post_type>. The former sets the number of columns in the layout for each post type so that $columns[post] = 2;
sets a 2 column layout for posts and $columns[post] = 1;
sets it to 1. The “get_user_option_screen_layout_<post_type>” does the same thing but in a different way. It specifies the post type in the filter name so that the function only has to return the number of columns.
function my_screen_layout_columns( $columns ) { $columns[<post_type>] = 1; return $columns; } function my_screen_layout() { return 1; } add_filter( 'screen_layout_columns', 'my_screen_layout_columns' ); add_filter( 'get_user_option_screen_layout_<post_type>', 'my_screen_layout' );
Putting the above into practice, here is the code to set the layout for a custom post type called “menu”. Notice that in the my_screen_layout_columns() function, that you must set the $columns array element before returning it:
function my_screen_layout_columns( $columns ) { $columns['menu'] = 1; return $columns; } function my_screen_layout_menu() { return 1; } add_filter( 'screen_layout_columns', 'my_screen_layout_columns' ); add_filter( 'get_user_option_screen_layout_menu', 'my_screen_layout_menu' );
Changing Meta Box Ordering
Once you’ve got all the Meta Boxes in one column, you may find that their ordering is not to your liking. A meta box’s position on the page can be changed by removing it and then including the $context and $priority arguments when re-adding it. The two arguments can seem like overkill, but they actually work well together to give you fine-grained control over meta-box positioning.
Using the $context and $priority Arguments
As described in the Intro to WordPress Meta Boxes article, the add_meta_box() function accepts four required arguments, and three optional ones.
add_meta_box( $id, $title, $callback, $post_type, [$context], [$priority], [$callback_args]);
Neither the $context or $priority need be supplied, but omitting them gives WordPress the final say on where to place the meta-box. Therefore, both are necessary for their precise positioning.
The $context argument defines where the meta box will be displayed on a general level. It may be one of three possible values: “side”, “normal”, or “advanced”. The latter is the default value. The “side” value will place the meta box in the right hand column of the screen where the “Publish” and “Featured Image” boxes are displayed in a two column layout. The “normal” and “advanced” values will both place the meta box in the main column somewhere below the main content textarea with “normal” meta-boxes receiving higher priority than “advanced” ones.
The $priority argument then determines where the meta box displays within the general (context) area of the page that it is being displayed. The $priority argument takes four values: “high”, “core”, “low”, and “default”. Here, “default” is the default value.
To help illustrate where the meta boxes will be displayed using the various $context or $priority argument combinations, the following table shows all 12 possible combinations. The “Position” column refers to where the meta box will be shown assuming that only the default meta boxes are being displayed and that all of the default meta boxes are selected to “Show on screen” in the “Screen Options” panel:
$context Value | $priority Value | Position | In Relation To |
---|---|---|---|
advanced | default | Below | Revisions |
high | Below | Revisions | |
low | Below | Revisions | |
core | Below | Revisions | |
normal | default | Below | Revisions |
high | Above | Excerpt | |
low | Below | Revisions | |
core | Below | Revisions | |
side | default | Below | Featured Image |
high | Above | Publish | |
low | Below | Featured Image | |
core | Below | Featured Image |
According to the above table, a meta box with $context set to “side” and $priority set to “high” will display higher than a meta box with $context set to “side” and $priority set to “low”. Moreover, if $context is set to “advanced”, the meta box will always display below the Revisions meta box. These arguments become important once you introduce other meta boxes into the page. Within a context, one meta box may be displayed higher or lower than another meta box depending on the $priority argument.
Note that other meta boxes may be competing for a similar position and, depending on a number of factors, it can be difficult to predict which meta box will get the desired position. For that reason, some experimentation may be required.
Tie Breaking
If two meta boxes have identical $context and $priority, the meta boxes will be arranged alphanumerically according to the $id argument, with “a” and “0” being highest and “z” and “8” being the lowest.
To recap:
- $priority values (highest to lowest): “high”, “core”, “default”, “low”
- $context values: “advanced”, “normal”, “side”
- “normal” is higher than “advanced”
- Alphanumeric sort of $id will play the deciding role when two meta boxes with identical $context and $priority values
Conclusion
Whether you decide to go with a plugin or write the code yourself, at least now you know that positioning meta boxes is something that anyone can do with a little trial and error. As long as you can determine the meta box’s ID, you can position it where ever you like.