Code Stencil provides an elegant, easy to read pattern that is great for generating stub files, and will streamline your code generation tasks. A common occurrence with code generation is that readability and maintenance suffer, but with Code Stencil, it's a piece of cake!
Stencil::make()
->php()
->strictTypes()
->namespace('App/Models')
->curlyStatement('class MyClass', fn(Stencil$s) => $s
->line('private OtherClass $otherClass;')
->use(OtherClass::class) // This will add a use statement to the file
->line()
->phpdoc(
summary: 'Create a new instance of MyClass',
tags: ['param' => ['OtherClass $class', 'bool $options']]
)
->curlyStatement('function __construct(OtherClass $class, bool $options = false)', fn(Stencil$s) => $s
->line('$this->otherClass = $class;')
)
)
->save('MyClass.php')Show Result
<?phpdeclare(strict_types = 1);
namespaceApp\Models;
useOtherClass;
class MyClass
{
privateOtherClass$otherClass;
/** * Create a new instance of MyClass * @param OtherClass $class * @param bool $options */function__construct(OtherClass$class, bool$options = false)
{
$this->otherClass = $class;
}
}It can also become much more dynamic, with the addition of variables, functions, and conditional logic.
$properties = ['Id', 'Name', 'StartAt'];
$includeTimestamp = false;
Stencil::make()
->php()
->variable('__class__', 'MyClass')
->function('lcfirst', fn(string$value) => lcfirst($value))
->curlyStatement('class __class__', fn(Stencil$s) => $s
->foreach($properties, fn(Stencil$s, string$property) => $s
->line("private string % lcfirst %($property);") // We can call our 'lcfirst' function that we defined above using this syntax
)
->when($includeTimestamp, fn(Stencil$s) => $s->line('private DateTime $timestamp;'))
)
->save('__class__.php') // File output will be to MyClass.phpShow Result
<?phpclass MyClass {
privatestring id;
privatestring name;
privatestring startAt;
}This example is basic, but there's no limit to the complexity of code you can generate!
Native integration for stub files in Laravel is also supported. You'll be able to create stub files for use with existing laravel commands.
This means that you can return a Stencil directly within a custom stub file, and it will then be processed just like any other stencil.
If you don't already have the stubs published in your project, you can run php artisan stub:publish.
Then within any of these files you can create a stencil like so.
<?phpuseCodeStencil\Stencil;
return Stencil::make()
->php()
->namespace('App\Models')
->use('Illuminate\Database\Eloquent\Factories\HasFactory')
->use('Illuminate\Database\Eloquent\Model')
->curlyStatement('class i_name extends Model', fn(Stencil$s) => $s
->line('use HasFactory;')
)
->overrideStubLocation(base_path('Domain/Other/Path/i_name.php'));In larger projects, you may not be using the default locations where Laravel generates the file. If you would like to change this,
you can call the overrideStubLocation method on the Stencil, and provide a custom location where you would like the stub file to be written to.
Note that this method is implemented via a macro, and code completion will not be available for it.
If you have a formatter installed, such as Pint, PHP CS Fixer, or StyleCI, your stencil will be formatted as well!
