Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I using the built-in gallery in wordpress to store and sort images inside a custom post type. In the theme I was using:

$attachments = get_posts(
                 array('post_type' => 'attachment',
                       'post_parent' => $post->ID,
                       'orderby' => 'menu_order'
                 )
               );

The above code returns the gallery images correctly, but in the wrong order. When I look at the content field for the post containing the gallery, it contains the gallery data:

[gallery ids="2,5,7,8"]

So, my guess is that the built-in gallery doesn't store the sorting in a separate field like menu_order instead it stores a sorted list of attachment ids in the content field of the parent post.

So my question is what would be the best way to get the gallery images sorted correctly from the theme?

I tried something like:

$matches = array();
if(preg_match('/ids="(.*)"/', $post->post_content, $matches)) {
    $ids = $matches[1];

    $query = "SELECT * FROM $wpdb->posts ".
             "WHERE post_type = 'attachment' &&
                    post_parent = $post->ID ".
             "ORDER BY FIELD(ID, $ids)";
    $attachments = $wpdb->get_results($query);
 }

This seems to work but is there a cleaner way of doing this.

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

You are correct.

The menu_order is no longer used for media in the gallery. Not sure if this is by design or an oversight. 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:

// 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
    )
);

Hope that helps!

share|improve this answer
    
+1, very nice and helpful answer. –  Krister Andersson Mar 5 '13 at 10:48
    
Glad that helped. If that answers your question, would you mind marking it as answer in addition to the +1? Thanks! –  anderly Mar 5 '13 at 15:33
    
Yes I will, but I want to try to code first=) –  Krister Andersson Mar 5 '13 at 20:17
    
This worked fine, but I had to add post_parent => $post->ID in the call to get_posts(), also I was using the post_types_order plugin and to get the order for gallery images correct I needed to exclude sorting for attachments by hacking the plugin. –  Krister Andersson Mar 6 '13 at 10:13
    
Cool...glad you got it working! –  anderly Mar 6 '13 at 23:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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