Classic theme structure
Skill Lonsdale201/wp-agent-skills/theme-development/classic-theme-structure
Build or audit a modern classic PHP WordPress theme structure for WP 7.0 without FSE/block-theme assumptions. Covers required `style.css` + `index.php`, `functions.php` as bootstrap, `after_setup_theme`, `wp_enqueue_scripts`, `get_theme_file_uri/path`, `wp_head`, `wp_body_open`, `wp_footer`, recommended `assets/`, `inc/`, `template-parts/`, `page-templates/`, `languages/`, child-theme-safe paths, theme supports, menus, sidebars, and what belongs in a plugin instead of a theme. Use when scaffolding/reviewing a non-FSE theme, converting static HTML to a theme, or deciding where theme files/hooks belong.From its SKILL.md
npx -y skills add Lonsdale201/wp-agent-skills --skill classic-theme-structureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.1 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it
Classic Theme Structure
Use this when creating or reviewing a classic PHP WordPress theme. This skill deliberately avoids FSE/block-theme architecture: no templates/*.html as the primary rendering layer, no Site Editor assumptions, and no Gutenberg/block development workflow.
The target is a secure, maintainable classic theme for WP 7.0.
When to Use This Skill
- Scaffolding a new classic theme.
- Converting static HTML/CSS into a WordPress theme.
- Reviewing a theme folder for bad structure, missing hooks, direct asset tags, or business logic in
functions.php. - The work mentions
style.css,index.php,functions.php,header.php,footer.php,template-parts,after_setup_theme,wp_enqueue_scripts, or classic theme files.
Runtime Minimum vs Practical Minimum
WordPress recognizes a classic theme with:
style.cssin the theme root, with a valid theme header.index.phpin the theme root, as the final template fallback.
For real projects, also include:
functions.phpfor bootstrap/hooks.header.phpandfooter.php.404.php,page.php,single.php,archive.php,search.php.comments.phpif comments are supported.screenshot.pngfor admin display and distribution.
Do not create a block theme by accident. A classic theme's fallback template is root index.php, not templates/index.html.
Recommended Folder Layout
mytheme/
|-- style.css
|-- functions.php
|-- index.php
|-- header.php
|-- footer.php
|-- 404.php
|-- page.php
|-- single.php
|-- archive.php
|-- search.php
|-- comments.php
|-- screenshot.png
|-- assets/
| |-- css/
| |-- js/
| |-- images/
| `-- fonts/
|-- inc/
| |-- setup.php
| |-- enqueue.php
| |-- template-tags.php
| |-- template-functions.php
| `-- customizer.php
|-- template-parts/
| |-- content.php
| |-- content-page.php
| |-- content-none.php
| `-- content-search.php
|-- page-templates/
| `-- full-width.php
`-- languages/
Keep root templates thin. Put repeatable PHP helpers in inc/, repeatable markup in template-parts/, and static assets in assets/.
style.css Header
style.css must live in the theme root. WordPress parses its header through WP_Theme.
/*
Theme Name: MyTheme
Theme URI: https://example.com/mytheme
Author: Example Team
Description: A classic PHP WordPress theme.
Version: 1.0.0
Requires at least: 7.0
Tested up to: 7.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: mytheme
Domain Path: /languages
*/
For a child theme, add Template: parent-theme-folder-name.
functions.php as Bootstrap
functions.php loads on frontend and admin. In a child theme, the child functions.php loads before the parent functions.php.
Use it as a bootstrap, not as a 2,000-line application file:
<?php
/**
* Theme bootstrap.
*
* @package MyTheme
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'MYTHEME_VERSION', wp_get_theme()->get( 'Version' ) );
require_once get_template_directory() . '/inc/setup.php';
require_once get_template_directory() . '/inc/enqueue.php';
require_once get_template_directory() . '/inc/template-tags.php';
require_once get_template_directory() . '/inc/template-functions.php';
Use get_template_directory() for parent-theme code includes. Use get_theme_file_path() when child themes should be able to override a file.
Do not put custom post types, business rules, payment logic, CRM sync, or data migrations in a theme. If the feature should survive a theme switch, build a plugin.
Theme Setup
Register theme support and theme-owned features on after_setup_theme.
<?php
/**
* Setup theme defaults.
*
* @package MyTheme
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'after_setup_theme', 'mytheme_setup' );
function mytheme_setup(): void {
load_theme_textdomain( 'mytheme', get_template_directory() . '/languages' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'automatic-feed-links' );
add_theme_support(
'html5',
array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'script', 'style' )
);
register_nav_menus(
array(
'primary' => __( 'Primary Menu', 'mytheme' ),
'footer' => __( 'Footer Menu', 'mytheme' ),
)
);
}
Register widget areas on widgets_init, not in global scope:
add_action( 'widgets_init', 'mytheme_register_sidebars' );
function mytheme_register_sidebars(): void {
register_sidebar(
array(
'name' => __( 'Sidebar', 'mytheme' ),
'id' => 'sidebar-1',
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h2 class="widget-title">',
'after_title' => '</h2>',
)
);
}
Assets
Never hardcode <link> or <script> tags in templates. Enqueue assets on wp_enqueue_scripts.
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_assets' );
function mytheme_enqueue_assets(): void {
wp_enqueue_style(
'mytheme-style',
get_stylesheet_uri(),
array(),
MYTHEME_VERSION
);
$script = 'assets/js/main.js';
$path = get_theme_file_path( $script );
wp_enqueue_script(
'mytheme-main',
get_theme_file_uri( $script ),
array(),
file_exists( $path ) ? filemtime( $path ) : MYTHEME_VERSION,
array(
'strategy' => 'defer',
'in_footer' => true,
)
);
}
Use child-theme-safe helpers:
| Need | Function |
|---|---|
| Active theme stylesheet URL | get_stylesheet_uri() |
| Child override first, then parent URL | get_theme_file_uri( 'assets/js/main.js' ) |
| Child override first, then parent path | get_theme_file_path( 'inc/file.php' ) |
| Parent theme URL only | get_parent_theme_file_uri( 'assets/css/base.css' ) |
| Parent theme path only | get_template_directory() . '/inc/file.php' |
Required Hooks in Templates
header.php must include:
language_attributes()on<html>.bloginfo( 'charset' )or equivalent charset meta.wp_head()before</head>.body_class()on<body>.wp_body_open()immediately after<body>.
footer.php must include wp_footer() before </body>.
Without these, plugins and WordPress core cannot enqueue scripts/styles, inject metadata, render admin bar assets, or hook accessibility integrations correctly.
Structural Rules
- Prefix global functions with the theme slug, or use a unique namespace for non-template helper code.
- Do not close PHP-only files with
?>. - Use lowercase, hyphenated file names for ordinary files.
- Use
require_oncefor mandatory includes. - Use
get_template_part( 'template-parts/content', 'page', $args )instead of global variables for reusable markup. - Keep templates focused on presentation. Query manipulation belongs in hooks such as
pre_get_posts, and portable site features belong in plugins.
What This Skill Does Not Cover
- Block themes, FSE,
theme.json, block templates, block patterns, and Site Editor workflows. - Deep template hierarchy decisions; use
classic-template-hierarchy. - Detailed escaping/security review; use
classic-theme-security-standardsandwp-security-audit.
References
- Official documentation: https://developer.wordpress.org/themes/classic-themes/
- Official documentation: https://developer.wordpress.org/themes/releasing-your-theme/required-theme-files/
- Official documentation: https://developer.wordpress.org/themes/classic-themes/basics/main-stylesheet-style-css/
- Official documentation: https://developer.wordpress.org/themes/core-concepts/custom-functionality/
- Official documentation: https://developer.wordpress.org/themes/core-concepts/including-assets/
- Verified source paths:
wp-includes/template-loader.phpwp-includes/template.phpwp-includes/general-template.phpwp-includes/theme.phpwp-includes/link-template.phpwp-includes/functions.wp-scripts.phpwp-includes/functions.wp-styles.phpwp-includes/class-wp-theme.phpwp-content/themes/storefront/wp-content/themes/generatepress/
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.