Display latest 10 galleries

Getting the latest posts with a gallery is simple: search for posts with the string '[gallery'.

$posts = get_posts(
    array (
        's'           => '[gallery'
    )
);

Getting the first image from each gallery is harder, because you have to render the gallery shortcode. I would not use the default handler, it does much more than we need here. It would waste too much time.

Step by step …

The main function

Let’s start with a function to retrieve a list of latest gallery posts with two parameters: the number of posts and a formatting helper:

function t5_list_galleries( $num = 10, $formatter="t5_gallery_list_formatter" )
{
    $posts = get_posts(
        array (
            's'           => '[gallery',
            'numberposts' => (int) $num
        )
    );

    if ( ! $posts )
        return FALSE;

    $list = new T5_Gallery_Image_Extractor( $posts );

    $html = call_user_func( $formatter, $list->get_results() );
    return $html;
}

As you can see we need a class T5_Gallery_Image_Extractor to build the list and a formatting function to create the Markup. I haven’t put the formatter into the gallery extractor to stay flexible: You might use the function in a widget or in a shortcode with different formatters.

The class T5_Gallery_Image_Extractor

The class constructor expects a list of posts. It doesn’t care about how we got that list, so we can build is manually with a completely different main function.

Internally, it replaces the default shortcode handler for gallery with a simplified version to get just the first image from the first gallery in a post.

The public method get_results() returns an array like this:

Array
(
    [0] => Array
        (
            [url] => http://single.wp/blog/gallery-2/
            [img] => <img width="150" height="150" src="http://content.wp/singlewp/uploads/2013/01/git-bash-150x150.png" class="attachment-thumbnail" alt="git-bash" />
            Display latest 10 galleries => Gallery 2
        )

    [1] => Array
        (
            [url] => http://single.wp/blog/gallery-1/
            [img] => <img width="150" height="150" src="http://content.wp/singlewp/uploads/2013/01/hat-150x150.png" class="attachment-thumbnail" alt="hat" />
            Display latest 10 galleries => Gallery 1
        )
)

So we get the post URL, the image markup and the post title for each post with a gallery.

The code, sorry, no time for comments, maybelater. 🙂

class T5_Gallery_Image_Extractor
{
    protected $results             = array ();

    protected $current_post        = NULL;

    protected $old_gallery_handler = FALSE;

    public function __construct( $posts )
    {
        $this->replace_gallery_shortcode();

        foreach ( $posts as $post )
            $this->collect_first_image( $post );
    }

    public function get_results()
    {
        remove_shortcode( 'gallery' );

        if ( $this->old_gallery_handler )
            add_shortcode( 'gallery', $this->old_gallery_handler );

        return $this->results;
    }

    protected function collect_first_image( $post )
    {
        $this->current_post = $post;
        do_shortcode( $post->post_content );
        $this->current_post = NULL;
    }

    protected function replace_gallery_shortcode()
    {
        // replace the old gallery shortcode
        if ( isset( $GLOBALS['shortcode_tags']['gallery'] ) )
            $this->old_gallery_handler = $GLOBALS['shortcode_tags']['gallery'];

        remove_shortcode( 'gallery' );
        add_shortcode( 'gallery', array ( $this, 'gallery_shortcode' ) );
    }

    public function gallery_shortcode( $attr )
    {
        static $processed_posts = array ();

        $post = $this->current_post;

        if ( in_array( $post->ID, $processed_posts) )
            return; // no need to run through all galleries of a post.

        $processed_posts[] = $post->ID;

        if ( ! empty ( $attr['ids'] ) )
        {
            if ( empty ( $attr['orderby'] ) )
                $attr['orderby'] = 'post__in';

            $attr['include'] = $attr['ids'];
        }

        if ( isset ( $attr['orderby'] ) )
        {
            $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
            if ( ! $attr['orderby'] )
                unset( $attr['orderby'] );
        }


        extract(shortcode_atts(array(
            'order'      => 'ASC',
            'orderby'    => 'menu_order ID',
            'id'         => $post->ID,
            'include'    => '',
            'exclude'    => ''
        ), $attr));

        $id = intval($id);

        if ( 'RAND' == $order )
            $orderby = 'none';

        $att_args = array (
            'post_status'    => 'inherit',
            'post_type'      => 'attachment',
            'post_mime_type' => 'image',
            'order'          => $order,
            'orderby'        => $orderby,
            'numberposts'    => 1
        );

        if ( ! empty ( $include ) )
        {
            $att_args['include'] = $include;
            $attachments         = get_posts( $att_args );
        }
        else
        {
            $att_args['post_parent'] = $post->ID;

            if ( ! empty ( $exclude ) )
                $att_args['exclude'] = $exclude;

            $attachments = get_children( $att_args );
        }
        $this->results[] = array (
            'url'   => get_permalink( $post->ID ),
            'img'   => wp_get_attachment_image( current( $attachments )->ID ),
            'title' => $post_title = esc_attr( $post->post_title )
        );
    }
}

The formatter

Dead simple: just convert the array from above into a HTML list.

function t5_gallery_list_formatter( $list )
{
    $output="<ul class="t5-gallery-list">";

    foreach ( $list as $item )
        $output .= sprintf(
            '<li><a href="https://wordpress.stackexchange.com/questions/77882/%1$s" title="%2$s">%3$s</a></li>',
            $item['url'],
            $item['title'],
            $item['img']
        );

    return "$output</ul>";
}

Now we can use the main function wherever we need it:

print t5_list_galleries();

And the result is a nice list of the latest ten posts with a gallery, the first image from the first gallery is used as link text.

enter image description here

Visual formatting is left to the stylesheet:

.t5-gallery-list {
    /* here be dragon rules */
}