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
| Setting | Default | Options | Description |
|---|---|---|---|
| Min Images | 0 | Integer | Minimum images required. 0 = no minimum. |
| Max Images | 0 | Integer | Maximum images allowed. 0 = unlimited. |
| Return Format | object | object · id · url | Controls the shape of each item in the returned array. |
| Field: Caption | true | on/off | Show the per-image caption input. |
| Field: Alt Text | true | on/off | Show the per-image alt text input. |
| Field: Link | false | on/off | Show the per-image link URL input. |
| Preview Size | thumbnail | Any WP image size | Image 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
Basic grid gallery
$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>';
}
Lightbox gallery with links
$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>';
}