← Writing  ·  Tutorials · WordPress · ACF Pro

Custom WordPress themes with ACF Pro — a real-world setup.

The folder structure, partial-template approach, and ACF block patterns I reach for on every client build. Aimed at intermediate WP devs.

S
Saugat Rimal
Frontend Developer · Jul 18, 2023
12 min read WordPress ACF Pro
wp

Building custom WordPress themes is one of those skills that is easy to do badly. ACF Pro plus a strict folder convention makes it dramatically easier to do well. Here is the setup I have used on roughly 40 client builds at Swivt and Growthzilla.

01Why ACF Pro is still the answer in 2026

Gutenberg has come a long way. Full Site Editing is real. So why am I still paying for ACF Pro?

  • Authoring experience. ACF builds editor UIs that match how clients think about their content.
  • Custom blocks in PHP. Skip the React build pipeline for blocks. Write a template, register a field group, done.
  • Repeaters, flexible content, relationships. Native Gutenberg can do most of this — clumsily. ACF makes it pleasant.
  • It has been stable for a decade. Clients can hand the site to the next dev and it will just work.

02Folder structure

Every WP theme I ship looks like this:

theme/
├── style.css            // required header, mostly empty
├── functions.php        // thin — just include()s
├── header.php
├── footer.php
├── index.php
├── front-page.php
├── page.php
├── single.php
├── archive.php
├── 404.php
│
├── inc/                 // PHP includes
│   ├── setup.php
│   ├── assets.php
│   ├── acf.php
│   ├── blocks.php
│   └── helpers.php
│
├── partials/            // reusable template pieces
│   ├── nav.php
│   ├── footer.php
│   ├── hero.php
│   └── card.php
│
├── blocks/              // ACF block templates
│   ├── hero/
│   │   ├── block.json
│   │   └── render.php
│   └── feature-grid/
│       ├── block.json
│       └── render.php
│
├── acf-json/            // version-controlled field groups
└── assets/
    ├── css/
    ├── js/
    └── img/
The single most important file is acf-json/. Toggling “Local JSON” in ACF means field groups version-control like normal code — no more “the staging site has different fields than prod.”

03Field groups by template, not by post type

Beginners attach field groups to a post type. Better: attach them to the template. That way, switching a page from “Default” to “Landing” swaps the fields automatically.

04ACF Blocks for Gutenberg

Modern WP, page builder ergonomics, no React build step:

// blocks/hero/block.json
{
  "name": "acf/hero",
  "title": "Hero",
  "category": "theme",
  "icon": "star-filled",
  "acf": {
    "mode": "preview",
    "renderTemplate": "render.php"
  }
}

05Partial templates and get_template_part

Anything that appears in more than one place lives in partials/ and is included via get_template_part() — the WordPress equivalent of a React component.

06Gotchas to avoid

  • Always escape output. esc_html(), esc_url(), esc_attr().
  • Set a fallback for empty fields. Editors will leave things blank. Default gracefully.
  • Do not query inside loops. get_field() does not hit the DB but child queries do. Batch.
  • Version-control your acf-json/. Commit those files. The whole point.
  • Use ACF block previews. Editors should see roughly what visitors see. Set "mode": "preview" in block.json.

This setup has handled marketing sites, ecommerce, and editorial publications. If you are still building WP themes that look like 2018, give this structure a weekend.

WordPress ACF Pro Custom themes PHP Tutorial