orchestra/canvas-core
Core utilities for Orchestra Canvas code generators. Build and customize generators for Laravel apps and packages, with testing and coverage support. Provides the foundational services used by Canvas to scaffold code and streamline development workflows.
Installation:
composer require orchestra/canvas-core
Ensure your project uses Laravel 11.x (or later compatible versions).
Publish Configuration:
php artisan vendor:publish --provider="Orchestra\Canvas\Core\CanvasServiceProvider"
This creates a config/canvas.php file with default presets.
First Command: Generate a basic model with migrations, factory, and tests:
php artisan canvas:generate model User --with=migration,factory,test
Verify the files are created in app/Models/User.php, database/migrations/..., etc.
Explore Presets:
Check config/canvas.php for built-in presets like model, controller, policy, and resource.
Example for a controller:
php artisan canvas:generate controller Admin/UserController --resource
Customize Templates:
Override default templates by copying files from vendor/orchestral/canvas-core/src/Resources/views to resources/views/vendor/canvas/.
php artisan canvas:generate model Post --with=migration,seeder,policy,test
Generates:
app/Models/Post.php)database/migrations/...)database/seeders/PostsTableSeeder.php)app/Policies/PostPolicy.php)tests/Feature/PostTest.php)config/canvas.php:
'presets' => [
'package' => [
'path' => 'stubs/package',
'files' => [
'Provider' => 'src/Providers/{Name}ServiceProvider.php',
'Command' => 'src/Console/Commands/{Name}Command.php',
],
],
],
Then generate:
php artisan canvas:generate package MyPackage --with=Provider,Command
composer.json scripts:
"scripts": {
"post-create-project-cmd": [
"canvas:generate model User --with=migration,factory,test"
]
}
Or use a GitHub Action:
- name: Generate Boilerplate
run: php artisan canvas:generate model Post --with=migration,seeder
// app/Generators/ApiResourceGenerator.php
namespace App\Generators;
use Orchestra\Canvas\Core\GeneratesCode;
class ApiResourceGenerator extends GeneratesCode
{
protected $signature = 'canvas:generate api-resource {name}';
protected $description = 'Generate an API resource';
public function generate()
{
$this->generateClass($this->name, 'api-resource', 'ApiResource');
}
}
Register it in AppServiceProvider:
public function boot()
{
$this->app->make('command.canvas.generate.api-resource')->register();
}
Now use:
php artisan canvas:generate api-resource PostResource
vendor/orchestral/canvas-core/src/Resources/views/model.stub to resources/views/vendor/canvas/model.stub and modify it.
Example: Add a softDeletes trait to all generated models:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class {{ class }} extends Model
{
use SoftDeletes;
// ...
}
Leverage Laravel Facades:
Use Laravel’s facades (e.g., Schema, Artisan) within generators for dynamic logic:
use Illuminate\Support\Facades\Schema;
public function generate()
{
Schema::create($this->name.'s', function ($table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
Combine with Workbench Actions:
Use orchestra/workbench actions to extend generators with business logic:
use Orchestra\Workbench\Actions\Action;
class AddSoftDeletes extends Action
{
public function handle()
{
// Add soft deletes to the generated model
}
}
Dynamic File Paths:
Use Illuminate\Filesystem\join_paths() for cross-platform compatibility:
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Storage;
$path = join_paths(app_path(), 'Models', $this->name.'.php');
Event Listeners: Trigger events after generation to run additional logic:
use Orchestra\Canvas\Core\Events\CodeHasBeenGenerated;
CodeHasBeenGenerated::dispatch($this->name);
Testing Generators: Use Laravel’s testing tools to verify generator output:
public function test_model_generator()
{
$this->artisan('canvas:generate model TestModel')
->expectsOutput('Model created successfully.')
->assertExitCode(0);
$this->assertFileExists(app_path('Models/TestModel.php'));
}
Generator Registration:
$this->app->bind('command.canvas.generate.my-generator', function ($app) {
return new \App\Generators\MyGenerator();
});
Template Path Conflicts:
resources/views/vendor/canvas/ may override defaults unexpectedly.resources/views/vendor/canvas/myapp/) and update config/canvas.php:
'paths' => [
'templates' => resource_path('views/vendor/canvas/myapp'),
],
Laravel Version Mismatch:
Null Generators Array:
null to the generators config key can cause errors.generators is an array:
'generators' => [
'model' => ['migration', 'factory', 'test'],
],
Soft Deprecations:
possibleModelsUsingCanvas() are soft-deprecated.possibleModels()) instead.PHP Attributes:
Migration Generator Conflicts:
MigrationGeneratorCommand may cause conflicts.use Illuminate\Database\Console\Migrations\MigrationGeneratorCommand;
class CustomMigrationGenerator extends MigrationGeneratorCommand
{
// Extend logic here
}
Enable Debug Mode:
Set debug to true in config/canvas.php to log generator actions:
'debug' => env('CANVAS_DEBUG', false),
Check Generator Output:
Use --verbose flag to see detailed generation steps:
php artisan canvas:generate model User --verbose
Inspect Template Rendering: Add debug statements in stub templates to trace variable replacements:
{{ dump($variables) }}
Validate File Permissions: Ensure the target directory (e.g., `app
How can I help you explore Laravel packages today?