Found this useful? Install from Packagist (
composer require nowo-tech/word-template-bundle) and consider starring WordTemplateBundle on GitHub.
Symfony bundle that fills Microsoft Word .docx templates (PHPWord TemplateProcessor) using a PHP context array:
- Scalars (strings, numbers, booleans, null) →
setValueon placeholders such as${client_name}or${client.city}when you nest arrays (flattened to dot keys). ConditionalBlock→${#if block}…${#endif block}regions (nested blocks supported); show or remove from PHP.TableRows→cloneRow+ per-cell#1,#2, … replacements for repeating table lines.HtmlContent→ rich fragments (paragraphs, bold/italic, tables inside HTML, etc.) via PHPWordHtml::addHtmlembedded as a complex block (lists<ul>/<ol>may require extra numbering setup in PHPWord; prefer plain paragraphs or combine with HtmlToWordBundle for full HTML pipelines).ImageSource→setImageValuewith optional width/height.listVariables()→ read a template and list unique placeholder names (respects configured delimiters).
This bundle does not execute Word VBA macros; “macros” here means template placeholders in the .docx compatible with PHPWord.
Under FrankenPHP (especially worker mode), process() is bounded by a configurable timeout (default 180s, cooperative deadline + set_time_limit) so a long merge cannot pin a worker forever. See docs/CONFIGURATION.md and docs/DEMO-FRANKENPHP.md (REQ-RUNTIME-001).
- GitHub Actions CI requirements
- Installation
- Configuration
- Usage
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
- FrankenPHP / Docker demo —
demo/symfony8(seedemo/README.md)
- PHP 8.2+
- Symfony 7.x / 8.x (as in
composer.json) - Extensions:
dom,json,libxml,zip
composer require nowo-tech/word-template-bundle:^1.2Register Nowo\WordTemplateBundle\WordTemplateBundle if needed, then wire your templates and inject WordTemplateProcessorInterface:
use Nowo\WordTemplateBundle\Processor\WordTemplateProcessorInterface;
$doc = $this->wordTemplateProcessor->process(
'/path/to/template.docx',
[
'title' => 'Contract #42',
'client' => ['name' => 'ACME', 'city' => 'Madrid'],
],
);
$bytes = $doc->readContents();
$doc->dispose(); // if the processor used a temp file| Scope | Detail |
|---|---|
| PHPUnit | composer test — unit + integration (minimal kernel in tests/Fixtures/AppKernel.php). |
| Lines | composer coverage-check enforces ≥ 99% (PCOV). Latest global measurement: ~100%. |
make up
make qa
make release-checkDemos run with FrankenPHP (Caddy + PHP in Docker). docker-compose defaults to APP_ENV=dev, so the entrypoint uses Caddyfile.dev (no PHP worker), and Twig/PHP changes are visible on refresh. Worker mode applies to a production-style setup — see docs/DEMO-FRANKENPHP.md.
From the repository root:
cd demo/symfony8 && cp .env.example .env && make up # Symfony 8, port 8021Or from demo/: make up (see demo/README.md).