Photo Gallery

An image gallery field with drag-to-reorder sorting, per-image metadata (caption, alt text, link), and configurable min/max image counts. More structured than the native Gallery field — each image can carry its own caption and link URL independently of the media library.

★
Pro field

Photo Gallery requires the Extra Fields for ACF Pro license.

Settings

SettingDefaultOptionsDescription
Min Images0IntegerMinimum images required. 0 = no minimum.
Max Images0IntegerMaximum images allowed. 0 = unlimited.
Return Formatobjectobject · id · urlControls the shape of each item in the returned array.
Field: Captiontrueon/offShow the per-image caption input.
Field: Alt Texttrueon/offShow the per-image alt text input.
Field: Linkfalseon/offShow the per-image link URL input.
Preview SizethumbnailAny WP image sizeImage size used for admin thumbnails.

Return values

return_format: 'object'

Returns an array of image objects.

$gallery = get_field('project_gallery');
// [
//   [
//     'id'      => 123,
//     'url'     => 'https://example.com/wp-content/uploads/photo.jpg',
//     'caption' => 'Living room after renovation',
//     'alt'     => 'Bright open-plan living room with oak flooring',
//     'link'    => 'https://example.com/projects/renovation',
//     'sizes'   => ['thumbnail' => '...', 'medium' => '...', 'large' => '...'],
//   ],
//   ...
// ]

return_format: 'id'

Returns an array of attachment IDs.

$ids = get_field('project_gallery');
// [123, 124, 125]

return_format: 'url'

Returns an array of full-size image URLs.

$urls = get_field('project_gallery');
// ['https://example.com/.../photo.jpg', ...]

Usage

$gallery = get_field('project_gallery');

if ($gallery) {
    echo '<div class="gallery grid grid-cols-3 gap-4">';
    foreach ($gallery as $image) {
        $src = wp_get_attachment_image_url($image['id'], 'medium_large');
        $alt = $image['alt'] ?: get_post_meta($image['id'], '_wp_attachment_image_alt', true);

        echo '<figure class="gallery-item">';
        echo '<img src="' . esc_url($src) . '" alt="' . esc_attr($alt) . '" loading="lazy">';

        if ($image['caption']) {
            echo '<figcaption>' . esc_html($image['caption']) . '</figcaption>';
        }
        echo '</figure>';
    }
    echo '</div>';
}
$gallery = get_field('portfolio_gallery');

if ($gallery) {
    echo '<div class="gallery" data-lightbox="portfolio">';
    foreach ($gallery as $image) {
        $full  = wp_get_attachment_image_url($image['id'], 'full');
        $thumb = wp_get_attachment_image_url($image['id'], 'thumbnail');

        echo '<a href="' . esc_url($full) . '" data-lightbox="portfolio">';
        echo '<img src="' . esc_url($thumb) . '" alt="' . esc_attr($image['alt']) . '">';
        echo '</a>';
    }
    echo '</div>';
}

Using with a JS slider

$images = get_field('hero_slider'); // return_format: 'object'

if ($images) {
    echo '<div class="swiper">';
    echo '<div class="swiper-wrapper">';
    foreach ($images as $image) {
        $src = wp_get_attachment_image_url($image['id'], 'large');
        echo '<div class="swiper-slide">';
        echo '<img src="' . esc_url($src) . '" alt="' . esc_attr($image['alt']) . '">';
        echo '</div>';
    }
    echo '</div>';
    echo '</div>';
}