Block metabox – No expanding, no moving around

Deregistering the postbox script seemed a little bit drastic and as mentioned the “Edit” button for the permalink slug does not work as expected anymore.

I actually came up another method which uses filters from WordPress and the functionality of the jQuery UI sortable plugin allowing to cancel the sort when it is issued from specific element(s) through the cancel option.

Context

WordPress 3.4.2 uses jQuery UI 1.8.20. Here’s the initialization code that is used in postbox.js (I’ve stripped down the not relevant options):

a(".meta-box-sortables").sortable({
    ...
    connectWith: ".meta-box-sortables",
    items: ".postbox",
    handle: ".hndle",
    ...
});

So the plugin creates a sortable list for elements .postbox. The sort is issued with the child element .hndle.

Solution

  1. Adding classes to the .postbox elements

    WordPress provides a filter hook to customize the css classes added to the postboxes:

    postbox_classes_{page}_{id}
    

    {page} is the page the metabox is displayed on
    {id}is the metabox id

    So if I have a metabox with id “_movie_details_metabox” applied for a custom post type called “movie_type”, you can do this:

    function metabox_not_sortable($classes) {
        $classes[] = 'not-sortable';
        return $classes;
    }
    add_filter('postbox_classes_movie_type__movie_details_metabox', 'metabox_not_sortable');
    

  2. Alter jquery ui sortable instance

    Then you can insert a footer script in the admin area to alter the sortable instance to cancel the sort event if it is issued through the .hndle element from a postbox with the added css class not-sortable:

    <?php
    add_action('admin_print_footer_scripts','my_admin_print_footer_scripts',99);
    function my_admin_print_footer_scripts()
    {
        ?><script type="text/javascript">/* <![CDATA[ */
            jQuery(function($)
            {
                $(".meta-box-sortables")
                    // define the cancel option of sortable to ignore sortable element
                    // for boxes with '.not-sortable' css class
                    .sortable('option', 'cancel', '.not-sortable .hndle, :input, button')
                    // and then refresh the instance
                    .sortable('refresh');
            });
        /* ]]> */</script><?php
    }

Postboxes with the css class .not-sortable cannot be sorted anymore, the other ones still can.

Leave a Comment