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 want to create a custom page that will display let's say 20 latest galleries / page - but only the first image from the gallery, not all of them. something like this: http://www.autoblog.it/gallerie/

I've done this:

<?php
$args = array(
'post_type' => 'attachment',
'posts_per_page' => 10,
'post_parent' => $postid,
'numberposts' => 1,
'paged' => $paged,
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
    echo the_attachment_link($attachment->ID, false, false, true )
    echo get_the_title();   }
}?>

it works but what it does is to display latest 10 images, not latest 10 galleries, so first image from each gallery.

Please help

Thank you

share|improve this question
add comment

2 Answers 2

Hi and thank you for the code...

I also made a shorter code that acually works ,,

here it is:

<?php
wp_reset_query();
global $wpdb;
$posts = $wpdb->get_results
("
 SELECT *
 FROM $wpdb->posts 
 WHERE
   post_status = 'publish'
   AND
    ID IN (
SELECT DISTINCT post_parent
FROM $wpdb->posts
WHERE
  post_parent > 0
AND
  post_type = 'attachment'
AND
  post_mime_type IN ('image/jpeg', 'image/png')
  )
   ORDER BY post_date DESC LIMIT 0, 10
 ");

  foreach($posts as $post) :
  setup_postdata($post);
 ?>
<div>

 </span>
 <div class="slider-image">
   <?php
   $images = get_children(array(
  'post_parent' => get_the_id(),
  'post_type' => 'attachment',
  'post_mime_type' => 'image',
  'orderby' => 'ID',
  'order' => 'ASC'
));
$ids = array_keys($images);
?>

<div style="height:180px; width:150px; border-bottom:solid 1px #f17d0b; float:left; margin-right:5px; margin-left:5px; margin-top:20px; overflow:hidden;" ><?php 
echo the_attachment_link($ids[0],false, false, true);

  ?><div style=" font-size:11px; color:#666; font-family:Arial, Helvetica, sans-serif;">             <?php echo get_the_title();    ?> </div></div>
 </div>
 </div>
 <?php
  endforeach;
 wp_reset_query();
 ?>

This actually work perfect. The only question is now how can i do pagination ???

Thank you very much.

share|improve this answer
    
This will list the latest attachments, not the latest galleries. A gallery is a part of a post, not an attachment. –  toscho Jan 2 '13 at 16:37
add comment

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" />
            [title] => 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" />
            [title] => 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="%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 */
}
share|improve this answer
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.