gallery_shortcode()WP 2.5.0

Function that replaces the shortcode [gallery] in the text of the post. This function is responsible for displaying WordPress galleries in the post.

Using hooks from this function, you can partially or completely change the output of the gallery. For example, by using the hook post_gallery, you can completely change how this function works to your own code, see example below.

Returns

String. HTML of the gallery.

Usage

gallery_shortcode( $attr );
$attr(array) (required)

Attributes based on which the HTML gallery will be built.

  • order
    The order of sorting the images, can be: ASC, DESC.
    Default: 'ASC'

  • orderby
    The field by which the images will be sorted. Can be the name of any column from the wp_posts table (where image data is stored). Here are the fields that can be used primarily: post_title, ID, post_author, post_date, post_name.
    Default: 'menu_order ID'

  • id
    The ID of the post to which the gallery belongs.

  • itemtag
    HTML tag for each image. Can be: dl or figure (for HTML5, when HTML5 support is enabled).
    Default: 'dl'

  • captiontag
    HTML tag for each image caption. Can be: dd or figcaption (HTML5).

  • columns
    The number of columns in the gallery.
    Default: 3

  • size
    The size of the image in the gallery.
    Default: 'thumbnail'

  • ids
    A list of attachment IDs (the images themselves), separated by commas (these IDs are usually specified in the shortcode).
    Default: ''

  • include
    IDs of images (attachments), separated by commas. For more details, see the include parameter in get_posts(). When this parameter is specified, the ids parameter is ignored.
    Default: ''

  • exclude
    IDs of images that should not be displayed. Will skip images even if they are specified in the gallery shortcode.
    Default: ''

  • link
    Where the image will link to. Can be: file, none.
    Default: '' (empty - link to the attachment page)

Examples

1

#1 Removing the frame from images

You can use the gallery_style filter to change the inserted styles. So you don't have to rewrite them all (although there's not much there). For example, let's remove the frame from images:

add_filter( 'gallery_style', function( $str ){

	return str_replace( 'border: 2px solid #cfcfcf;', '', $str );
} );
0

#2 Disable default css gallery styles

With the use_default_gallery_style hook, we can remove the added default gallery styles and style the gallery output in our own way, in the theme styles file. The code must be inserted into the theme file functions.php:

// turn off gallery styles
add_filter( 'use_default_gallery_style', '__return_false' );

And this is what removed styles look like:

<style type="text/css">
	#gallery-1 {
		margin: auto;
	}
	#gallery-1 .gallery-item {
		float: left;
		margin-top: 10px;
		text-align: center;
		width: 20%;
	}
	#gallery-1 img {
		border: 2px solid #cfcfcf;
	}
	#gallery-1 .gallery-caption {
		margin-left: 0;
	}
	/* see gallery_shortcode() in wp-includes/media.php */
</style>
0

#3 Replace the function gallery_shortcode() completely with your own

By using the post_gallery hook in a template file or in a plugin, we can completely replace gallery_shortcode() at the beginning:

/* 
 * Changing the gallery output via shortcode
 * See the gallery_shortcode function at http://wp-kama.ru/filecode/wp-includes/media.php
 * $output = apply_filters( 'post_gallery', '', $attr );
 */
add_filter('post_gallery', 'my_gallery_output', 10, 2);
function my_gallery_output( $output, $attr ){
	$ids_arr = explode(',', $attr['ids']);
	$ids_arr = array_map('trim', $ids_arr );

	$pictures = get_posts( array(
		'posts_per_page' => -1,
		'post__in'       => $ids_arr,
		'post_type'      => 'attachment',
		'orderby'        => 'post__in',
	) );

	if( ! $pictures ) return 'The query returned an empty result.'

	// Conclusion
	$out = '<dl class="gallery_photos">';

	// Display each picture in the gallery
	foreach( $pictures as $pic ){
		$src = $pic->guid;
		$t = esc_attr( $pic->post_title );
		$title = ( $t && false === strpos($src, $t)  ) ? $t : '';

		$caption = ( $pic->post_excerpt != '' ? $pic->post_excerpt : $title );

		$out .= '
		<dt>
			<a href="'. esc_url($src) .'"><img src="'. kama_thumb_src('w=185&h=120&src='. $src ) .'" alt="'. $title .'" /></a>'. 
			( $caption ? "<span class='caption'>$caption</span>" : '' ) .
		'</dt>';
	}

	$out .= '</dl>';

	return $out;
}

Changelog

Since 2.5.0 Introduced.
Since 2.8.0 Added the $attr parameter to set the shortcode output. New attributes included such as size, itemtag, icontag, captiontag, and columns. Changed markup from div tags to dl, dt and dd tags. Support more than one gallery on the same page.
Since 2.9.0 Added support for include and exclude to shortcode.
Since 3.5.0 Use get_post() instead of global $post. Handle mapping of ids to include and orderby.
Since 3.6.0 Added validation for tags used in gallery shortcode. Add orientation information to items.
Since 3.7.0 Introduced the link attribute.
Since 3.9.0 html5 gallery support, accepting 'itemtag', 'icontag', and 'captiontag' attributes.
Since 4.0.0 Removed use of extract().
Since 4.1.0 Added attribute to wp_get_attachment_link() output aria-describedby.
Since 4.2.0 Passed the shortcode instance ID to post_gallery post_playlist
Since 4.6.0 Standardized filter docs to match documentation standards for PHP.
Since 5.1.0 Code cleanup for WPCS 1.0.0 coding standards.
Since 5.3.0 Saved progress of intermediate image creation after upload.
Since 5.5.0 Ensured that galleries can be output as a list of links in feeds.
Since 5.6.0 Replaced order-style PHP type conversion functions with typecasts. Fix logic for an array of image dimensions.

gallery_shortcode() code WP 6.9.1

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

	static $instance = 0;
	++$instance;

	if ( ! empty( $attr['ids'] ) ) {
		// 'ids' is explicitly ordered, unless you specify otherwise.
		if ( empty( $attr['orderby'] ) ) {
			$attr['orderby'] = 'post__in';
		}
		$attr['include'] = $attr['ids'];
	}

	/**
	 * Filters the default gallery shortcode output.
	 *
	 * If the filtered output isn't empty, it will be used instead of generating
	 * the default gallery template.
	 *
	 * @since 2.5.0
	 * @since 4.2.0 The `$instance` parameter was added.
	 *
	 * @see gallery_shortcode()
	 *
	 * @param string $output   The gallery output. Default empty.
	 * @param array  $attr     Attributes of the gallery shortcode.
	 * @param int    $instance Unique numeric ID of this gallery shortcode instance.
	 */
	$output = apply_filters( 'post_gallery', '', $attr, $instance );

	if ( ! empty( $output ) ) {
		return $output;
	}

	$html5 = current_theme_supports( 'html5', 'gallery' );
	$atts  = shortcode_atts(
		array(
			'order'      => 'ASC',
			'orderby'    => 'menu_order ID',
			'id'         => $post ? $post->ID : 0,
			'itemtag'    => $html5 ? 'figure' : 'dl',
			'icontag'    => $html5 ? 'div' : 'dt',
			'captiontag' => $html5 ? 'figcaption' : 'dd',
			'columns'    => 3,
			'size'       => 'thumbnail',
			'include'    => '',
			'exclude'    => '',
			'link'       => '',
		),
		$attr,
		'gallery'
	);

	$id = (int) $atts['id'];

	if ( ! empty( $atts['include'] ) ) {
		$_attachments = get_posts(
			array(
				'include'        => $atts['include'],
				'post_status'    => 'inherit',
				'post_type'      => 'attachment',
				'post_mime_type' => 'image',
				'order'          => $atts['order'],
				'orderby'        => $atts['orderby'],
			)
		);

		$attachments = array();
		foreach ( $_attachments as $key => $val ) {
			$attachments[ $val->ID ] = $_attachments[ $key ];
		}
	} elseif ( ! empty( $atts['exclude'] ) ) {
		$post_parent_id = $id;
		$attachments    = get_children(
			array(
				'post_parent'    => $id,
				'exclude'        => $atts['exclude'],
				'post_status'    => 'inherit',
				'post_type'      => 'attachment',
				'post_mime_type' => 'image',
				'order'          => $atts['order'],
				'orderby'        => $atts['orderby'],
			)
		);
	} else {
		$post_parent_id = $id;
		$attachments    = get_children(
			array(
				'post_parent'    => $id,
				'post_status'    => 'inherit',
				'post_type'      => 'attachment',
				'post_mime_type' => 'image',
				'order'          => $atts['order'],
				'orderby'        => $atts['orderby'],
			)
		);
	}

	if ( ! empty( $post_parent_id ) ) {
		$post_parent = get_post( $post_parent_id );

		// Terminate the shortcode execution if the user cannot read the post or it is password-protected.
		if ( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID )
			|| post_password_required( $post_parent )
		) {
			return '';
		}
	}

	if ( empty( $attachments ) ) {
		return '';
	}

	if ( is_feed() ) {
		$output = "\n";
		foreach ( $attachments as $att_id => $attachment ) {
			if ( ! empty( $atts['link'] ) ) {
				if ( 'none' === $atts['link'] ) {
					$output .= wp_get_attachment_image( $att_id, $atts['size'], false, $attr );
				} else {
					$output .= wp_get_attachment_link( $att_id, $atts['size'], false );
				}
			} else {
				$output .= wp_get_attachment_link( $att_id, $atts['size'], true );
			}
			$output .= "\n";
		}
		return $output;
	}

	$itemtag    = tag_escape( $atts['itemtag'] );
	$captiontag = tag_escape( $atts['captiontag'] );
	$icontag    = tag_escape( $atts['icontag'] );
	$valid_tags = wp_kses_allowed_html( 'post' );
	if ( ! isset( $valid_tags[ $itemtag ] ) ) {
		$itemtag = 'dl';
	}
	if ( ! isset( $valid_tags[ $captiontag ] ) ) {
		$captiontag = 'dd';
	}
	if ( ! isset( $valid_tags[ $icontag ] ) ) {
		$icontag = 'dt';
	}

	$columns   = (int) $atts['columns'];
	$itemwidth = $columns > 0 ? floor( 100 / $columns ) : 100;
	$float     = is_rtl() ? 'right' : 'left';

	$selector = "gallery-{$instance}";

	$gallery_style = '';

	/**
	 * Filters whether to print default gallery styles.
	 *
	 * @since 3.1.0
	 *
	 * @param bool $print Whether to print default gallery styles.
	 *                    Defaults to false if the theme supports HTML5 galleries.
	 *                    Otherwise, defaults to true.
	 */
	if ( apply_filters( 'use_default_gallery_style', ! $html5 ) ) {
		$type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"';

		$gallery_style = "
		<style{$type_attr}>
			#{$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;
			}
			/* see gallery_shortcode() in wp-includes/media.php */
		</style>\n\t\t";
	}

	$size_class  = sanitize_html_class( is_array( $atts['size'] ) ? implode( 'x', $atts['size'] ) : $atts['size'] );
	$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";

	/**
	 * Filters the default gallery shortcode CSS styles.
	 *
	 * @since 2.5.0
	 *
	 * @param string $gallery_style Default CSS styles and opening HTML div container
	 *                              for the gallery shortcode output.
	 */
	$output = apply_filters( 'gallery_style', $gallery_style . $gallery_div );

	$i = 0;

	foreach ( $attachments as $id => $attachment ) {

		$attr = ( trim( $attachment->post_excerpt ) ) ? array( 'aria-describedby' => "$selector-$id" ) : '';

		if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) {
			$image_output = wp_get_attachment_link( $id, $atts['size'], false, false, false, $attr );
		} elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) {
			$image_output = wp_get_attachment_image( $id, $atts['size'], false, $attr );
		} else {
			$image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr );
		}

		$image_meta = wp_get_attachment_metadata( $id );

		$orientation = '';

		if ( isset( $image_meta['height'], $image_meta['width'] ) ) {
			$orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape';
		}

		$output .= "<{$itemtag} class='gallery-item'>";
		$output .= "
			<{$icontag} class='gallery-icon {$orientation}'>
				$image_output
			</{$icontag}>";

		if ( $captiontag && trim( $attachment->post_excerpt ) ) {
			$output .= "
				<{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'>
				" . wptexturize( $attachment->post_excerpt ) . "
				</{$captiontag}>";
		}

		$output .= "</{$itemtag}>";

		if ( ! $html5 && $columns > 0 && 0 === ++$i % $columns ) {
			$output .= '<br style="clear: both" />';
		}
	}

	if ( ! $html5 && $columns > 0 && 0 !== $i % $columns ) {
		$output .= "
			<br style='clear: both' />";
	}

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

	return $output;
}