Capstone — Building a Custom Theme With a Custom Post Type
WordPress Intermediate/Advanced
Chapter 10 · Capstone — Building a Custom Theme With a Custom Post Type
Nine chapters have built the pieces, one at a time. This capstone assembles them into one real, working theme — a portfolio site with a custom post type, a widget area, and a genuinely secured contact form — closing both this course and the full 20-chapter WordPress track.
1. Theme File Structure
style.css's header, index.php, and header.php/footer.php (correctly calling wp_head()/wp_footer()) follow exactly the structure Chapter 1 established.
2. The "Project" Custom Post Type & Taxonomy
Directly from Chapter 4, with Chapter 6's show_in_rest included from the start — this project type is REST-accessible immediately, not bolted on later.
3. Displaying Projects — Template Hierarchy & The Loop
Per Chapter 2's own hierarchy, this file is automatically selected for the projects archive with no further wiring required. the_post_thumbnail() deliberately preserves the width/height attributes Chapter 9 named as a real CLS protection.
4. A Widget Area
register_sidebar(), hooked to its own dedicated widgets_init action, defines the widget area WordPress Fundamentals 7 covered purely from the site-owner side — this is what actually makes a widget area exist for a theme to offer in the first place.
5. A Properly Secured Contact Form
Chapter 8's own two-part defense, fully assembled: the nonce is checked before anything else runs, and both the submitted values and the final email output are escaped. This is the single most security-sensitive piece of the entire capstone, and deliberately the one built with the most care.
6. Enqueuing the Theme's Own Assets
Chapter Attribution
| Piece | Source chapter |
|---|---|
| Theme file structure, wp_head()/wp_footer() | Chapter 1 |
| archive-project.php selected automatically | Chapter 2 |
| The Loop displaying projects | Chapter 3 |
| The "project" post type and "project_type" taxonomy | Chapter 4 |
| Contact form handled via a hooked action | Chapter 5 |
| show_in_rest on the project post type | Chapter 6 |
| Properly enqueued styles/scripts with a jQuery dependency | Chapter 7 |
| Nonce verification and output escaping on the contact form | Chapter 8 |
| Preserved thumbnail dimensions, footer-loaded scripts | Chapter 9 |
Honest Scope Note
- No WooCommerce/e-commerce — reserved for a still-outstanding, deliberately-not-yet-scoped third WordPress course
- No Full Site Editing/block-theme implementation — this capstone builds a classic PHP-template theme, matching this course's own focus throughout
- No automated testing or version-controlled deployment workflow
- Production deployment itself is Setting Up a Web Server on Debian's own territory, not repeated here
Hands-On Exercises
Explain why the contact form's nonce check happens before the sanitize_text_field() calls, rather than after, referencing this chapter's own Chapter 8 material.
📄 View solutionExplain why the_post_thumbnail() is specifically called out in this chapter as preserving width/height "automatically," and why that matters for this capstone's own Chapter 9 attribution.
📄 View solutionExplain why this capstone's own closing note says a real production theme would likely be a child theme instead, and why the capstone deliberately doesn't build it that way.
📄 View solutionChapter 10 Quick Reference — Course & Track Complete
- A real theme combining theme anatomy, the template hierarchy, the Loop, a custom post type + taxonomy, the REST API, proper enqueuing, security hardening, and performance practice
- The contact form is the single most security-sensitive piece — nonce check first, then sanitize input, then escape output
- register_sidebar(), hooked to widgets_init, is what makes a widget area exist for a theme to offer
- WooCommerce/e-commerce is deliberately out of scope — a plausible future third WordPress course, not yet planned in detail
- This completes both WordPress Fundamentals and WordPress Intermediate/Advanced — the full 20-chapter track