Build classic and block WordPress themes from scratch: the template hierarchy, The Loop, the_title() and the_content(), template parts, menus, the Customizer, child themes and theme.json.
Lessons
add_theme_support() tells WordPress which optional features your theme is ready to handle — such as letting WordPress manage the page title, enabling featured images, or letting the site owner upload a logo.
Features are opt-in so that old themes keep working. Each call is a promise: "my templates will display this properly."
<?php
function gdc_starter_setup() {
// WordPress prints a correct <title> inside wp_head().
add_theme_support( 'title-tag' );
// Adds the Featured Image box to posts and pages.
add_theme_support( 'post-thumbnails' );
// RSS feed links in <head>.
add_theme_support( 'automatic-feed-links' );
// Modern, valid markup for these core features.
add_theme_support(
'html5',
array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script', 'navigation-widgets' )
);
// A logo the site owner uploads in Appearance → Customize.
add_theme_support(
'custom-logo',
array(
'height' => 80,
'width' => 240,
'flex-height' => true,
'flex-width' => true,
)
);
// Block editor features.
add_theme_support( 'wp-block-styles' );
add_theme_support( 'align-wide' );
add_theme_support( 'responsive-embeds' );
add_theme_support( 'editor-styles' );
add_editor_style( 'assets/css/editor.css' );
}
add_action( 'after_setup_theme', 'gdc_starter_setup' );| Feature | What changes | Your job in templates |
|---|---|---|
title-tag | WordPress outputs the <title> | Remove any hard-coded <title>. |
post-thumbnails | Featured Image panel appears | Print it with the_post_thumbnail() (lesson 19). |
custom-logo | Logo upload in the Customizer | Print it with the_custom_logo(). |
html5 | Search forms, comments and galleries use semantic HTML5 | Nothing — it is markup only. |
align-wide | Wide and full-width alignment options in the editor | Style .alignwide and .alignfull. |
responsive-embeds | Videos keep their aspect ratio | Nothing. |
editor-styles | The editor loads your stylesheet | Write editor.css so the editor looks like the front end. |
<div class="site-branding">
<?php if ( has_custom_logo() ) : ?>
<?php the_custom_logo(); ?>
<?php else : ?>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a>
<?php endif; ?>
</div>the_custom_logo() outputs a linked image with the correct alt text and srcset. The fallback to the site name means the header never ends up empty.
With editor-styles on, assets/css/editor.css is loaded into the block editor and automatically scoped so it only styles the content area:
/* assets/css/editor.css */
body {
font-family: "Inter", system-ui, sans-serif;
font-size: 18px;
line-height: 1.7;
color: #1e293b;
}
h1, h2, h3 {
font-family: "Syne", system-ui, sans-serif;
line-height: 1.2;
}
a {
color: #6c63ff;
}Tip: When the editor looks like the published page, clients make far fewer "it looked different when I wrote it" support requests.
current_theme_supports( 'post-thumbnails' ) returns whether a feature is on. Plugins use it to adapt to your theme — another reason to declare features honestly.
<title> from header.php and confirm the browser tab still shows the right title.editor.css and compare a post in the editor and on the front end.In accordance with Section 6 & Section 7 of the DPDP Act 2023, third-party analytics and marketing trackers are strictly gated behind your affirmative consent. You may withdraw consent at any time under Section 6(4).
Essential for session authentication (ci_session), Cross-Site Request Forgery security (csrf_cookie_name), and Cloudflare DDoS/bot prevention. Cannot be disabled.
Gated under DPDP Section 7. Allows Google Analytics 4 (Google Consent Mode v2) to measure aggregate, anonymized tool usage.
Enables browser local storage to preserve your theme selection (dark/light mode) and code editor layout between visits.
Used to display developer sponsorships and native tool partner notices.