Flexible content is the custom fields feature that turns WordPress into a page builder without the bloat. Define multiple “row layouts” (hero, features, testimonials, CTA), let editors mix and match layouts to build a page. Field Forge’s flexible content field is fully ACF-compatible and powers modular landing page patterns on production WordPress sites.
A flexible content field is a row-based field where each row can be one of several predefined layouts. Unlike a repeater (where every row has the same sub-fields), flexible content lets editors pick which layout to use per row.
A field group called “Landing Page Sections” contains a flexible content field with four possible layouts:
An editor building a landing page clicks “Add Row” and chooses which layout to use. They can add a Hero, then Features, then two Testimonials, then another Features, then a CTA. Mix and match in any order, any number of each.
The result: a custom landing page builder with consistent design and structured data.
In Field Forge’s visual builder, you configure a flexible content field by defining layouts. Each layout is a named container for sub-fields:
Flexible Content: Page Sections
Layout: Hero
- Title (Text, required)
- Subtitle (Textarea)
- Background Image (Image, required)
- CTA Button (Group: text + URL)
Layout: Features
- Section Title (Text)
- Features (Repeater)
- Icon (Select from icon library)
- Title (Text)
- Description (Textarea)
Layout: Testimonial
- Quote (Textarea)
- Author Name (Text)
- Author Photo (Image)
- Author Company (Text)
Layout: CTA
- Headline (Text)
- Primary Button (Group)
Editors see a dropdown or grid of these layouts when adding rows.
Flexible content uses the same template functions as ACF and SCF. Code written for ACF works unchanged:
<?php if (have_rows('page_sections')) : ?>
<?php while (have_rows('page_sections')) : the_row(); ?>
<?php if (get_row_layout() === 'hero') : ?>
<section class="hero">
<h1><?php the_sub_field('title'); ?></h1>
<p><?php the_sub_field('subtitle'); ?></p>
<?php $image = get_sub_field('background_image'); ?>
<img src="<?php echo esc_url($image['url']); ?>">
</section>
<?php elseif (get_row_layout() === 'features') : ?>
<section class="features">
<h2><?php the_sub_field('section_title'); ?></h2>
<?php if (have_rows('features')) : ?>
<div class="feature-grid">
<?php while (have_rows('features')) : the_row(); ?>
<div class="feature">
<h3><?php the_sub_field('title'); ?></h3>
<p><?php the_sub_field('description'); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
</section>
<?php elseif (get_row_layout() === 'testimonial') : ?>
<blockquote>
<p><?php the_sub_field('quote'); ?></p>
<cite><?php the_sub_field('author_name'); ?></cite>
</blockquote>
<?php elseif (get_row_layout() === 'cta') : ?>
<section class="cta">
<h2><?php the_sub_field('headline'); ?></h2>
</section>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
The get_row_layout() function returns the layout name of the current row, letting you branch rendering logic. This is identical to how ACF handles flexible content.
Flexible content wins when:
Page builders (Elementor, Divi) win when:
Many sites use both: flexible content for structured sections (product pages, landing pages, case studies) and a page builder for one-off marketing pages.
If you’re coming from ACF (or SCF), your existing flexible content data migrates cleanly. Field Forge’s importer:
get_row_layout() / have_rows() calls in your themeTemplate code using get_row_layout() keeps working unchanged.
Flexible content fields are historically slow in ACF and SCF because each row’s data is stored as separate wp_postmeta entries. A page with 10 flexible content rows and 5 sub-fields per row = 50 meta entries, and the query to reconstruct the row order and layout names is complex.
Field Forge stores flexible content rows in the custom wp_fieldforge_values table with proper parent_id and row_index columns. A single query fetches all rows with their layouts and sub-field values. Learn more about custom table storage →
Flexible content rows are exposed as an array of objects with the layout name included:
{
"page_sections": [
{
"acf_fc_layout": "hero",
"title": "Welcome to Our Site",
"subtitle": "Building better WordPress experiences",
"background_image": { "id": 123, "url": "..." }
},
{
"acf_fc_layout": "features",
"section_title": "Why Choose Us",
"features": [
{ "title": "Fast", "description": "..." },
{ "title": "Reliable", "description": "..." }
]
},
{
"acf_fc_layout": "cta",
"headline": "Ready to start?"
}
]
}
The acf_fc_layout key matches ACF’s output format for REST API consumers that already parse ACF data.
Get Field Forge — from $35/year →
Flexible content is included in every paid plan.