W
WordPress SOPKnowledge Base
Search
← All topics

WordPress Theme Development

runnable

Complete pattern for custom WordPress theme setup including style.css header, functions.php essentials, script enqueueing, widget registration, and menu setup.

developmentthemefunctions-phpenqueue
Agent trigger phrases: wordpress theme development · custom wordpress theme · functions.php setup · wp_enqueue_scripts · wordpress theme from scratch

Custom WordPress themes require a specific file structure and setup sequence. Build on a starter theme (GeneratePress, Kadence, or Underscores) rather than from blank when possible.

Required Files

my-theme/
├── style.css          # Theme header + base styles
├── functions.php      # Theme setup, enqueue, hooks
├── index.php          # Fallback template
├── header.php         # Site header
├── footer.php         # Site footer
├── page.php           # Default page template
├── single.php         # Single post template
├── archive.php        # Archive/taxonomy template
├── 404.php            # 404 template
└── template-parts/    # Reusable partials

style.css Theme Header

/*
Theme Name: My Custom Theme
Theme URI: https://example.com/theme
Author: Your Name
Author URI: https://example.com
Description: Custom theme for [client]
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.5
Requires PHP: 8.1
License: GPL v2 or later
Text Domain: my-theme
*/

functions.php Essentials

<?php
function mytheme_setup() {
    add_theme_support('title-tag');
    add_theme_support('post-thumbnails');
    add_theme_support('html5', ['search-form', 'comment-form', 'gallery', 'caption']);
    add_theme_support('responsive-embeds');
    add_theme_support('editor-styles');

    register_nav_menus([
        'primary' => __('Primary Menu', 'my-theme'),
        'footer'  => __('Footer Menu', 'my-theme'),
    ]);

    add_image_size('hero', 1920, 800, true);
    add_image_size('card', 400, 300, true);
}
add_action('after_setup_theme', 'mytheme_setup');

function mytheme_scripts() {
    wp_enqueue_style('mytheme-style', get_stylesheet_uri(), [], '1.0.0');
    wp_enqueue_style('mytheme-main', get_template_directory_uri() . '/assets/css/main.css', [], '1.0.0');

    wp_enqueue_script('mytheme-main', get_template_directory_uri() . '/assets/js/main.js', ['jquery'], '1.0.0', true);

    wp_localize_script('mytheme-main', 'mythemeAjax', [
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce'   => wp_create_nonce('mytheme_nonce'),
    ]);
}
add_action('wp_enqueue_scripts', 'mytheme_scripts');

function mytheme_widgets() {
    register_sidebar([
        'name'          => __('Sidebar', 'my-theme'),
        'id'            => 'sidebar-1',
        'before_widget' => '<div class="widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h3 class="widget-title">',
        'after_title'   => '</h3>',
    ]);
}
add_action('widgets_init', 'mytheme_widgets');

Version Control

Track theme with Git. Initialize in the theme folder (wp-content/themes/my-theme/), not the WordPress root. Add node_modules/, *.log, and *.DS_Store to .gitignore.