How to customise the output of the WP image gallery shortcode from a plugin?

We’re building a plugin that displays posts, and we also want to display the image gallery when it is used in a post. However, we need to limit the number of photos displayed? Is that possible?

Related posts

Leave a Reply

2 comments

  1. There’s two ways you can go about this, but both involve creating a function that does pretty much the same as the existing gallery shortcode function…

    You can either..

    1. Hook onto post_gallery and manipulate the incoming data(you can use the gallery shortcode function as a base for the filter if necessary)
    2. Unregister the gallery shortcode and register a new gallery shortcode with modifications(again you can use the existing function as a base if necessary)

    I did something similar in this thread, and i’m only referring to it because i’m going to take the same approach for the example that follows.

    Example filter for the gallery shortcode

    add_filter( 'post_gallery', 'my_post_gallery', 10, 2 );
    function my_post_gallery( $output, $attr) {
        global $post, $wp_locale;
    
        static $instance = 0;
        $instance++;
    
        // We're trusting author input, so let's at least make sure it looks like a valid orderby statement
        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,
            'itemtag'    => 'dl',
            'icontag'    => 'dt',
            'captiontag' => 'dd',
            'columns'    => 3,
            'size'       => 'thumbnail',
            'include'    => '',
            'exclude'    => ''
        ), $attr));
    
        $id = intval($id);
        if ( 'RAND' == $order )
            $orderby = 'none';
    
        if ( !empty($include) ) {
            $include = preg_replace( '/[^0-9,]+/', '', $include );
            $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
    
            $attachments = array();
            foreach ( $_attachments as $key => $val ) {
                $attachments[$val->ID] = $_attachments[$key];
            }
        } elseif ( !empty($exclude) ) {
            $exclude = preg_replace( '/[^0-9,]+/', '', $exclude );
            $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
        } else {
            $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) );
        }
    
        if ( empty($attachments) )
            return '';
    
        if ( is_feed() ) {
            $output = "n";
            foreach ( $attachments as $att_id => $attachment )
                $output .= wp_get_attachment_link($att_id, $size, true) . "n";
            return $output;
        }
    
        $itemtag = tag_escape($itemtag);
        $captiontag = tag_escape($captiontag);
        $columns = intval($columns);
        $itemwidth = $columns > 0 ? floor(100/$columns) : 100;
        $float = is_rtl() ? 'right' : 'left';
    
        $selector = "gallery-{$instance}";
    
        $output = apply_filters('gallery_style', "
            <style type='text/css'>
                #{$selector} {
                    margin: auto;
                }
                #{$selector} .gallery-item {
                    float: {$float};
                    margin-top: 10px;
                    text-align: center;
                    width: {$itemwidth}%;           }
                #{$selector} img {
                    border: 2px solid #cfcfcf;
                }
                #{$selector} .gallery-caption {
                    margin-left: 0;
                }
            </style>
            <!-- see gallery_shortcode() in wp-includes/media.php -->
            <div id='$selector' class='gallery galleryid-{$id}'>");
    
        $i = 0;
        foreach ( $attachments as $id => $attachment ) {
            $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);
    
            $output .= "<{$itemtag} class='gallery-item'>";
            $output .= "
                <{$icontag} class='gallery-icon'>
                    $link
                </{$icontag}>";
            if ( $captiontag && trim($attachment->post_excerpt) ) {
                $output .= "
                    <{$captiontag} class='gallery-caption'>
                    " . wptexturize($attachment->post_excerpt) . "
                    </{$captiontag}>";
            }
            $output .= "</{$itemtag}>";
            if ( $columns > 0 && ++$i % $columns == 0 )
                $output .= '<br style="clear: both" />';
        }
    
        $output .= "
                <br style='clear: both;' />
            </div>n";
    
        return $output;
    }
    

    Modify that function to impose whatever restrictions you like(it’s just a base)..

    You can find the hook i’m using in wp-includes/media.php inside the gallery shortcode callback function(see line 763).

    http://core.trac.wordpress.org/browser/tags/3.0.1/wp-includes/media.php#L745

    Hope that helps.. 🙂

  2. You can specify the number of images per gallery. This can be configured via the gallery tab in the media thickbox in the post editor. After you have already inserted the gallery, I think you can edit that by editing the gallery in the visual editor.