Title: gallery_shortcode
Published: April 25, 2014
Last modified: February 24, 2026

---

# gallery_shortcode( array $attr ): string

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#changelog)
 * [User Contributed Notes](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#user-contributed-notes)

[ Back to top](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#wp--skip-link--target)

Builds the Gallery shortcode output.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#description)󠁿

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

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#parameters)󠁿

 `$attr`arrayrequired

Attributes of the gallery shortcode.

 * `order` string
 * Order of the images in the gallery. Default `'ASC'`. Accepts `'ASC'`, `'DESC'`.
 * `orderby` string
 * The field to use when ordering the images. Default ‘menu_order ID’.
    Accepts 
   any valid SQL ORDERBY statement.
 * `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 empty.
 * `include` string
 * A comma-separated list of IDs of attachments to include. Default empty.
 * `exclude` string
 * A comma-separated list of IDs of attachments to exclude. Default empty.
 * `link` string
 * What to link each image to. Default empty (links to the attachment page).
    Accepts`'
   file'`, `'none'`.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#return)󠁿

 string HTML content to display gallery.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#source)󠁿

    ```php
    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;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/media.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/media.php#L2711)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/media.php#L2711-L2961)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#hooks)󠁿

 [apply_filters( ‘gallery_style’, string $gallery_style )](https://developer.wordpress.org/reference/hooks/gallery_style/)

Filters the default gallery shortcode CSS styles.

 [apply_filters( ‘post_gallery’, string $output, array $attr, int $instance )](https://developer.wordpress.org/reference/hooks/post_gallery/)

Filters the default gallery shortcode output.

 [apply_filters( ‘use_default_gallery_style’, bool $print )](https://developer.wordpress.org/reference/hooks/use_default_gallery_style/)

Filters whether to print default gallery styles.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#related)󠁿

| Uses | Description | 
| [is_post_publicly_viewable()](https://developer.wordpress.org/reference/functions/is_post_publicly_viewable/)`wp-includes/post.php` |

Determines whether a post is publicly viewable.

  | 
| [get_children()](https://developer.wordpress.org/reference/functions/get_children/)`wp-includes/post.php` |

Retrieves all children of the post parent ID.

  | 
| [tag_escape()](https://developer.wordpress.org/reference/functions/tag_escape/)`wp-includes/formatting.php` |

Escapes an HTML tag name.

  | 
| [sanitize_html_class()](https://developer.wordpress.org/reference/functions/sanitize_html_class/)`wp-includes/formatting.php` |

Sanitizes an HTML classname to ensure it only contains valid characters.

  | 
| [wptexturize()](https://developer.wordpress.org/reference/functions/wptexturize/)`wp-includes/formatting.php` |

Replaces common plain text characters with formatted entities.

  | 
| [wp_kses_allowed_html()](https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/)`wp-includes/kses.php` |

Returns an array of allowed HTML tags and attributes for a given context.

  | 
| [is_feed()](https://developer.wordpress.org/reference/functions/is_feed/)`wp-includes/query.php` |

Determines whether the query is for a feed.

  | 
| [is_rtl()](https://developer.wordpress.org/reference/functions/is_rtl/)`wp-includes/l10n.php` |

Determines whether the current locale is right-to-left (RTL).

  | 
| [shortcode_atts()](https://developer.wordpress.org/reference/functions/shortcode_atts/)`wp-includes/shortcodes.php` |

Combines user attributes with known attributes and fill in defaults when needed.

  | 
| [wp_get_attachment_link()](https://developer.wordpress.org/reference/functions/wp_get_attachment_link/)`wp-includes/post-template.php` |

Retrieves an attachment page link using an image or icon, if possible.

  | 
| [post_password_required()](https://developer.wordpress.org/reference/functions/post_password_required/)`wp-includes/post-template.php` |

Determines whether the post requires password and whether a correct password has been provided.

  | 
| [wp_get_attachment_image()](https://developer.wordpress.org/reference/functions/wp_get_attachment_image/)`wp-includes/media.php` |

Gets an HTML img element representing an image attachment.

  | 
| [wp_get_attachment_metadata()](https://developer.wordpress.org/reference/functions/wp_get_attachment_metadata/)`wp-includes/post.php` |

Retrieves attachment metadata for attachment ID.

  | 
| [get_posts()](https://developer.wordpress.org/reference/functions/get_posts/)`wp-includes/post.php` |

Retrieves an array of the latest posts, or posts matching the given criteria.

  | 
| [current_user_can()](https://developer.wordpress.org/reference/functions/current_user_can/)`wp-includes/capabilities.php` |

Returns whether the current user has the specified capability.

  | 
| [current_theme_supports()](https://developer.wordpress.org/reference/functions/current_theme_supports/)`wp-includes/theme.php` |

Checks a theme’s support for a given feature.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [get_post()](https://developer.wordpress.org/reference/functions/get_post/)`wp-includes/post.php` |

Retrieves post data given a post ID or post object.

  |

[Show 13 more](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#)

| Used by | Description | 
| [WP_Widget_Media_Gallery::render_media()](https://developer.wordpress.org/reference/classes/wp_widget_media_gallery/render_media/)`wp-includes/widgets/class-wp-widget-media-gallery.php` |

Render the media on the frontend.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#changelog)󠁿

| Version | Description | 
| [5.6.0](https://developer.wordpress.org/reference/since/5.6.0/) | Replaced order-style PHP type conversion functions with typecasts. Fix logic for an array of image dimensions. | 
| [5.5.0](https://developer.wordpress.org/reference/since/5.5.0/) | Ensured that galleries can be output as a list of links in feeds. | 
| [5.3.0](https://developer.wordpress.org/reference/since/5.3.0/) | Saved progress of intermediate image creation after upload. | 
| [5.1.0](https://developer.wordpress.org/reference/since/5.1.0/) | Code cleanup for WPCS 1.0.0 coding standards. | 
| [4.6.0](https://developer.wordpress.org/reference/since/4.6.0/) | Standardized filter docs to match documentation standards for PHP. | 
| [4.2.0](https://developer.wordpress.org/reference/since/4.2.0/) | Passed the shortcode instance ID to `post_gallery` and `post_playlist` filters. | 
| [4.1.0](https://developer.wordpress.org/reference/since/4.1.0/) | Added attribute to `wp_get_attachment_link()` to output `aria-describedby`. | 
| [4.0.0](https://developer.wordpress.org/reference/since/4.0.0/) | Removed use of `extract()`. | 
| [3.9.0](https://developer.wordpress.org/reference/since/3.9.0/) | `html5` gallery support, accepting `'itemtag'`, `'icontag'`, and `'captiontag'` attributes. | 
| [3.7.0](https://developer.wordpress.org/reference/since/3.7.0/) | Introduced the `link` attribute. | 
| [3.6.0](https://developer.wordpress.org/reference/since/3.6.0/) | Added validation for tags used in gallery shortcode. Add orientation information to items. | 
| [3.5.0](https://developer.wordpress.org/reference/since/3.5.0/) | Use [get_post()](https://developer.wordpress.org/reference/functions/get_post/) instead of global `$post`. Handle mapping of `ids` to `include` and `orderby`. | 
| [2.9.0](https://developer.wordpress.org/reference/since/2.9.0/) | Added support for `include` and `exclude` to shortcode. | 
| [2.8.0](https://developer.wordpress.org/reference/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. | 
| [2.5.0](https://developer.wordpress.org/reference/since/2.5.0/) | Introduced. |

[Show 10 more](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#)

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#user-contributed-notes)󠁿

 1.  [Skip to note 2 content](https://developer.wordpress.org/reference/functions/gallery_shortcode/?output_format=md#comment-content-1386)
 2.   [Codex](https://profiles.wordpress.org/codex/)  [  10 years ago  ](https://developer.wordpress.org/reference/functions/gallery_shortcode/#comment-1386)
 3. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fgallery_shortcode%2F%23comment-1386)
    Vote results for this note: -4[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fgallery_shortcode%2F%23comment-1386)
 4. **Basic Example**
 5. Adds the gallery shortcode.
 6.     ```php
        add_shortcode( 'gallery', 'gallery_shortcode' );
        ```
    
 7.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fgallery_shortcode%2F%3Freplytocom%3D1386%23feedback-editor-1386)

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fgallery_shortcode%2F)
before being able to contribute a note or feedback.