A Laravel Code Generator based on your Models using Blade Template Engine

Overview

Laravel Code Generator

Laravel Code Generator is a PHP Laravel Package that uses Blade template engine to generate code for you.

The difference between other code generators is that this one will generate the code exactly as you want it to be, same design, same lines of code.

Demo

Installation

Use composer to install Laravel Code Generator.

composer require --dev victoryoalli/laravel-code-generator

Usage

Single file generation

php artisan code:generate 'App\Models\User' -t 'schema' //prints to command line
php artisan code:generate 'App\Models\User' -t 'schema' -o 'user-schema.json'

Example Output

{
  "name": "User",
  "complete_name": "App\\Models\\User",
  "table": {
    "name": "users",
    "columns": [
      {
        "name": "id",
        "type": "BigInt",
        "length": "",
        "nullable": "",
        "autoincrement": "1",
        "default": ""
      },
      {
        "name": "name",
        "type": "String",
        "length": "255",
        "nullable": "",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "email",
        "type": "String",
        "length": "255",
        "nullable": "",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "email_verified_at",
        "type": "DateTime",
        "length": "0",
        "nullable": "1",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "password",
        "type": "String",
        "length": "255",
        "nullable": "",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "remember_token",
        "type": "String",
        "length": "100",
        "nullable": "1",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "created_at",
        "type": "DateTime",
        "length": "0",
        "nullable": "1",
        "autoincrement": "",
        "default": ""
      },
      {
        "name": "updated_at",
        "type": "DateTime",
        "length": "0",
        "nullable": "1",
        "autoincrement": "",
        "default": ""
      }
    ]
  },
  "relations": []
}

Multiple file generator

First create a custom command like this example

Create a Custom Command

php artisan make:command CodeGeneratorCommand --command='code:generator'

Custom Command

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use VictorYoalli\LaravelCodeGenerator\Facades\CodeGenerator;
use VictorYoalli\LaravelCodeGenerator\Facades\ModelLoader;
use VictorYoalli\LaravelCodeGenerator\Structure\Model;

class CodeGeneratorCommand extends Command
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'code:generator {model : Model(s) separated by commas: i.e: \'User, Post, Section\' } ' .
            '{--namespace=App\Models : Models Namesspace} ' .
            '{--w|views : View files} ' .
            '{--c|controller : Controller} ' .
            '{--a|api : Creates API Controller} ' .
            '{--r|routes : Display Routes} ' .
            '{--l|lang : Language} ' .
            '{--A|all : All Files}' .
            '{--f|factory : Factory} ' .
            '{--t|tests : Feature Test} ' .
            '{--auth : Auth (not included in all)} ' .
            '{--event= : Event (not included in all)} ' .
            '{--notification= : Notification (not included in all)} ' .
            '{--F|force : Overwrite files if exists} ' .
            '{--livewire : Add livewire files}' .
            '{--theme=blade : Theme}';

    protected $description = 'Multiple files generation';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $force = $this->option('force');

        //Options
        $controller = $this->option('controller');
        $routes = $this->option('routes');
        $views = $this->option('views');
        $api = $this->option('api');
        $lang = $this->option('lang');
        $factory = $this->option('factory');
        $tests = $this->option('tests');
        $auth = $this->option('auth');
        $event = $this->option('event');
        $notification = $this->option('notification');
        $all = $this->option('all');
        $livewire = $this->option('livewire');
        $theme = $this->option('theme');
        if ($all) {
            $lang = $controller = $routes = $views = $all;
        }
        $request = ($controller || $api);

        $options = compact(['factory', 'controller', 'routes', 'views',  'api', 'tests', 'auth', 'request', 'notification', 'event', 'lang','livewire']);
        $namespace = rtrim($this->option('namespace'), '\\');
        $models = collect(explode(',', $this->argument('model')));

        $models->each(function ($model) use ($namespace, $options, $theme, $force) {
            $model = "{$namespace}\\{$model}";
            if (!$model) {
                return;
            }
            $m = ModelLoader::load($model);

            $this->generate($m, $options, $theme, $force);
        });
    }

    public function generate(Model $m, $options, $theme, $force)
    {
        $option = (object) $options;
        $folder = str($m->name)->plural()->snake();

        $this->info('🚀 Starting code generation');
        $this->newLine();
        if ($option->controller) {
            $this->printif('Web Controller', CodeGenerator::generate($m, $theme . '/Http/Controllers/ModelController', "app/Http/Controllers/{$m->name}Controller.php", $force, $options));
        }
        if ($option->api) {
            $this->printif('API Controller', CodeGenerator::generate($m, $theme . '/Http/Controllers/API/ModelController', "app/Http/Controllers/API/{$m->name}Controller.php", $force, $options));
        }
        if ($option->request) {
            $this->printif('Form Request', CodeGenerator::generate($m, $theme . '/Http/Requests/ModelRequest', "app/Http/Requests/{$m->name}Request.php", $force, $options));
        }

        if ($option->views) {
            $this->printif('Index View', CodeGenerator::generate($m, $theme . '/views/index', "resources/views/{$folder}/index.blade.php", $force, $options));
            $this->printif('Create View', CodeGenerator::generate($m, $theme . '/views/create', "resources/views/{$folder}/create.blade.php", $force, $options));
            $this->printif('Show View', CodeGenerator::generate($m, $theme . '/views/show', "resources/views/{$folder}/show.blade.php", $force, $options));
            $this->printif('Edit View', CodeGenerator::generate($m, $theme . '/views/edit', "resources/views/{$folder}/edit.blade.php", $force, $options));
        }
        if ($option->lang) {
            $this->printif('Lang', CodeGenerator::generate($m, $theme . '/lang/en/Models', "resources/lang/en/{$folder}.php", $force, $options));
        }
        if ($option->factory) {
            $this->printif('Factory ', CodeGenerator::generate($m, $theme . '/database/factories/ModelFactory', "database/factories/{$m->name}Factory.php", $force, $options));
        }
        if ($option->tests) {
            $this->printif('Feature Test Controller', CodeGenerator::generate($m, $theme . '/tests/Feature/Http/Controllers/ModelControllerTest', "tests/Feature/Http/Controllers/{$m->name}ControllerTest.php", $force, $options));
            if ($option->controller) {
                $this->printif('Feature Test Controller', CodeGenerator::generate($m, $theme . '/tests/Feature/Http/Controllers/ModelControllerTest', "tests/Feature/Http/Controllers/{$m->name}ControllerTest.php", $force, $options));
            }
            if ($option->api) {
                $this->printif('Feature Test API Controller', CodeGenerator::generate($m, $theme . '/tests/Feature/Http/Controllers/API/ModelControllerTest', "tests/Feature/Http/Controllers/API/{$m->name}ControllerTest.php", $force, $options));
            }
        }
        if ($option->notification) {
            $this->printif('Notification', CodeGenerator::generate($m, $theme . '/Notifications/ModelNotification', "app/Notifications/{$m->name}{$option->notification}.php", $force, $options));
        }
        if ($option->event) {
            $this->printif('Event', CodeGenerator::generate($m, $theme . '/Events/ModelEvent', "app/Events/{$m->name}{$option->event}.php", $force, $options));
        }
        if ($option->livewire) {
            $plural = str($m->name)->plural();
            $this->printif('Livewire Component ', CodeGenerator::generate($m, "/livewire/Http/Index", "app/Http/Livewire/{$plural}/Index.php", $force, $options));
            $this->printif('Livewire index view ', CodeGenerator::generate($m, "/livewire/views/index", "resources/views/livewire/{$folder}/index.blade.php", $force, $options));
            $this->printif('Livewire list view ', CodeGenerator::generate($m, "/livewire/views/list", "resources/views/livewire/{$folder}/list.blade.php", $force, $options));
            $this->printif('Livewire edit view ', CodeGenerator::generate($m, "/livewire/views/edit", "resources/views/livewire/{$folder}/edit.blade.php", $force, $options));
            $this->printif('Livewire show view ', CodeGenerator::generate($m, "/livewire/views/show", "resources/views/livewire/{$folder}/show.blade.php", $force, $options));
        }
        if ($option->routes) {
            $this->newLine(3);
            $this->line('<fg=cyan>'.CodeGenerator::generate($m, $theme . '/routes', null, $force, $options).'</>');
        }

        $this->newLine();
        $this->info('🎉 Finished!');
    }

    public function printif($type, $filename)
    {
        $text = empty($filename) ? '<fg=red> ✖ </> '. $type . '<fg=yellow> already exists </>' : '<fg=green>✔</> <fg=default>' . $filename . '<fg=magenta> created. </>';
        $this->line($text);
    }
}

Execute custom command

php artisan code:generator 'App\User' -FA

Templates & Customization

Templates are located at resources/vendor/laravel-code-generator. For example once you publish the views the file schema.blade.json will be located at the relative path is resources/vendor/laravel-code-generator\schema.blade.json .

The path resources/views/vendor/laravel-code-generator is where you can create your own new templates, or customize the existing ones.

Publish template views & Config

You can publish :

## views at: resources/views/vendor/laravel-code-generator
php artisan vendor:publish --provider="VictorYoalli\LaravelCodeGenerator\LaravelCodeGeneratorServiceProvider" --tag="views"

or the config file

## config file: config/laravel-code-generator.php
php artisan vendor:publish --provider="VictorYoalli\LaravelCodeGenerator\LaravelCodeGeneratorServiceProvider" --tag="config"

This is the contents of the published config file config/laravel-code-generator.php:

By default you can use as templates files with following extensions, if you need to generate or use different files as templates you can add to the config file.

<?php

return [
    /**
     * Extension files that can be used with this Blade template engine.
     * You can add more if you need to.
     * .blade.php
     * .blade.js
     * .blade.jsx
     * .blade.vue
     * .blade.html
     * .blade.txt
     * .blade.json
     */
    'extensions' => [
        'js',
        'jsx',
        'vue',
        'html',
        'txt',
        'json',
    ]
];

Structure

  • Model (object)
    • name (string)
    • table (object)
    • relations (array)
  • Table (object)
    • name (string)
    • columns (array)
  • Column (object)
    • name (string)
    • type (string)
    • length (integer)
    • nullable (boolean)
    • autoincrement (boolean)
    • default (string)
  • Relations (array)
    • name (string)
    • type (string)
    • local_key (string)
    • foreign_key (string)
    • model (array)

Example

{!!code()->PHPSOL()!!}

namespace App\Http\Controllers\API;

use App\{{$model->name}};
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class {{$model->name}}Controller extends Controller
{
    /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
    public function index()
    {
        return {{$model->name}}::all();
    }

    /**
    * Store a newly created resource in storage.
    *
    * @param \Illuminate\Http\Request $request
    * @return \Illuminate\Http\Response
    */
    public function store(Request $request)
    {
        $this->validate($request, [
            @foreach($model->table->columns as $col)
            @if(!str($col->name)->matches('/_at$/') && !str($col->name)->matches('/^id$/'))
            @if(!$col->nullable) '{{$col->name}}' => 'required',
            @endif
            @endif
            @endforeach
        ]);

        ${{str($model->name)->camel()}} = {{$model->name}}::create($request->all());

        return ${{str($model->name)->camel()}};
    }

...
}

Output Sample

<?php

namespace App\Http\Controllers\API;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
    * Display a listing of the resource.
    *
    * @return  \Illuminate\Http\Response
    */
    public function index()
    {
        return User::all();
    }

    /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request $request
    * @return  \Illuminate\Http\Response
    */
    public function store(Request $request)
    {
        $this->validate($request, [
        'name' => 'required',
        'email' => 'required',
        'password' => 'required',

        ]);

        $user = User::create($request->all());

        return $user;
    }

Helpers

PHPSOL(): PHP Start Of Line

{!!code->PHPSOL()!!}

Will print

<?php

doubleCurlyOpen(): Opening Double Curly Braces

{{code()->doubleCurlyOpen()}}

Will print:

{{

doubleCurlyClose(): Closing Double Curly Braces

{{code()->doubleCurlyClose()}}

Will print:

}}

tag('x-component-name'): Closing Double Curly Braces

{{code()->tag('x-component-name)}}

Will print:

<x-component-name>

CodeGenerator::generate Facade

This is how you can use the Facade when you want to create your own Code Generator.

    $filename = CodeGenerator::generate('App\Models\User', 'blade/show', "resources/views/{$folder}/show.blade.php", false);
    $generatedCodeString = CodeGenerator::generate($m, 'blade/routes' );

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Comments
  • Where to add templates for custom template (Inertia.JS Vue Component)

    Where to add templates for custom template (Inertia.JS Vue Component)

    Hi there, fantastic code - thanks for this.

    I'm trying to get this setup to work with Tailwind and Inertia.JS and instead of creating blade view files I want to crate .vue components in resources/js/Pages/FolderName/create.vue etc.

    I can do this with the following custom command: https://gist.github.com/raisonon/83a9589a40fcc8e2d9200f42461eaec8

    However, I'm still getting the View file templates. I've created my own create.vue etc. files in views/vendor/lavevel-code-generator/basic folder but no luck.

    Any advice on how I can create and select my own template files for these vue files?

    Thanks in advance

    opened by ejntaylor 7
  • Type=

    Type="date" not been implemented

    Hello Victor.

    I have a date attribute on my database. I remember with the older versions, you can use the calendar picker by default, but now is missing.

    Please take a look at this video. Is just one minute long. Thanks.

    http://somup.com/crjh08Y5AX

    opened by Jesusjeco 2
  • php artisan code:generator 'Models\Datos' -FA proyecto de cero

    php artisan code:generator 'Models\Datos' -FA proyecto de cero

    Unable to find 'App\Models\Datos' class TypeError

    Argument 1 passed to App\Console\Commands\CodeGeneratorCommand::generate() must be an instance of VictorYoalli\LaravelCodeGenerator\Structure\Model, bool given, called in C:\wamp64\www\proyecto_taller\app\Console\Commands\CodeGeneratorCommand.php on line 80

    80| $this->generate($m, $options, $theme, $force); 81| }); 82| } 83|

    84| public function generate(Model $m, $options, $theme, $force) 85| { 86| $option = (object) $options; 87| $folder = CodeHelper::plural(CodeHelper::snake($m->name)); 88| if ($option->controller) {

    1 C:\wamp64\www\proyecto_taller\app\Console\Commands\CodeGeneratorCommand.php:80 App\Console\Commands\CodeGeneratorCommand::generate("basic")

    2 C:\wamp64\www\proyecto_taller\vendor\laravel\framework\src\Illuminate\Support\Traits\EnumeratesValues.php:202 App\Console\Commands\CodeGeneratorCommand::App\Console\Commands{closure}("App\Models\Datos") este problema aparece es un proyecto en blanco segui los paso para

    opened by KoviScz 1
  • PhP 8 issue

    PhP 8 issue

    - victoryoalli/laravel-code-generator is locked to version 1.0.9 and an update of this package was not requested.
    - victoryoalli/laravel-code-generator 1.0.9 requires php ^7.1 -> your php version (8.0.0) does not satisfy that requirement.
    - 
    

    I fixed it by running: composer require victoryoalli/laravel-code-generator --ignore-platform-reqs

    opened by Gerbenodk 1
  • PhP 8

    PhP 8

    [InvalidArgumentException] Package victoryoalli/laravel-code-generator has a PHP requirement incompatible with your PHP version, PHP extensions and Composer version

    Hi amazing package you have but can you make it compatible with the new php8? Thanks in advance

    opened by Gerbenodk 1
  • Undefined variable in Structure\Table

    Undefined variable in Structure\Table

    Hello, there is minor error here: public function getColumns() { $cols = $this->table->getColumns(); $columns = []; <--missing foreach ($cols as $key => $col) { $columns[] = new Column($col); } return $columns; } and also minor error here: try { // handle abstract classes, interfaces, ... $reflectionClass = new \ReflectionClass($model_name);

            if (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')) {
                print_r("\nNot an eloquent '$model_name' class");
                return false;
            }
    
            if (!$reflectionClass->IsInstantiable()) {
                // ignore abstract class or interface
                return false;
            }
    
            $model = $this->app->make($model_name);
            $this->model = new Model($model);
            $finder = new RelationFinder();
            if ($recursive) {
                $this->model->relations = $finder->getModelRelations($model_name);
            }
        } catch (\Exception $e) {
            print_r('Exception: ' . $e->getMessage() . "\nCould not analyze class {$this->model->name}."); <---HERE
        }
    

    this print_r fails if exception happens before $this->model declaration and all you get is "getting property name of undefined variable" Thanks a lot, great utility, just what i looked for

    opened by superkozel 1
  • Invalid argument for laravel-code-generator.extensions loop

    Invalid argument for laravel-code-generator.extensions loop

    Any ideas on this error I get with latest version of Laravel... Perhaps I need to define laravel-code-generator.extensions somewhere?

    This occurs when running a command like: php artisan code:generator 'App\User' -c

    Thanks

    ` ErrorException

    Invalid argument supplied for foreach()

    at vendor/victoryoalli/laravel-code-generator/src/CodeGenerator.php:18 14| { 15| $app = app(); 16| $this->view = $app['view']; 17| $extensions = config('laravel-code-generator.extensions'); > 18| foreach ($extensions as $ext) { 19| $this->view->addExtension("blade.{$ext}", 'blade'); 20| } 21| $this->files = app(Filesystem::class); 22| }`

    opened by ejntaylor 1
  • Laravel 7

    Laravel 7

    Bit premature to create a ticket perhaps, but now I just tried with Laravel 7 (released today) and got the following error:

    Your requirements could not be resolved to an installable set of packages.

    Problem 1 - Conclusion: remove laravel/framework v7.0.1 - Conclusion: don't install laravel/framework v7.0.1

    ...

    - don't install illuminate/filesystem v5.8.27|don't install laravel/framework v7.0.1
    

    ...

    Installation failed, reverting ./composer.json to its original content.

    opened by ejntaylor 1
Releases(3.0.1)
Owner
Victor Yoalli
Life, Tech, Niners, Design, Marketing, Open Source, and Programming #Laravel #VueJS #ReactJS #ReactNative #NET #CSharp #TailwindCSS @VientoDigital Founder.
Victor Yoalli
Snippets for blade template engine

Blade Snippets for Sublime Text Blade is a simple, yet powerful templating engine provided with Laravel PHP framework. These snippets works with blade

Alex Antonyuk 113 Jan 3, 2023
Blade UI Kit is a set of renderless components to utilise in your Laravel Blade views

Blade UI Kit is a set of renderless components to utilise in your Laravel Blade views. In all essence, it's a collection of useful utilities, connecting the dots between different parts of the TALL stack. It was made for Blade, Laravel's powerful templating engine.

Blade UI Kit 1.2k Jan 5, 2023
Create Laravel views (blade template) using 'php artisan' command-line interface

About LaraBit Have you ever wonder to create Laravel views (Blade Templates) using the same type of artisan commands that you usually use to create ne

Ragib MRB 5 Oct 15, 2021
Use Laravel's Blade templating engine outside of Laravel.

Use Laravel's Blade templating engine outside of Laravel. This package provides a standalone version of Laravel's Blade templating engine for use outs

Ryan Chandler 22 Jan 2, 2023
This package adds syntax definitions for the Laravel Blade engine.

Laravel Blade Highlighter This package adds syntax definitions for the Laravel Blade engine. Works with various Sublime Text version, for older/specif

Eric Percifield 393 Dec 24, 2022
A general-purpose parser for Laravel's Blade templating engine.

A general-purpose parser for Laravel's Blade templating engine. This is where your description should go. Try and limit it to a paragraph or two. Cons

Ryan Chandler 6 Feb 18, 2022
Use Laravel's blade engine as a CLI for rendering files.

Blade CLI Use Laravel's blade engine as a CLI for rendering files. Introduction This package customizes and extends several of the Illuminate\View cla

Sergio Compean 31 Oct 21, 2022
Blade is a simple, yet powerful templating engine provided for the Slim Framework

slim-blade Blade is the default template engine of Laravel. The main advantage of Blade is template inheritance whilst using plain PHP. This package a

Kevin Darren 32 May 24, 2021
Laravel Livewire (TALL-stack) form generator with realtime validation, file uploads, array fields, blade form input components and more.

TALL-stack form generator Laravel Livewire, Tailwind forms with auto-generated views. Support Contributions Features This is not an admin panel genera

TinaH 622 Jan 2, 2023
An opinionated blade template formatter for Laravel that respects readability

blade-formatter An opinionated blade template formatter for Laravel that respects readability Online Demo Features Automatically Indents markup inside

Shuhei Hayashibara 277 Dec 26, 2022
Source code behind the Laracasts Larabit: Creating and Using Custom Blade Directives

This is the source code behind the Laracasts Larabit: Creating and Using Custom Blade Directives, and features all of the files and code available in that video.

Andrew Schmelyun 1 Nov 12, 2021
Shows the path of each blade file loaded in a template

Laravel Tracer Tracer shows the paths of all the Blade files that are loaded into your templates. This could be very convenient for a number of reason

Appstract 97 Oct 1, 2022
Is an Extension of Laravel View Class which compiles String Template on the fly. It automatically detects changes on your string template and recompiles it if needed.

Laravel-fly-view Is an Extension of Laravel View Class which compiles String Template on the fly. It automatically detects changes on your string temp

John Turingan 16 Jul 17, 2022
View template engine of PHP extracted from Laravel

Blade 【įŽ€äŊ“中文】 This is a view templating engine which is extracted from Laravel. It's independent without relying on Laravel's Container or any others.

Scholer 143 Dec 13, 2022
Laravel Design Pattern Generator (api generator)

Laravel Design Pattern Generator (api generator) you can create your restful api easily by using this library and you can filter, sort and include elo

HusseinAlaa 2 Sep 25, 2022
🔹 Generator Template for 🙃 Phony Framework

?? Generator Template This repository contains the Generator Template for ?? Phony Framework. ?? Start generating fake data with ?? Phony Framework, v

Phonyland 2 Jan 30, 2022
Decorate Your Models and Write Clean/Reusable Code with Presenters.

Laravel Presenter A clean way to present your model attributes without putting them in the wrong file. Installation You can install the package via co

Coderflex 14 Dec 19, 2022
Laravel blade directives and php helpers for serverside rendered content, based on browser window size WITHOUT css

Laravel Window Size and Breakpoints Laravel blade directives and php helpers for server side rendered content, based on browser window size WITHOUT cs

Tina Hammar 7 Nov 23, 2022
Laravel blade directives and php helpers for serverside rendered content, based on browser window size WITHOUT css. Requires Livewire and AlpineJS.

Laravel Livewire Window Size and Breakpoints Laravel blade directives and php helpers for server side rendered content, based on browser window size W

Tina Hammar 15 Oct 6, 2022