Rules on creating patterns in php for the WordPress block editor

Creating patterns programmatically for a WordPress theme using blocks is incredibly hard and frustrating for so many reasons. Even AIs struggle – and they have access to so much more than we do, so with the help of GPT 5 and days and days of struggle (back and forth coding) it came up with this. I hope it helps.

1. File Structure

  • Each pattern lives in its own PHP file inside /patterns/.
  • File must start with a docblock header:
/**
 * Title: My Pattern Title
 * Slug: my-theme/my-pattern
 * Categories: text, theme
 * Description: Short description of the pattern.
 */

2. Block Markup Rules

Canonical Format

  • No custom HTML comments like <!-- Title -->.

✅ Correct:

<!-- wp:heading -->
    <h2 class="wp-block-heading">Example</h2>
<!-- /wp:heading -->

❌ Incorrect:

<!-- Title Section -->
<!-- wp:heading {"level":2} -->
    <h2 class="wp-block-heading">
      Example
    </h2>
<!-- /wp:heading -->

3. Headings

  • <h2> is the default heading level. Do not include {"level":2}.
  • Explicitly set other levels:
    • {"level":1} for <h1>
    • {"level":3} for <h3>, etc.

4. Group & Wrapper Blocks

If the root is a <group>, include metadata:

"metadata":{
  "categories":["text","theme"],
  "patternName":"my-theme/my-pattern",
  "name":"My Pattern"
}

5. Attributes

  • Only include non‑default attributes.
  • ✅ Keep {"fontSize":"large"} if applied.
  • ❌ Don’t keep {"level":2} or other defaults.
  • WordPress will normalize defaults away.

6. Comments

  • Use only WordPress block comments (<!-- wp:... --> / <!-- /wp:... -->).
  • Do not add developer notes or section labels inside comments.

7. Testing

  • Always test by:
    1. Importing the pattern into the Block Editor.
    2. Saving the page.
    3. Verifying zero recovery warnings in the console.

Summary: Do’s & Don’ts

✅ Do:

  • Use correct docblock headers.
  • Match canonical output exactly.
  • Explicitly set heading levels other than <h2>.
  • Include metadata on root group blocks.
  • Keep only non‑default attributes.

❌ Don’t:

  • Include {"level":2}.
  • Add extra HTML comments.