Welcome. This is the canonical reference for the Elementary WordPress theme and the framework layer it ships with (inc/Framework/).
The docs are written for two audiences:
- Junior developers new to the codebase — start at Getting Started and work through in order.
- AI coding agents — see AI Agent Notes first; it tells you which file to touch for which kind of change.
Everything here describes the post-refactor architecture: PHP-DI container, service providers, auto-discovered modules, abstract base classes, and a two-tier test strategy (Brain Monkey unit + WP integration).
| # | Doc | What it covers |
|---|---|---|
| 1 | Getting Started | Install, run tests, build your first module |
| 2 | Architecture Overview | Layers, boot sequence, request lifecycle |
| 3 | Dependency Injection | The container, autowiring, factories, scopes |
| 4 | Service Providers | When and how to write a provider |
| 5 | Modules & Auto-Discovery | The ModuleInterface, the loader, load_order |
| 6 | Abstracts Reference | AbstractPostType, AbstractTaxonomy, AbstractBlockExtension, AbstractRestController, AbstractShortcode |
| 7 | Traits Catalogue | AssetLoaderTrait, ContainerAwareTrait, Singleton (legacy), AutoloaderTrait |
| 8 | Testing | Unit vs integration, Brain Monkey, fixtures, mocking via DI |
| 9 | Recipes | Copy-paste solutions for the 10 most common tasks |
| 10 | Conventions | Style, naming, file organisation, namespacing |
| 11 | Troubleshooting | Common errors and fixes |
| 12 | Migration Guide | Move legacy singleton code onto DI |
| 13 | Glossary | Terms used across these docs |
| 14 | AI Agent Notes | Operating manual for AI coders |
| – | Asset Build Process | Webpack pipeline (pre-refactor doc, still current) |
- Add a new custom post type → Recipes § CPT
- Add a new block extension → Recipes § Block Extension
- Replace a service in a test → Testing § Mocking via DI
- Wire a new service that needs config → Service Providers § Writing a provider
- Lint / type-check / test commands → Getting Started § Commands
Three rules. Internalise these before writing code.
- No new singletons. The
Singletontrait exists for one class (Main). Every new service belongs in the container. - Auto-discovered modules implement
ModuleInterface. Explicit services bind viaServiceProvider. Don't mix the two. - Constructor-inject, don't service-locate. Services should declare their dependencies in
__construct(...). Only reach forContainer::get()at the top of the call graph (kernel, providers).
If a change you're making seems to require breaking one of these rules, treat that as a signal to re-read the relevant doc before continuing.