Skip to main content

Child Theme Structure

Child Theme Structure Explained

PathPurposeNotes
style.cssTheme identity + parent link (Template:)Required
functions.phpHooks, filters, enqueues, includesRequired
inc/Modular PHP files (hooks/filters/setup)Recommended
assets/CSS/JS/imagesRecommended
templates/Template overridesUse sparingly
languages/i18n filesOptional unless translating
composer.jsonAutoloading for advanced buildsOptional

Why It Matters

  • Structure prevents "functions.php bloat" and makes code reviews easier.
  • A predictable layout supports multi-site reuse and CI/CD packaging.
  • Clean enqueues and modular includes reduce performance regressions.

How It Works

Your child theme is just a folder in wp-content/themes/. WordPress loads functions.php and style.css, and you can include additional PHP files from inc/ to keep logic organized.

flowchart LR
WP[WordPress] --> P[Parent theme]
P --> F[Child functions.php]
F --> INC[Child inc/* includes]
F --> ENQ[Asset enqueue]
WP --> TPL[Template selection]
TPL -->|child first| CT[Child templates/*]
CT -->|fallback| PT[Parent templates/*]

Practical Walkthrough

Step 1: Inspect the Current Child Theme Tree

inspect-child-theme-tree.sh
cd /var/www/html
ls -lah wp-content/themes/generatepress-child
ls -lah wp-content/themes/generatepress-child/inc 2>/dev/null || true
ls -lah wp-content/themes/generatepress-child/assets 2>/dev/null || true

Step 2: Create a Scalable Folder Layout

create-child-theme-structure.sh
cd /var/www/html
mkdir -p wp-content/themes/generatepress-child/inc
mkdir -p wp-content/themes/generatepress-child/assets/css
mkdir -p wp-content/themes/generatepress-child/assets/js
mkdir -p wp-content/themes/generatepress-child/templates

Step 3: Use a Simple Include Pattern

wp-content/themes/generatepress-child/functions.php
<?php

require_once get_stylesheet_directory() . '/inc/enqueue.php';
require_once get_stylesheet_directory() . '/inc/hooks.php';
require_once get_stylesheet_directory() . '/inc/filters.php';

Practical Examples

Example 1: Enqueue CSS/JS with Cache Busting

wp-content/themes/generatepress-child/inc/enqueue.php
<?php

add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_style(
'generatepress-child',
get_stylesheet_directory_uri() . '/assets/css/custom.css',
array(),
filemtime( get_stylesheet_directory() . '/assets/css/custom.css' )
);

wp_enqueue_script(
'generatepress-child',
get_stylesheet_directory_uri() . '/assets/js/custom.js',
array(),
filemtime( get_stylesheet_directory() . '/assets/js/custom.js' ),
true
);
} );
caution

Avoid large JS bundles in a theme. If you need an app-like frontend, consider a plugin or a build step with strict budgets.

Example 2: Keep Templates Minimal

If you override a template, document why and keep changes small.

audit-template-overrides.sh
cd /var/www/html
ls -lah wp-content/themes/generatepress-child/templates 2>/dev/null || true

Example 3: Put Hooks in inc/hooks.php

wp-content/themes/generatepress-child/inc/hooks.php
<?php

add_action( 'generate_after_header', function() {
echo '<div class="gp-child-after-header">After header hook (staging)</div>';
} );

Best Practices

PracticeWhy
Split logic into inc/Easier testing and review
Keep templates/ overrides rareParent updates become harder to merge
Use filemtime() for assets in stagingPrevents stale caches while iterating
Add a README.md with environment notesFaster onboarding

Troubleshooting

IssueCauseFix
Changes not loadingWrong file path in require_onceUse ls to verify paths and check PHP errors
CSS not updatingCache or missing cache-bustingPurge LSCache and verify filemtime() versions
Template override ignoredWrong filename/locationMirror parent path exactly and confirm which template renders

Hands-On

  1. Create inc/enqueue.php, inc/hooks.php, and inc/filters.php.
  2. Include them from functions.php.
  3. Add one small hook in inc/hooks.php and confirm it renders.
  4. Add a comment to README.md explaining why you chose hooks vs template overrides.

Quick Reference

child-theme-structure-cheatsheet.sh
cd /var/www/html/wp-content/themes/generatepress-child
ls
ls inc
ls assets

What's Next