Frontmatter

How to convert an HTML design to WordPress PHP templates

The developer's approach to converting a static HTML/CSS design into WordPress-compatible PHP templates - partials, page templates, variable wiring, and how to skip the manual rewrite.

When a static design needs to become a WordPress theme, the work is mostly mechanical. The layout already exists. The job is to translate it into PHP files and wire in data without breaking the structure.

The traditional approach - and why it breaks down

The usual workflow is to split index.html into header.php, footer.php, and index.php, then replace static strings with WordPress template tags by hand.

That works for tiny sites. It breaks down as soon as the design gets more complex. Variables get named differently from page to page, optional blocks get missed, and the backend developer has to reverse-engineer what the theme expects.

What a WordPress PHP theme needs

The minimum files are predictable:

  • style.css - theme declaration header plus your CSS
  • index.php - the main fallback template
  • header.php / footer.php - shared structure
  • page-{slug}.php - per-page templates
  • partials/ - reusable includes

Solo generates the rendering layer. Your WordPress developer wires the data.

Generated by SoloWritten by your WordPress developer
PHP partials (partials/hero.php, etc.)functions.php
Layout (layouts/base.php)WordPress hooks and filters
Page template stubsget_field() / WP_Query calls
manifest.jsonMenu registration
INTEGRATION.mdPlugin integration (ACF, Yoast, etc.)

The variable contract - $fm

The generated templates use a simple contract:

  • $fm['props'] - template-specific values
  • $fm['site'] - global site data
  • $fm['page'] - page-level metadata
  • $fm['data'] - loops and shared collections

That contract is what lets the partials stay clean. The partial renders what it receives. It does not fetch its own data.

<?php // partials/hero.php ?>
<section class="hero">
  <h1><?= htmlspecialchars($fm['props']['headline']) ?></h1>
  <?php if (!empty($fm['props']['sub'])): ?>
    <p><?= htmlspecialchars($fm['props']['sub']) ?></p>
  <?php endif; ?>
</section>

Why structure your design in Astro first

Static HTML has no typed props and no enforced contract. Astro gives you both. A constrained Astro project tells you exactly which fields are required, which are optional, and how the structure is composed before the conversion starts.

That makes the PHP output predictable. It also makes the integration doc useful, because the backend developer is wiring a contract instead of guessing at intent.

Run solo-check first if you want to validate the project before you generate the PHP output.

Running Solo

frontmatter solo:build --adapter php

Use Frontmatter Solo when you want the generated WordPress render pack - partials, layouts, page templates, manifest, and INTEGRATION.md - without rewriting the frontend by hand.