Go back to home page of Unsolicited Advice from Tiffany B. Brown

WordPress: Adding custom galleries to your theme

WordPress has a gallery feature that allows you to include a set of images with your posts. The syntax is simple, using what's known as a shortcode. WordPress has an entire API devoted to shortcodes.

In WordPress 3.5, it's possible to add a gallery using the gallery short code, and a comma-separated list of image identifiers. For example:

[gallery ids="729,732,731,720"]

This short code is parsed by the gallery_shortcode function, found in wp-includes/functions.php. gallery_shortcode returns markup and some rogue CSS. When building a theme, however, you may want to force some constraints on the gallery. Or you may wish to change its markup to get rid of that CSS. All of these changes should be made in your theme's functions.php file, and you'll need to know PHP.

If you want to customize the function, first you'll need to remove the existing short code hook using remove_shortcode('gallery', 'gallery_shortcode'). Next, you'll need to add a new hook using add_shortcode('gallery', NEW_GALLERY_FUNCTION); Where NEW_GALLERY_FUNCTION is the name of your replacement function. Then you can copy the gallery_shortcode from wp-includes/functions.php, and make whatever adjustments you'd like. What follows is a quick-and-dirty example from a real-life project (emphasis on dirty) that is more or less a duplicate of gallery_shortcode.

remove_shortcode('gallery', 'gallery_shortcode');
add_shortcode('gallery', 'custom_gallery');

function custom_gallery($attr) {
    $post = get_post();

    static $instance = 0;
    $instance++;

    # hard-coding these values so that they can't be broken

    $attr['columns'] = 1;
    $attr['size'] = 'full';
    $attr['link'] = 'none';

    $attr['orderby'] = 'post__in';
    $attr['include'] = $attr['ids'];

    #Allow plugins/themes to override the default gallery template.
    $output = apply_filters('post_gallery', '', $attr);

    if ( $output != '' )
        return $output;

    # 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'    => 'div',
        'icontag'    => 'div',
        'captiontag' => 'p',
        'columns'    => 1,
        'size'       => 'thumbnail',
        'include'    => '',
        'exclude'    => ''
    ), $attr));

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

    if ( !empty($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) ) {
        $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 '';

    $gallery_style = $gallery_div = '';

    if ( apply_filters( 'use_default_gallery_style', true ) )
        $gallery_style = "<!-- see gallery_shortcode() in functions.php -->";

    $gallery_div = "<div id='homepage-gallery-wrap' class='gallery gallery-columns-1 gallery-size-full'>";

    $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );

    foreach ( $attachments as $id => $attachment ) {
        $link = wp_get_attachment_link($id, 'full', true, false);

        $output .= "<div class='homepage-gallery-item'>";
        $output .= "
            <div class='homepage-gallery-icon'>
                $link
            </div>";
        if ( $captiontag && trim($attachment->post_excerpt) ) {
            $output .= "
                <p class='wp-caption-text homepage-gallery-caption'>
                " . wptexturize($attachment->post_excerpt) . "
                </p>";
        }
        $output .= "</div>";
    }

    $output .= "</div>\n";

    return $output;
}

You could also add another type of gallery rather than override the existing function. To do that, simply use add_shortcode(NEW_SHORTCODE, NEW_GALLERY_FUNCTION);, where NEW_SHORTCODE is the short code you wish to use, say [full_screen_gallery] and NEW_GALLERY_FUNCTION is the name of your new function.