With the new Gallery editor in Wordpress I am able to set up my galleries and to drag the Thumbnails to re-arrange the image order. On the backend that seems to work fine. But I ran into an issue when I try to display the gallery on the front end using the 'orderby' => 'menu_order' attribute. The display was not using menu_order. When I looked in the database I noticed that the menu_order value for my attachments was still '0' for all gallery images. So it looks like reordering and saving Galleries in Wordpress 3.5 does not set the menu_order value in the database. Is this a bug? Has anyone else run across this? If so do you know of a fix?
4 Answers
it seems to me, after going through the source codes (both PHP and JS), that gallery and it's order is not saved to database at all. Gallery exists only in JS when you are creating that and even does not persist when you leave a post editing page.
Gallery gets saved only by inserting gallery shortcode with exact order of IDs declared in that shortcode - no extra info is saved to database, it is all about that shortcode.
If you want to loop attachements of a post by menu order, you have to assign to attachment post_type new support for page-attributes from plugin or your functions.php by inserting this code:
add_action('init', 'my_custom_init');
function my_custom_init() {
add_post_type_support( 'attachment', 'page-attributes' );
}
But, frankly, to assign menu order by enterin' each attachement edit page is quite pain. If you need to list post's attachement by menu order, WP 3.5's default Gallery is not for you and I suggest you to use some proven plugin (eg. NextGen Gallery) or write down a custom plugin which will enable you to either set menu order from Media Uploader or Library.
You are correct.
The menu_order is no longer used for media in the gallery. Unfortunately, it looks like the only "source" of the gallery order is the "ids" argument for the gallery shortcode which is embedded in the page/post content.
Not sure if this is by design or an oversight, but it could be by design since you can now include media in a gallery even if it is not "attached" to the page/post. In any case, below is the method I use to grab the ids and get the attachments based on the order specified in the shortcode.
The key is that the "orderby" param on the call to get_posts must be "post__in" this tells it to order by the post id order specified in the "include" param. See below.
// helper function to return first regex match
function get_match( $regex, $content ) {
preg_match($regex, $content, $matches);
return $matches[1];
}
// Extract the shortcode arguments from the $page or $post
$shortcode_args = shortcode_parse_atts(get_match('/\[gallery\s(.*)\]/isU', $post->post_content));
// get the ids specified in the shortcode call
$ids = $shortcode_args["ids"];
// get the attachments specified in the "ids" shortcode argument
$attachments = get_posts(
array(
'include' => $ids,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'order' => 'menu_order ID',
'orderby' => 'post__in', //required to order results based on order specified the "include" param
)
);
This isn't ideal and it would be nice if WP core would store this ordering in the database somewhere, but it works until we have a cleaner way.
Hope that helps!
Just a follow up as this came up for me again on another recent project. I used the solution posted here by user (vickybiswas):
http://wordpress.org/support/topic/35-rc1-menu_order-not-saved-to-the-database-for-attached-images
What's nice about this is that it will add the menu order to the items in the database. Seems to work for me without any issues so far.
Here's the code he provided:
function pmc_gallery_menu_order_fix($id) {
$regex_pattern = get_shortcode_regex();
preg_match ('/'.$regex_pattern.'/s', stripslashes($_POST['content']), $regex_matches);
if ($regex_matches[2] == 'gallery') :
$attribureStr = str_replace (" ", "&", trim ($regex_matches[3]));
$attribureStr = str_replace ('"', '', $attribureStr);
$attributes = wp_parse_args ($attribureStr);
endif;
$ids = explode(',', $attributes[ids]);
$images = get_posts( array(
'post_parent' => $post->ID,
'numberposts' => '-1',
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'orderby' => 'menu_order ID',
'order' => 'ASC'
) );
if ( empty($images) ) {
// no attachments here
} else {
foreach ( $images as $attachment_id => $attachment ) {
if (in_array($attachment->ID, $ids)) {
$update_post = array();
$update_post['ID'] = $attachment->ID;
$update_post['menu_order'] = array_search($attachment->ID, $ids);
wp_update_post( $update_post );
};
}
}
}
add_action('pre_post_update', 'pmc_gallery_menu_order_fix');
-
to avoid loops as of wordpress 4, please apply this modification: wordpress.stackexchange.com/a/162418/27933 Commented Feb 1, 2016 at 15:57
I had a similar issue, it appears the menu order isn't being set until you make a change by dragging an image to a new location, then it is saved asynchronously for all images in the set.
The menu order also seems to be limited only to the images attached to a particular post, although honestly I haven't played with the others as much.
Hope it helps.