WordPressWordPressTheme DevelopmentPHPWeb DevelopmentCMS

WordPress Theme Development: Build a Custom Theme from Scratch

Step-by-step guide to building a custom WordPress theme — PHP templates, theme.json, block patterns, and best practices for 2025.

Abdur Razzak

Abdur Razzak

Full-Stack Web Developer

April 7, 2024 9 min read

Classic Themes vs Block Themes in 2025

WordPress now offers two theme paradigms. Classic themes use PHP template files (header.php, page.php, single.php) and enqueue stylesheets with functions.php. Block themes (Full Site Editing) use HTML template files with block markup and a theme.json file for global design settings. For new projects in 2025, I recommend block themes — they give clients more editing flexibility and are where WordPress development is heading.

Setting Up the Theme Structure

Create a folder in wp-content/themes/your-theme-name/. A minimal theme needs: style.css (with the Theme Name header comment), index.php or templates/index.html for block themes, and functions.php. For a classic theme, add header.php, footer.php, page.php, single.php, and archive.php for the main template hierarchy. Register your theme in style.css with the proper comment block so WordPress recognizes it.

theme.json: Design System for Block Themes

The theme.json file is the heart of a block theme. It defines your color palette, font sizes, spacing scale, and layout constraints. These settings are available to the block editor in the site customizer, giving clients control over their design without touching code. Define your brand colors as named presets, set up a fluid typography scale, and lock down maximum content width so layouts stay consistent.

Custom Post Types and Fields

For portfolio sites, directories, or real estate, you need custom post types beyond posts and pages. Register them in functions.php using register_post_type(). For custom fields (extra data per post), use the Advanced Custom Fields (ACF) plugin for non-developers, or register_meta() with the REST API enabled for headless WordPress setups. Always create templates for your custom post types in the theme template hierarchy.

Performance: Enqueuing Assets Correctly

Never add stylesheets or scripts directly to header.php. Use wp_enqueue_style() and wp_enqueue_script() in your theme's functions.php to register and enqueue assets properly. This allows WordPress and plugins to manage load order and dependencies. Add the in_footer parameter to scripts where possible to defer them, improving LCP. For block themes, only enqueue what the full site editing system doesn't already handle.

Security Best Practices

WordPress themes are frequent attack vectors. Always escape output with esc_html(), esc_url(), esc_attr(), and wp_kses() before rendering dynamic data. Use nonces for form submissions and AJAX requests. Never use $_POST, $_GET, or $_REQUEST directly — always validate and sanitize. Keep WordPress, themes, and plugins updated. Use a security plugin like Wordfence for monitoring and blocking malicious traffic.

Share this article

All posts
#WordPress#Theme Development#PHP#Web Development#CMS
Abdur Razzak — Full Stack Web Developer
⭐ Top Rated

Upwork Top Rated Developer

Work With a Developer Clients Trust