gallery_shortcode()WP 2.5.0

Builds the Gallery shortcode output.

This implements the functionality of the Gallery Shortcode for displaying WordPress images on a post.

Return

String. HTML content to display gallery.

Usage

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

Attributes of the gallery shortcode.

  • order(string)
    Order of the images in the gallery. Accepts 'ASC', 'DESC'.
    Default: 'ASC'

  • orderby(string)
    The field to use when ordering the images. Accepts any valid SQL ORDERBY statement.
    Default: 'menu_order ID'

  • id(int)
    Post ID.

  • itemtag(string)
    HTML tag to use for each image in the gallery.
    Default: 'dl', or 'figure' when the theme registers HTML5 gallery support

  • icontag(string)
    HTML tag to use for each image's icon.
    Default: 'dt', or 'div' when the theme registers HTML5 gallery support

  • captiontag(string)
    HTML tag to use for each image's caption.
    Default: 'dd', or 'figcaption' when the theme registers HTML5 gallery support

  • columns(int)
    Number of columns of images to display.
    Default: 3

  • size(string|int[])
    Size of the images to display. Accepts any registered image size name, or an array of width and height values in pixels (in that order).
    Default: 'thumbnail'

  • ids(string)
    A comma-separated list of IDs of attachments to display.
    Default: ''

  • include(string)
    A comma-separated list of IDs of attachments to include.
    Default: ''

  • exclude(string)
    A comma-separated list of IDs of attachments to exclude.
    Default: ''

  • link(string)
    What to link each image to. Accepts 'file', 'none'.
    Default: empty (links to the attachment page)

Examples

0

#1 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

#2 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

#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.4.3

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 user cannot read the post or 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;
}