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
<?php
declare(strict_types = 1);
namespace App\Models;
use OtherClass;
class MyClass
{
private OtherClass $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.php
Show Result
<?php
class MyClass {
private string id;
private string name;
private string 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.
<?php
use CodeStencil\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!