symfony2admingenerator/twig-generator
Twig generator component for Symfony2AdminGenerator, providing Twig-based templates and rendering support for generated Symfony admin interfaces. Helps scaffold and customize CRUD backends with reusable Twig templates.
symfony2admingenerator/twig-generator is a small, low-level library that sits underneath the Symfony2 Admin Generator stack: it takes Twig templates that emit PHP source and writes the resulting files to disk. Reach for it directly only when you need a code-generation engine inside your own tool, not when you just want admin scaffolding.
Minimal steps:
composer require symfony2admingenerator/twig-generatorsrc/TwigGenerator/Builder/Generator.php and src/TwigGenerator/Builder/BaseBuilder.php first — the entire public surface is those two classes plus the Twig extensions in src/TwigGenerator/Twig/Extension/.Generator, point it at your template directories and an output directory, hand it a bag of variables, register one or more builders that each map a template to an output file, then call generate().First use case: generate a small set of Doctrine entities (or form types, or controllers) from a single spec array. You define one BaseBuilder subclass per artifact type, keep the actual PHP scaffolding in .php.twig templates, and pass the spec through the generator's variable bag. That is the intended workflow — one builder, one template, one file.
Shared variables, per-builder templates. The usual shape is: Generator::setVariables($shared) with a global bag, then addBuilder() for each artifact. Builders read from that bag and may override or add to it in getVariables(). Keep the contract in a plain array or a simple DTO — do not pass ORM entities directly to templates unless you control the Twig extensions in use.
Builder per artifact. A builder's responsibilities are small and worth respecting: return a template name, return an output filename, optionally return false from mustGenerate() to skip when nothing changed. Do not put branching logic into the template if a separate builder would express it more clearly — one template generating two wildly different files is the fastest way to an unreadable generator.
Template directories are ordered. setTemplateDirs() accepts several paths; the engine searches them in order. Use this for a two-tier pattern — a base template set shipped in your package, plus a project-level directory that overrides individual templates. That gives downstream users an extension point without touching your source.
Inject Twig extensions rather than building strings in PHP. The package's own extensions (string manipulation, indentation, pluralization, PHP escaping helpers, etc.) exist precisely so templates stay templates. If you need a new transform, add a Twig\Extension\AbstractExtension and register it on the generator's Twig environment — do not pre-bake strings in the builder.
Integration tip — let the Symfony2AdminGenerator bundles drive it. In a real Symfony app you rarely call Generator yourself. GeneratorBundle, the builders (DoctrineORMBuilder, DoctrineODMBuilder, PropelBuilder), and the admin generator bundle all instantiate it for you from a command. If you are customizing generated admin code, your hook is the template directory override, not a fork of this package.
Regeneration workflow. Treat generated output as a build artifact. Commit it if your users expect runnable source in src/, or cache it if it is disposable — the library only writes files, it does not reconcile diffs, so a "check before overwrite" step is your responsibility via mustGenerate().
getOutputName(). Two builders returning the same path overwrite each other with no warning. Add an assertion in your own registry that filenames are unique before calling generate().Twig\Extension\AbstractExtension conventions. If you are on Twig 3.x, verify the extensions in src/TwigGenerator/Twig/Extension/ still implement the current interface before relying on them; otherwise register your own and skip theirs.composer.json for the actual constraint before adopting; do not assume PHP 8.3 works because the release date looks fresh.generate() so a stack trace is actually actionable.mkdir -p the target yourself and check writability; a permission failure can otherwise appear as a silently empty file.BaseBuilder (subclass for new artifact types), a custom Twig extension, and the ordered template directories are the three sanctioned hooks. Anything else — modifying generated files post-hoc in PHP — belongs in your own layer, not inside a template.How can I help you explore Laravel packages today?