Launch offer
Business website $150 USD Custom plugin $200 USD Ready in 5 days
Get a quote
WordPress Theme Development

WordPress Theme Development Complete Tutorial (96 Topics with Code)

Complete WordPress theme development tutorial covering template hierarchy, classic and block themes, Customizer, WooCommerce templates, security, SEO, accessibility, and wordpress.org release — with practical code examples.

This complete WordPress Theme Development tutorial covers 96 topics — from your first classic theme to template hierarchy, Customizer, block themes/FSE, WooCommerce templates, security, SEO, accessibility, and wordpress.org release.

Course roadmap

1. Introduction to WordPress Theme Development

A WordPress theme controls how your site looks and how templates render content. This series covers classic and block themes, template hierarchy, Customizer, WooCommerce templates, security, performance, and wordpress.org submission.

  1. Learn theme structure and hierarchy first.
  2. Build classic templates, then explore block themes.
  3. Finish with a complete professional theme project.

Learning path

Theme basics + hierarchy → templates/loop
Menus/widgets/customizer → assets/hooks
Block themes/FSE → WooCommerce
Security/SEO/a11y → release

2. What is a WordPress Theme?

Themes provide templates, styles, and theme supports. Plugins add features; themes should focus on design and display.

Theme vs plugin

Theme  → design, templates, presentation
Plugin → features, integrations, business logic
Best practice: keep feature logic in plugins when possible

3. WordPress Theme Architecture

WordPress selects templates via the hierarchy, runs The Loop, and prints content with template tags — all styled by your theme assets.

Request flow

Request → query → template hierarchy
→ header/content/sidebar/footer
→ enqueue CSS/JS → HTML output

4. WordPress Theme Types – Classic vs Block Themes

Classic themes use PHP templates (`header.php`, `single.php`). Block themes use `theme.json`, HTML templates, and the Site Editor.

Quick comparison

Classic: PHP templates, functions.php, Customizer
Block: templates/*.html, parts/, theme.json, FSE
Many sites still use classic or hybrid approaches

5. Installing WordPress for Theme Development

Use Local, XAMPP/WAMP, Laravel Valet, or Docker. Enable debugging and use a disposable database.

Dev setup tips

1. Local WP install
2. WP_DEBUG on
3. Starter theme folder in wp-content/themes
4. Test with sample content (WP-CLI or importer)

6. Creating Your First WordPress Theme

WordPress requires at least `style.css` (with header) and `index.php` for a classic theme to appear and run.

  1. Create `wp-content/themes/mytheme/`.
  2. Add `style.css` with a Theme Name header.
  3. Add `index.php`, then activate the theme.

Minimal theme files

mytheme/
  style.css
  index.php
  functions.php (recommended)

7. WordPress Theme File Structure

Keep templates at the root (or in standard folders), assets in `/assets`, and reusable parts in `/template-parts`.

Classic structure

mytheme/
  style.css
  functions.php
  index.php
  header.php / footer.php
  template-parts/
  assets/css|js|images
  languages/

8. style.css and Theme Header

The theme header in `style.css` is required. Main CSS can still be enqueued separately for performance.

Theme header

/*
Theme Name: Acme Theme
Theme URI: https://example.com/acme-theme
Author: Imtiyaj
Description: A clean starter theme.
Version: 1.0.0
Requires at least: 6.0
Requires PHP: 7.4
Text Domain: acme-theme
*/

9. functions.php in WordPress Themes

`functions.php` is the theme bootstrap file. Prefer small include files as the theme grows.

Theme setup sketch

<?php
add_action('after_setup_theme', function () {
    add_theme_support('title-tag');
    add_theme_support('post-thumbnails');
    register_nav_menus([
        'primary' => __('Primary Menu', 'acme-theme'),
    ]);
});

10. index.php in WordPress Themes

`index.php` is mandatory for classic themes and is the last fallback in the template hierarchy.

Basic index.php

<?php get_header(); ?>
<main>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <article <?php post_class(); ?>>
    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    <?php the_excerpt(); ?>
  </article>
<?php endwhile; else : ?>
  <p><?php esc_html_e('No posts found.', 'acme-theme'); ?></p>
<?php endif; ?>
</main>
<?php get_footer(); ?>

11. WordPress Template Hierarchy

More specific templates win (e.g. `single-book.php` before `single.php` before `index.php`). Mastering hierarchy is core theme skill.

Examples

Single post: single-$posttype-$slug.php → single-$posttype.php → single.php → singular.php → index.php
Page: page-$slug.php → page-$id.php → page.php → singular.php → index.php

12. Header and Footer Templates

Use `get_header()` and `get_footer()` so navigation, meta, and scripts stay consistent.

Include header/footer

<?php get_header(); ?>
<!-- page content -->
<?php get_footer(); ?>

13. header.php in WordPress Themes

Always call `wp_head()` before `</head>` and open the document structure cleanly.

header.php sketch

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
  <meta charset="<?php bloginfo('charset'); ?>">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<header class="site-header">
  <a href="<?php echo esc_url(home_url('/')); ?>"><?php bloginfo('name'); ?></a>
  <?php wp_nav_menu(['theme_location' => 'primary']); ?>
</header>

14. footer.php in WordPress Themes

`wp_footer()` is required so plugins/themes can print deferred scripts correctly.

footer.php sketch

<footer class="site-footer">
  <p>© <?php echo esc_html(date('Y')); ?> <?php bloginfo('name'); ?></p>
</footer>
<?php wp_footer(); ?>
</body>
</html>

15. sidebar.php in WordPress Themes

Sidebars display registered widget areas. Check `is_active_sidebar()` before printing markup.

sidebar.php

<?php if (is_active_sidebar('sidebar-1')) : ?>
<aside class="sidebar">
  <?php dynamic_sidebar('sidebar-1'); ?>
</aside>
<?php endif; ?>

16. single.php in WordPress Themes

`single.php` shows one post. You can specialize with `single-{post-type}.php`.

single.php loop

<?php get_header(); ?>
<?php while (have_posts()) : the_post(); ?>
  <article <?php post_class(); ?>>
    <h1><?php the_title(); ?></h1>
    <?php the_content(); ?>
  </article>
<?php endwhile; ?>
<?php get_footer(); ?>

17. page.php in WordPress Themes

Pages often omit post meta like date/author. Use `page-{slug}.php` for unique layouts.

page.php sketch

<?php get_header(); ?>
<?php while (have_posts()) : the_post(); ?>
  <h1><?php the_title(); ?></h1>
  <?php the_content(); ?>
<?php endwhile; ?>
<?php get_footer(); ?>

18. archive.php in WordPress Themes

Archives should show titles, excerpts, and pagination. Use `the_archive_title()` for headings.

Archive heading

<h1><?php the_archive_title(); ?></h1>
<?php the_archive_description(); ?>

19. search.php in WordPress Themes

`search.php` renders results for `?s=`. Show the query and helpful no-result UI.

Search title

<h1><?php printf(esc_html__('Results for: %s', 'acme-theme'), esc_html(get_search_query())); ?></h1>

20. 404.php in WordPress Themes

A good 404 page reduces bounce rate — include search form and navigation back to key pages.

404 sketch

<?php get_header(); ?>
<h1><?php esc_html_e('Page not found', 'acme-theme'); ?></h1>
<?php get_search_form(); ?>
<?php get_footer(); ?>

21. front-page.php vs home.php

`front-page.php` is for the front page (static or latest posts). `home.php` is for the blog posts index when a static front page is set.

When each loads

front-page.php → front of site
home.php → blog posts page
index.php → fallback for both

22. The WordPress Loop

The Loop checks `have_posts()`, sets up post data with `the_post()`, then prints tags like `the_title()` and `the_content()`.

Standard Loop

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
  <?php the_title('<h2>', '</h2>'); ?>
  <?php the_content(); ?>
<?php endwhile; endif; ?>

23. Custom WordPress Queries

Custom queries power homepages and modules. Always `wp_reset_postdata()` after a custom `WP_Query`.

Secondary loop habit

new WP_Query → loop → wp_reset_postdata()
Avoid query_posts() in themes

24. WP_Query in WordPress Themes

`WP_Query` is the main class for custom content queries in themes and plugins.

WP_Query example

$q = new WP_Query([
  'post_type' => 'post',
  'posts_per_page' => 3,
  'category_name' => 'news',
]);
while ($q->have_posts()) : $q->the_post();
  the_title('<h3>', '</h3>');
endwhile;
wp_reset_postdata();

25. Template Tags in WordPress

Template tags print or return common post/site data. Prefer escaped variants when returning HTML.

Common tags

the_title();
the_permalink();
the_excerpt();
the_post_thumbnail('large');
echo esc_html(get_the_date());

26. Conditional Tags in WordPress

Conditional tags detect context so one theme can adapt templates and classes per view.

Conditionals

if (is_front_page()) {
  // home layout
} elseif (is_singular('post')) {
  // single post
} elseif (is_search()) {
  // search results
}

27. Custom Page Templates

Add a Template Name header in a PHP file (or use `templates/` in newer structures) so editors can pick it.

Page template header

<?php
/**
 * Template Name: Full Width
 */
get_header();
// custom layout...
get_footer();

28. Child Themes in WordPress

Child themes override selected templates/styles while inheriting the parent. Great for client customizations.

  1. Create a child folder with `style.css` pointing to the parent `Template`.
  2. Enqueue parent+child styles properly in `functions.php`.
  3. Override only the templates you need.

Child style.css

/*
Theme Name: Acme Child
Template: acme-theme
Text Domain: acme-child
*/

29. Theme Customization API

Register panels, sections, settings, and controls so users can change colors, logos, and text with preview.

Customize register sketch

add_action('customize_register', function ($wp_customize) {
  $wp_customize->add_section('acme_colors', ['title' => 'Theme Colors']);
  $wp_customize->add_setting('acme_primary_color', ['default' => '#0f766e', 'sanitize_callback' => 'sanitize_hex_color']);
  $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'acme_primary_color', [
    'label' => 'Primary color',
    'section' => 'acme_colors',
  ]));
});

30. WordPress Customizer

Even with FSE growth, many classic themes still rely on Customizer settings for branding options.

Output setting

$color = get_theme_mod('acme_primary_color', '#0f766e');
echo '<style>:root{--acme-primary:' . esc_attr($color) . ';}</style>';

31. Theme Options

Too many options hurt UX and performance. Prefer sensible defaults and a small set of meaningful settings.

Options guidance

Prefer: Customizer / theme.json
Avoid: giant option panels with unused settings
Always: sanitize on save, escape on output

32. Navigation Menus in Themes

Menus are assigned in Appearance → Menus (or Site Editor for block themes).

Register + print menu

register_nav_menus(['primary' => __('Primary', 'acme-theme')]);
wp_nav_menu([
  'theme_location' => 'primary',
  'container' => 'nav',
  'menu_class' => 'primary-menu',
]);

33. Widget Areas and Sidebars

Widget areas let users place blocks/widgets without editing code.

register_sidebar

add_action('widgets_init', function () {
  register_sidebar([
    'name' => __('Sidebar', 'acme-theme'),
    'id' => 'sidebar-1',
    'before_widget' => '<section class="widget">',
    'after_widget' => '</section>',
    'before_title' => '<h3 class="widget-title">',
    'after_title' => '</h3>',
  ]);
});

34. Featured Images in Themes

Add theme support, then use `the_post_thumbnail()` with defined image sizes.

Thumbnails

add_theme_support('post-thumbnails');
add_image_size('acme-card', 600, 400, true);

if (has_post_thumbnail()) {
  the_post_thumbnail('acme-card');
}

35. Post Formats in WordPress Themes

Post formats are optional. Only enable formats you actually style.

Add support

add_theme_support('post-formats', ['video', 'quote', 'gallery']);
if (has_post_format('quote')) {
  // quote layout
}

36. Custom Post Types in Themes

Themes can style CPTs, but registering CPTs in a plugin keeps content safe if users switch themes.

Best practice

Register CPT/taxonomies in a plugin (or mu-plugin)
Theme provides single-{type}.php / archive-{type}.php templates

37. Custom Taxonomies in Themes

Use `taxonomy-{taxonomy}.php` templates and `the_terms()` for front-end output.

Term output

the_terms(get_the_ID(), 'genre', '<p>Genres: ', ', ', '</p>');

38. Custom Fields and Post Meta in Themes

Read meta with `get_post_meta()` and escape on output. Prefer registered meta / block bindings for modern workflows.

Display meta

$isbn = get_post_meta(get_the_ID(), '_acme_isbn', true);
if ($isbn) {
  echo '<p>ISBN: ' . esc_html($isbn) . '</p>';
}

39. Enqueue CSS and JavaScript in Themes

Enqueue on `wp_enqueue_scripts`, set dependencies/versions, and load JS in the footer when possible.

Enqueue theme assets

add_action('wp_enqueue_scripts', function () {
  wp_enqueue_style('acme-style', get_stylesheet_uri(), [], wp_get_theme()->get('Version'));
  wp_enqueue_script('acme-main', get_template_directory_uri() . '/assets/js/main.js', [], '1.0.0', true);
});

40. Responsive Theme Development

Use fluid layouts, responsive images, and mobile-first CSS. Test real devices and DevTools.

Responsive CSS idea

.grid { display: grid; gap: 1rem; }
@media (min-width: 768px) {
  .grid { grid-template-columns: 2fr 1fr; }
}

41. Mobile-Friendly WordPress Themes

Include a proper viewport meta tag via theme header markup and keep menus usable on mobile.

Viewport meta

<meta name="viewport" content="width=device-width, initial-scale=1">

42. Adding Google Fonts in WordPress Themes

Prefer self-hosted fonts for GDPR/performance. If using Google CSS, enqueue it and preconnect carefully.

Enqueue font stylesheet

wp_enqueue_style(
  'acme-fonts',
  'https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;700&display=swap',
  [],
  null
);

43. CSS and JavaScript Optimization

Don’t load slider scripts globally. Split assets by template when it helps.

Conditional enqueue

if (is_singular('post')) {
  wp_enqueue_script('acme-single');
}

44. WordPress Theme Hooks

Custom theme hooks (like `acme_before_content`) let child themes and plugins inject markup safely.

Theme action

do_action('acme_before_main');
// Child theme:
add_action('acme_before_main', function () {
  echo '<div class="notice">Hello</div>';
});

45. Actions and Filters in Themes

Themes commonly hook `after_setup_theme`, `wp_enqueue_scripts`, and content filters.

Excerpt filter

add_filter('excerpt_length', fn () => 30);
add_filter('excerpt_more', fn () => '…');

46. Adding Custom Functions in Themes

Prefix everything, avoid polluting the global namespace, and move helpers into `/inc` files.

Prefixed helper

function acme_posted_on() {
  echo '<time datetime="' . esc_attr(get_the_date(DATE_W3C)) . '">' . esc_html(get_the_date()) . '</time>';
}

47. Creating Reusable Template Parts

Template parts keep cards, meta rows, and entry headers DRY and easier to override in child themes.

Template part

get_template_part('template-parts/content', get_post_type());
// loads template-parts/content-post.php etc.

48. Gutenberg Compatibility in Themes

Add `align-wide`, editor styles, and color/font supports so backend matches frontend.

Editor supports

add_theme_support('align-wide');
add_theme_support('editor-styles');
add_editor_style('assets/css/editor.css');
add_theme_support('wp-block-styles');

49. Gutenberg Block Themes

Block themes replace many PHP templates with `templates/` and `parts/` HTML files powered by blocks.

Block theme folders

theme/
  style.css
  functions.php (optional/minimal)
  theme.json
  templates/index.html
  parts/header.html
  parts/footer.html

50. theme.json in WordPress

`theme.json` controls colors, typography, spacing, template parts, and block defaults for modern themes.

theme.json sketch

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 2,
  "settings": {
    "color": {
      "palette": [
        { "slug": "primary", "color": "#0f766e", "name": "Primary" }
      ]
    }
  }
}

51. Creating Custom Gutenberg Blocks for Themes

Prefer patterns and native blocks first. Add custom blocks only for truly custom UI.

Register from theme

add_action('init', function () {
  register_block_type(get_template_directory() . '/blocks/hero');
});

52. Full Site Editing (FSE)

FSE lets users modify site structure in Appearance → Editor using blocks and template parts.

FSE pieces

Site Editor
Templates + template parts
theme.json design system
Block patterns/styles

53. WordPress Block Patterns

Patterns speed up page building and keep design consistent across pages.

Register pattern

register_block_pattern('acme/hero', [
  'title' => 'Acme Hero',
  'categories' => ['featured'],
  'content' => '<!-- wp:heading -->n<h2>Hello</h2>n<!-- /wp:heading -->',
]);

54. Custom Block Styles

Block styles give users design variations without creating whole new blocks.

Register block style

register_block_style('core/button', [
  'name' => 'acme-outline',
  'label' => 'Outline',
]);

55. Dynamic Content in WordPress Themes

Dynamic content keeps titles, dates, and custom fields updated automatically as data changes.

Dynamic examples

The Loop + template tags
Blocks: site title, query loop, post date
Custom meta output in templates

56. AJAX in WordPress Themes

Localize script data (URL + nonce), verify on server, return HTML/JSON fragments.

Localize for AJAX

wp_localize_script('acme-main', 'AcmeTheme', [
  'ajaxUrl' => admin_url('admin-ajax.php'),
  'nonce' => wp_create_nonce('acme_theme'),
]);

57. REST API Integration in Themes

Use `/wp-json/` for headless-like pieces inside a traditional theme when useful.

Fetch posts

fetch('/wp-json/wp/v2/posts?per_page=3')
  .then((r) => r.json())
  .then((posts) => console.log(posts));

58. API Data in WordPress Themes

Fetch on the server when possible, cache with transients, and never expose secrets in frontend JS.

Transient-cached fetch

$data = get_transient('acme_api_data');
if (false === $data) {
  $res = wp_remote_get('https://api.example.com/data', ['timeout' => 10]);
  $data = is_wp_error($res) ? [] : json_decode(wp_remote_retrieve_body($res), true);
  set_transient('acme_api_data', $data, 15 * MINUTE_IN_SECONDS);
}

59. Forms in WordPress Themes

For complex forms, prefer plugins (or blocks). For simple theme forms, secure POST handling is mandatory.

Form nonce field

<?php wp_nonce_field('acme_contact', 'acme_contact_nonce'); ?>

60. Custom Search Functionality

Override `searchform.php` and use `pre_get_posts` carefully to include CPTs when needed.

searchform.php sketch

<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
  <label><span class="screen-reader-text">Search</span>
  <input type="search" name="s" value="<?php echo esc_attr(get_search_query()); ?>"></label>
  <button type="submit">Search</button>
</form>

61. Pagination in WordPress Themes

Use `the_posts_pagination()` for accessible archive pagination.

Posts pagination

the_posts_pagination([
  'mid_size' => 2,
  'prev_text' => __('Previous', 'acme-theme'),
  'next_text' => __('Next', 'acme-theme'),
]);

62. Breadcrumbs in WordPress Themes

Build a small helper or integrate with Yoast/Rank Math breadcrumb APIs when available.

Simple breadcrumb idea

echo '<nav class="breadcrumbs"><a href="' . esc_url(home_url('/')) . '">Home</a> / ';
if (is_singular()) {
  echo esc_html(get_the_title());
}
echo '</nav>';

63. Related Posts in WordPress Themes

Query by shared terms, exclude the current post, and limit results for performance.

Related by category

$cats = wp_get_post_categories(get_the_ID());
$related = new WP_Query([
  'category__in' => $cats,
  'post__not_in' => [get_the_ID()],
  'posts_per_page' => 3,
]);

64. Social Sharing Integration

Simple share URLs are lightweight. If using SDKs, load them conditionally.

Share links

$url = rawurlencode(get_permalink());
$title = rawurlencode(get_the_title());
echo '<a href="https://twitter.com/intent/tweet?url=' . $url . '&text=' . $title . '">Share</a>';

65. WooCommerce Theme Integration

Add `add_theme_support('woocommerce')` and provide overrides only where design needs them.

Declare support

add_action('after_setup_theme', function () {
  add_theme_support('woocommerce');
  add_theme_support('wc-product-gallery-zoom');
});

66. WooCommerce Template Overrides

Copy only needed templates into `yourtheme/woocommerce/…` and keep them updated across Woo releases.

Override path example

yourtheme/woocommerce/single-product.php
yourtheme/woocommerce/cart/cart.php
Prefer hooks before full template copies

67. Custom WooCommerce Shop Page

Adjust products per page/columns via filters and style `content-product.php` carefully.

Products per page

add_filter('loop_shop_per_page', fn () => 12);

68. Custom Product Page

WooCommerce hooks (`woocommerce_single_product_summary`) often beat copying entire templates.

Move product hook

remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20);
add_action('woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 35);

69. Custom Cart and Checkout Design

Avoid removing required checkout fields casually. Focus on typography, spacing, and trust cues.

Design tips

Clear totals
Mobile-first form layout
Visible validation errors
Minimal distractions on checkout

70. Theme Security Best Practices

Themes are still PHP apps — treat every output and request carefully.

Security checklist

- Escape on output
- Sanitize on input
- Nonces for forms/AJAX
- Prefix functions
- No remote code loading

71. Data Sanitization and Escaping in Themes

Use `esc_html`, `esc_attr`, `esc_url`, and `wp_kses_post` according to context.

Escape in templates

<h1><?php echo esc_html(get_the_title()); ?></h1>
<a href="<?php echo esc_url(get_permalink()); ?>">Read</a>

72. Nonces and Security in Themes

Nonces verify intent; capabilities authorize users. You need both for state-changing actions.

Verify nonce

if (! isset($_POST['_wpnonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'acme_theme_action')) {
  wp_die('Invalid request');
}

73. WordPress Coding Standards for Themes

Use WPCS/PHPCS, consistent indentation, and internationalize strings.

Standards focus

Prefixing
i18n wrappers
Escaping discipline
Readable template logic

74. Theme Performance Optimization

Fewer queries, smaller JS/CSS, and proper image sizes matter more than micro-tweaks.

Perf checklist

- Conditionally enqueue assets
- Avoid heavy query_posts hacks
- Lazy-load images
- Limit Google Fonts weights
- Cache expensive remote calls

75. WordPress Caching and Themes

Avoid personalized markup in fully cached pages without ESI/AJAX strategies.

Transient for menus-like data

$html = get_transient('acme_footer_html');
if (false === $html) {
  ob_start();
  // render expensive section
  $html = ob_get_clean();
  set_transient('acme_footer_html', $html, HOUR_IN_SECONDS);
}
echo $html; // phpcs:ignore if trusted generated HTML

76. SEO-Friendly Theme Development

Themes should output valid structure, fast pages, and support title-tag/canonical plugins cleanly.

SEO basics in themes

One H1 per page
title-tag support
Descriptive alt text
Fast LCP image strategy
No cloaking/hidden spam

77. Accessibility in WordPress Themes

Follow WCAG principles. Use skip links, focus styles, and meaningful labels.

Skip link

<a class="skip-link screen-reader-text" href="#main">Skip to content</a>
<main id="main">

78. Translation and Internationalization in Themes

Load the theme textdomain and wrap strings with `__()`, `esc_html__()`, `_e()`, etc.

Load textdomain

add_action('after_setup_theme', function () {
  load_theme_textdomain('acme-theme', get_template_directory() . '/languages');
});
esc_html_e('Read more', 'acme-theme');

79. Multilingual Theme Compatibility

Avoid hardcoded language strings in templates and test language switchers with your header/menu design.

Compatibility tips

Translate all strings
Support RTL when possible
Don’t hardcode home URLs with language paths
Test menu assignments per language

80. Browser Compatibility Testing

Use progressive enhancement. Avoid depending on experimental CSS without fallbacks.

Test checklist

Latest Chrome/Firefox/Safari/Edge
iOS Safari + Android Chrome
Reduced motion / zoom 200%
No console JS errors

81. WordPress Version Compatibility for Themes

Use “Requires at least” / “Tested up to” accurately in style.css and readme.

Header fields

Requires at least: 6.0
Tested up to: 6.7

82. PHP Version Compatibility for Themes

Declare `Requires PHP` and run smoke tests on that version.

Requires PHP

Requires PHP: 7.4

83. Debugging WordPress Themes

Locate wrong templates, missing `wp_head/wp_footer`, and unescaped output early.

Debug helpers

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
// Temporary: echo get_template();
// Use Query Monitor for hooks/queries

84. Theme Unit Testing

Combine PHPUnit for helpers with manual/theme check tools for templates and a11y.

Testing approach

Unit test pure helpers
Theme Check plugin / WP Theme Review sniff
Manual template hierarchy QA

85. Theme Documentation

Include a clear README, changelog, and screenshots. Document child-theme guidance.

Docs checklist

Installation
Menus/widgets/logo setup
Template list
Changelog
Support link

86. Creating Free and Pro Themes

Keep free themes useful. Put advanced features in a pro plugin/upsell when possible.

Freemium tips

Free: solid design + core templates
Pro: extra patterns, demos, premium support
Never lock user content behind license

87. Theme Licensing

WordPress.org requires GPL-compatible licensing for PHP (and typically bundled assets guidelines).

License header

License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

88. Theme Update System

Keep versions consistent across style.css and packaging. Provide upgrade notes for breaking changes.

Update channels

wordpress.org theme directory
or commercial dashboard/updater API

89. Preparing a Theme for WordPress.org

Pass Theme Check, remove placeholder content issues, and follow the handbook requirements.

Prep checklist

GPL license
No errors/warnings in Theme Check
Proper screenshot.png
Accessible & secure templates
Complete readme.txt

90. readme.txt and Theme Assets

Include description, tags, and changelog. Provide a 1200×900 `screenshot.png`.

Assets

screenshot.png (required)
readme.txt
Optional marketing assets for your own site

91. WordPress.org Theme Review Guidelines

Avoid bundled plugin required installs, hidden admin menus, and security violations.

Common issues

- Missing escaping
- Undeclared theme supports
- Including plugin-like options frameworks incorrectly
- Trademark/branding problems

92. Git and Theme Development Workflow

Keep `main` releasable, open PRs for features, and tag versions on release.

Workflow

feature branches → PR → main
tag v1.0.0 on release
ignore node_modules / vendor build junk carefully

93. Theme Version Management

Follow semver-inspired versioning and sync style.css version with release packages.

Release bump list

style.css Version
readme.txt Stable tag / Changelog
package.json (if used)
Git tag

94. Theme Deployment

Use Git deploy, CI artifacts, or SFTP carefully. Always test on staging first.

Deploy checklist

1. Build assets
2. Smoke test templates
3. Deploy to staging
4. Verify menus/widgets/Customizer
5. Deploy to production + clear caches

95. WordPress Theme Development Interview Questions

Be ready to explain template hierarchy, child themes, enqueueing, and classic vs FSE.

Sample Q&A

Q: Why is index.php required?
A: Final fallback template for classic themes.

Q: front-page.php vs home.php?
A: Front page vs posts index.

Q: Escape where?
A: On output, by context.

Q: Child theme benefit?
A: Safe customizations across parent updates.

96. Final Project – Complete Professional WordPress Theme

Ship a polished classic or block theme with hierarchy templates, menus/widgets, responsive design, accessibility, i18n, and release-ready documentation.

  1. Choose classic or block theme approach.
  2. Implement core templates and design system.
  3. Harden security/a11y/performance.
  4. Package with readme and screenshot.

Final project scope

1. style.css + functions.php setup
2. header/footer/index/single/page/archive/search/404
3. Menus + sidebar + featured images
4. Enqueued CSS/JS + responsive layout
5. Customizer logo/colors
6. Template parts + clean Loop
7. Optional WooCommerce support
8. Escaping/i18n + readme/screenshot
9. Accessibility + performance pass

Starter setup snippet

<?php
add_action('after_setup_theme', function () {
  add_theme_support('title-tag');
  add_theme_support('post-thumbnails');
  add_theme_support('html5', ['search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script']);
  register_nav_menus(['primary' => __('Primary', 'acme-theme')]);
  load_theme_textdomain('acme-theme', get_template_directory() . '/languages');
});

Conclusion

You now have a full WordPress theme path: architecture, templates, The Loop, Customizer, block themes, WooCommerce integration, and release workflows. Build the final professional theme project to turn the lessons into a portfolio-ready result.

Leave a reply

Your email address will not be published. Required fields are marked *