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>';
}