← All posts

Building Flexible Layouts with FlyntWP: The Twig Content Slot Pattern

Building Flexible Layouts with FlyntWP: The Twig Content Slot Pattern

One of the most common frustrations I hear from developers dealing with traditional low-code page builders is the sheer bloat and inflexibility they introduce. You get a visually appealing drag-and-drop interface, sure, but under the hood, it’s often a tangled mess of deeply nested divs, inline styles, and JavaScript that fights against any attempt to optimize for performance. This is precisely why I’ve come to love FlyntWP, and how its programmatic approach, particularly with modular Twig components, allows for truly clean and performant WordPress builds. Today, I want to dive into a specific, concrete technique that exemplifies this: using a "content slot" pattern within your Twig components.

At its core, FlyntWP promotes building your site out of small, self-contained Twig components. Think of them as Lego bricks, each with its own `index.twig` template, `script.js`, and `style.scss`. While ACF Pro fields handle the *data* for these components (like a heading string, an image URL, or a link object), sometimes you need a component that can house *arbitrary* HTML content — a paragraph, a list, even another component – rather than just simple data. This is where the content slot comes in.

Imagine you're building a "Card" component. It has a title, maybe an image, and a call-to-action link, all driven by ACF fields. But the main body of the card needs to be flexible. It might be a simple paragraph, or sometimes a bulleted list, or even a short form. Instead of creating a separate card component for each variation, we can define a slot for that body content. Here’s how your `components/Card/index.twig` might look:

<div class="card"> <div class="card__header"> {% if fields.image %} <img src="{{ fields.image.url }}" alt="{{ fields.image.alt }}" loading="lazy"> {% endif %} {% if fields.title %} <h3 class="card__title">{{ fields.title }}</h3> {% endif %} </div> <div class="card__body"> {{ content|raw }} </div> {% if fields.link %} <a href="{{ fields.link.url }}" class="card__link">{{ fields.link.title }}</a> {% endif %} </div>

Notice that `{{ content|raw }}` line? That's our content slot. It's a simple Twig variable, but critically, we're using the `|raw` filter to tell Twig to render its value as raw HTML, not escaped text. This is what allows us to pass in entire blocks of HTML.

Now, let's look at how you'd use this `Card` component in your `templates/post.twig` or even within another FlyntWP component. Let’s say you have an ACF Wysiwyg field called `card_description` on your Flexible Content layout for a particular page.

{% include 'components/Card/index.twig' with { fields: { title: post.title, image: post.thumbnail, link: { url: post.link, title: 'Read More' } }, content: post.meta('card_description') } %}

In this example, the `content` variable is populated directly from an ACF Wysiwyg field on our post. The beauty is, `content` could be anything: a hardcoded string of HTML, the output of another Twig partial, or even content from a different ACF field type. This pattern ensures our component remains highly reusable and agnostic to the *source* of its internal content.

The immediate benefits are clear: reduced code duplication, enhanced modularity, and a cleaner DOM. Because each component is focused on its specific task and only renders the necessary HTML, you end up with lean, semantic markup that search engines love. This directly translates to better Core Web Vitals, as there's less unnecessary HTML for the browser to parse and render. And when you're working with FlyntWP's Vite integration, making a change to one of these well-scoped components means Vite can hot-reload your changes almost instantly, providing a lightning-fast development experience that no traditional low-code builder can match.

By embracing programmatic patterns like this content slot in Twig, we leverage the full power of FlyntWP to build robust, high-performance WordPress sites that are a joy to develop and maintain, far surpassing the limitations of slow, bloated page builders. It's all about thoughtful structure and modularity, and Twig gives us the perfect tools for the job.