ACF Flexible Content Loop
January 14, 2025 · AI Conversations
### Example: ACF Flexible Content Loop
1. **Set Up Flexible Content in ACF**:
– Add a Flexible Content field group in ACF.
– Add multiple layouts (e.g., `hero_section`, `text_block`, `image_gallery`).
– Add fields within each layout (e.g., text, image, gallery).
2. **Code to Loop Through Layouts**:
In your template file (e.g., `page.php`, `single.php`), you can loop through the layouts like this:
<?php if (have_rows('flexible_content_field')): ?>
<?php while (have_rows('flexible_content_field')): the_row(); ?>
<?php if (get_row_layout() == 'hero_section'): ?>
<section class="hero-section">
<h1><?php the_sub_field('hero_title'); ?></h1>
<p><?php the_sub_field('hero_subtitle'); ?></p>
<img src="<?php the_sub_field('hero_image'); ?>" alt="Hero Image">
</section>
<?php elseif (get_row_layout() == 'text_block'): ?>
<div class="text-block">
<h2><?php the_sub_field('heading'); ?></h2>
<p><?php the_sub_field('content'); ?></p>
</div>
<?php elseif (get_row_layout() == 'image_gallery'): ?>
<div class="image-gallery">
<?php $images = get_sub_field('gallery'); ?>
<?php if ($images): ?>
<?php foreach ($images as $image): ?>
<img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>">
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
### Explanation of the Code:
– **`have_rows('flexible_content_field')`**: Checks if there are rows (layouts) in the Flexible Content field.
– **`the_row()`**: Iterates through each layout.
– **`get_row_layout()`**: Retrieves the current layout's name (e.g., `hero_section`).
– **`the_sub_field()`**: Displays subfields within the current layout.
– **Conditionals (`if`, `elseif`)**: Identify which layout is being used and display the appropriate content.
3. **Style Your Layouts**:
– Use CSS or SCSS to style your layouts. Assign unique classes (e.g., `hero-section`, `text-block`) to target specific sections.
4. **Optional: Use a Partial for Each Layout**:
For better maintainability, you can create partial files for each layout (e.g., `partials/hero-section.php`) and include them dynamically:
<?php if (have_rows('flexible_content_field')): ?>
<?php while (have_rows('flexible_content_field')): the_row(); ?>
<?php get_template_part('partials/' . get_row_layout()); ?>
<?php endwhile; ?>
<?php endif; ?>
This approach keeps your template file clean and makes it easier to manage each layout's HTML structure.
—
Let me know if you need help customizing or extending this!
—
### Example: ACF Flexible Content with a Repeater
#### 1. **Set Up ACF Flexible Content and Repeater**
– Create a **Flexible Content field** (e.g., `flexible_content_field`).
– Add layouts inside the Flexible Content field (e.g., `services_layout`, `testimonials_layout`).
– Inside one of the layouts (e.g., `services_layout`), add a **Repeater field** (e.g., `services_repeater`) with subfields like:
– `service_title`
– `service_description`
– `service_icon`
—
#### 2. **Template Code for Repeater Inside Layout**
Here’s how you loop through the Flexible Content field and handle the Repeater field inside a layout:
<?php if (have_rows('flexible_content_field')): ?>
<?php while (have_rows('flexible_content_field')): the_row(); ?>
<?php if (get_row_layout() == 'services_layout'): ?>
<section class="services-layout">
<h2><?php the_sub_field('services_heading'); ?></h2>
<?php if (have_rows('services_repeater')): ?>
<div class="services-list">
<?php while (have_rows('services_repeater')): the_row(); ?>
<div class="service-item">
<img src="<?php the_sub_field('service_icon'); ?>" alt="Service Icon">
<h3><?php the_sub_field('service_title'); ?></h3>
<p><?php the_sub_field('service_description'); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</section>
<?php elseif (get_row_layout() == 'testimonials_layout'): ?>
<section class="testimonials-layout">
<h2><?php the_sub_field('testimonials_heading'); ?></h2>
<p><?php the_sub_field('testimonial_text'); ?></p>
</section>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
—
### Explanation:
1. **Flexible Content Field**:
– Loops through each layout using `have_rows()` and `the_row()`.
2. **Repeater Field Inside Layout**:
– Checks for rows in the Repeater field using `have_rows('services_repeater')`.
– Loops through each row using `while (have_rows('services_repeater')): the_row()`.
3. **Subfields in Repeater**:
– Access each subfield in the Repeater with `the_sub_field('subfield_name')`.
—
### Sample Output
**Flexible Content Layout: Services Layout**
<section class="services-layout">
<h2>Our Services</h2>
<div class="services-list">
<div class="service-item">
<img src="icon1.png" alt="Service Icon">
<h3>Web Development</h3>
<p>Custom web development services for your business.</p>
</div>
<div class="service-item">
<img src="icon2.png" alt="Service Icon">
<h3>SEO Optimization</h3>
<p>Improve your site's visibility on search engines.</p>
</div>
</div>
</section>
—
### Benefits of This Approach:
1. **Reusable Components**:
– You can reuse the Repeater field for structured, repeated data within any layout.
2. **Customizable Layouts**:
– Add dynamic layouts and include repeatable sections for more flexibility.
3. **Modular Design**:
– Code for Flexible Content and Repeater fields is clean and easy to maintain.
—
Let me know if you need assistance setting this up!
—
### Steps to Use Separate Template Files for Each Layout
#### 1. **Set Up Your Flexible Content Field**
– Add a Flexible Content field (e.g., `flexible_content_field`) in ACF.
– Add layouts to it (e.g., `hero_section`, `services_layout`, `testimonials_layout`).
#### 2. **Create Template Files for Layouts**
In your theme folder, create a directory (e.g., `template-parts/flexible-content`) to store the layout files.
For example:
theme/
├── template-parts/
│ └── flexible-content/
│ ├── hero-section.php
│ ├── services-layout.php
│ └── testimonials-layout.php
Each file corresponds to a layout, e.g.:
**`template-parts/flexible-content/hero-section.php`:**
<section class="hero-section">
<h1><?php the_sub_field('hero_title'); ?></h1>
<p><?php the_sub_field('hero_subtitle'); ?></p>
<img src="<?php the_sub_field('hero_image'); ?>" alt="Hero Image">
</section>
**`template-parts/flexible-content/services-layout.php`:**
<section class="services-layout">
<h2><?php the_sub_field('services_heading'); ?></h2>
<?php if (have_rows('services_repeater')): ?>
<div class="services-list">
<?php while (have_rows('services_repeater')): the_row(); ?>
<div class="service-item">
<img src="<?php the_sub_field('service_icon'); ?>" alt="Service Icon">
<h3><?php the_sub_field('service_title'); ?></h3>
<p><?php the_sub_field('service_description'); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</section>
—
#### 3. **Main Template File**
In the main template file (e.g., `page.php`), use `get_template_part()` or `locate_template()` to load the correct layout template dynamically:
<?php if (have_rows('flexible_content_field')): ?>
<?php while (have_rows('flexible_content_field')): the_row(); ?>
<?php
// Get the layout name.
$layout = get_row_layout();
// Generate the path to the partial file.
$template = 'template-parts/flexible-content/' . $layout . '.php';
// Check if the template file exists before including it.
if (locate_template($template)) {
get_template_part('template-parts/flexible-content/' . $layout);
} else {
echo '<p>Template for layout <strong>' . $layout . '</strong> not found.</p>';
}
?>
<?php endwhile; ?>
<?php endif; ?>
—
### Explanation:
1. **`get_row_layout()`**:
– Retrieves the name of the current layout (e.g., `hero_section`, `services_layout`).
2. **`locate_template()`**:
– Ensures the template file exists before including it. Prevents errors if a layout file is missing.
3. **`get_template_part()`**:
– Loads the partial file for the layout dynamically.
4. **Fallback Handling**:
– If a layout's template is missing, it displays an error message (optional).
—
### Advantages of Separate Template Files:
1. **Improved Organization**:
– Each layout has its own file, making the codebase easier to manage.
2. **Reusability**:
– Layout files can be reused across different pages or projects.
3. **Clean Main Template**:
– The main template file (`page.php`) remains clean, handling only the logic to load layouts.
4. **Scalability**:
– Adding new layouts is simple—just create a new template file and include it automatically.
—
### Example Output for Missing Template
If a layout template is missing, the code will output:
<p>Template for layout <strong>missing_layout_name</strong> not found.</p>
This makes debugging easier and avoids breaking the site.
—
Let me know if you need help setting up a specific layout or resolving errors!
—
### Setting Up the Post Object Field in ACF
1. **Create the Post Object Field:**
– Go to **Custom Fields > Add New**.
– Add a new field group.
– Add a field with the type **Post Object**.
– Set options like:
– **Filter by Post Type:** (e.g., Posts, Pages, or Custom Post Types).
– **Allow multiple selections** (if you want to select more than one post).
2. **Assign the Field Group** to the relevant post type, page, or template.
—
### Using the Post Object Field in Your Template
#### Single Post Selection (Post Object Field):
If the Post Object field allows selecting a single post:
<?php
$post_object = get_field('your_post_object_field');
if ($post_object):
// Ensure the $post_object contains a valid post object
$post = $post_object;
setup_postdata($post);
?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_excerpt(); ?></p>
</article>
<?php
wp_reset_postdata();
endif;
?>
#### Multiple Post Selection (Post Object Field with Multiple Option Enabled):
If the Post Object field allows selecting multiple posts:
<?php
$posts = get_field('your_post_object_field');
if ($posts):
foreach ($posts as $post):
setup_postdata($post);
?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_excerpt(); ?></p>
</article>
<?php
endforeach;
wp_reset_postdata();
endif;
?>
—
### Using Post Object Inside a Repeater Field
If the Post Object field is inside a Repeater or Flexible Content layout:
<?php if (have_rows('your_repeater_field')): ?>
<?php while (have_rows('your_repeater_field')): the_row(); ?>
<?php
$post_object = get_sub_field('your_post_object_field');
if ($post_object):
$post = $post_object;
setup_postdata($post);
?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_excerpt(); ?></p>
</article>
<?php
wp_reset_postdata();
endif;
?>
<?php endwhile; ?>
<?php endif; ?>
—
### Displaying Custom Post Object Fields
If the selected post has custom fields (created with ACF), you can access them like this:
<?php
$post_object = get_field('your_post_object_field');
if ($post_object):
$post = $post_object;
setup_postdata($post);
?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p><?php the_field('custom_field_name'); ?></p>
</article>
<?php
wp_reset_postdata();
endif;
?>
—
### Example Use Case
#### ACF Field Setup:
– **Field Name:** `related_posts`
– **Type:** Post Object
– **Allow Multiple:** Yes
#### Template Code:
<?php
$related_posts = get_field('related_posts');
if ($related_posts):
echo '<section class="related-posts">';
echo '<h2>Related Posts</h2>';
foreach ($related_posts as $post):
setup_postdata($post);
?>
<article>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p><?php the_excerpt(); ?></p>
</article>
<?php
endforeach;
wp_reset_postdata();
echo '</section>';
endif;
?>
—
### Notes:
1. **`setup_postdata($post)`**:
– Ensures WordPress functions (e.g., `the_title()`, `the_excerpt()`) work as expected for the selected post.
2. **`wp_reset_postdata()`**:
– Resets the global `$post` variable after using `setup_postdata()`.
3. **Custom Styling**:
– Add classes or IDs to style the displayed posts.
—
Let me know if you need help with a specific implementation!
—
### Steps to Use Post Object Inside Flexible Content
#### 1. **Set Up Flexible Content and Post Object Field**
– Create a Flexible Content field (e.g., `flexible_content_field`).
– Add a layout (e.g., `related_posts_layout`).
– Inside the layout, add a **Post Object** field (e.g., `related_posts`).
– Enable **multiple selection** if you want to select more than one post.
—
#### 2. **Template Code for Post Object Inside Flexible Content**
Here’s how to loop through Flexible Content layouts and handle the **Post Object** field dynamically:
<?php if (have_rows('flexible_content_field')): ?>
<?php while (have_rows('flexible_content_field')): the_row(); ?>
<?php if (get_row_layout() == 'related_posts_layout'): ?>
<section class="related-posts">
<h2><?php the_sub_field('related_posts_heading'); ?></h2>
<?php
$related_posts = get_sub_field('related_posts'); // Post Object field
if ($related_posts): ?>
<div class="related-posts-list">
<?php foreach ($related_posts as $post): ?>
<?php setup_postdata($post); ?>
<article class="related-post-item">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p><?php the_excerpt(); ?></p>
</article>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
</div>
<?php else: ?>
<p>No related posts found.</p>
<?php endif; ?>
</section>
<?php elseif (get_row_layout() == 'another_layout'): ?>
<!-- Handle another layout -->
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
—
### Explanation:
1. **Flexible Content Field**:
– Use `have_rows('flexible_content_field')` to loop through layouts.
– Use `get_row_layout()` to check the current layout.
2. **Post Object Field**:
– Retrieve the Post Object field using `get_sub_field('related_posts')`.
– Check if posts exist, then loop through them.
3. **`setup_postdata($post)`**:
– Ensures WordPress functions like `the_title()` and `the_permalink()` work for each selected post.
4. **Reset Post Data**:
– Use `wp_reset_postdata()` after looping through the posts to avoid affecting the global `$post` variable.
—
### Example Use Case
#### Flexible Content Layout: `related_posts_layout`
– **Fields in Layout**:
– `related_posts_heading` (Text Field)
– `related_posts` (Post Object Field)
#### Sample Output:
<section class="related-posts">
<h2>Related Articles</h2>
<div class="related-posts-list">
<article class="related-post-item">
<h3><a href="post-link-1">Post Title 1</a></h3>
<p>Post excerpt 1...</p>
</article>
<article class="related-post-item">
<h3><a href="post-link-2">Post Title 2</a></h3>
<p>Post excerpt 2...</p>
</article>
</div>
</section>
—
### Notes:
– You can use additional ACF fields (like `related_posts_heading`) to customize the section heading or other elements.
– This approach works with single or multiple post selections.
– Always reset post data (`wp_reset_postdata()`) after using `setup_postdata()`.
Let me know if you need assistance with specific layouts!