diff --git a/README.md b/README.md index 867f7efa..49b73dd8 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,47 @@ -# Blueprint -A new open-source tool to rapidly generate multiple Laravel components using an expressive, human readable syntax. +![Blueprint](blueprint-logo.png) -Follow along with the development of Blueprint by [watching live streams](https://www.youtube.com/playlist?list=PLmwAMIdrAmK5q0c0JUqzW3u9tb0AqW95w) or [reviewing issues](https://github.com/laravel-shift/blueprint/issues). +_Blueprint_ is an open-source tool for **rapidly generating multiple** Laravel components from a **single, human readable** definition. -_**v0.1 Tagged**: A beta release of Blueprint is now available which supports generating components using `models` definitions._ +Watch a quick [demo of Blueprint](https://twitter.com/gonedark/status/1192513115826589698?s=20) in action and continue reading this document to get started. + +- [Installation](#installation) +- [Requirements](#requirements) +- [Basic Usage](#basic-usage) +- [Defining Components](#defining-components) +- [Contributing](#contributing) ## Installation -You can install this package via composer using this command: +You can install Blueprint via composer using the following command: ```sh composer require --dev laravel-shift/blueprint ``` -The package will automatically register itself. +Blueprint will automatically register itself using [package discovery](https://laravel.com/docs/packages#package-discovery). + +## Requirements +Blueprint requires a Laravel application running version 6.0 or higher. +While Blueprint may be more flexible in a future version, it currently assumes a standard project structure using the default `App` namespace. -## Usage +## Basic Usage Blueprint adds an artisan command. ```sh php artisan blueprint:build [draft] - ``` -The `draft` file contains your definition of the components to generate. By default, the `blueprint:build` command automatically loads a `draft.yaml` file. +The _draft_ file contains a [definition of the components](#defining-components) to generate. By default, the `blueprint:build` command attempts to load a `draft.yaml` file from the project root folder. + +## Defining Components +Use Blueprint's `artisan` commands you may generate multiple Laravel components from a single definition called a _draft_ file. ---- +Within this draft file you define _models_ and _controllers_ using an expressive, human-readable YAML syntax. +Let's review the following draft file: -**Example Syntax** ```yaml models: Post: @@ -54,18 +65,248 @@ controllers: redirect: post.index ``` -**Generated Components** -- [x] Migration -- [x] Model -- [x] Factory -- [x] Route -- [x] Controller -- [x] Form Request -- [x] Mailable -- [x] Job -- [x] Event -- [x] View (stub) +From these simple 20 lines of YAML, Blueprint will generate all of the following Laravel components: + +- A _model_ class for `Post` complete with `fillable`, `casts`, and `dates` properties, as well as relationships methods. +- A _migration_ to create the `posts` table. +- A [_factory_](https://laravel.com/docs/database-testing) intelligently setting columns with fake data. +- A _controller_ class for `PostController` with `index` and `store` actions complete with code generated for each [statement](#statements). +- _Routes_ for the `PostController` actions. +- A [_form request_](https://laravel.com/docs/validation#form-request-validation) of `StorePostRequest` validating `title` and `content` based on the `Post` model definition. +- A _mailable_ class for `ReviewNotification` complete with a `post` property set through the _constructor_. +- A _job_ class for `SyncMedia` complete with a `post` property set through the _constructor_. +- An _event_ class for `NewPost` complete with a `post` property set through the _constructor_. +- A _Blade template_ of `post/index.blade.php` rendered by `PostController@index`. + +While this draft file only defines a single model and controller, you may define multiple [models](#models) and [controllers](#controllers). + +### Models +Within the `models` section of a draft file you may define multiple models. Each model begins with a _name_ followed by a list of columns. Columns are `key: value` pairs where `key` is the column name and `value` defines its attributes. + +Expanding on the example above, this draft file defines multiple models: + +```yaml +models: + Post: + title: string:400 + content: longtext + published_at: nullable timestamp + + Comment: + content: longtext + published_at: nullable timestamp + + # additional models... +``` + +From this definition, Blueprint creates two models: `Post` and `Comment`, respectively. You may continue to define additional models. + +Blueprint recommends defining the model name in its _StudlyCase_, singular form to follow Laravel naming conventions. For example, `Post` instead of `post` or `posts`. + +Similarly, column names will be used as-is. The attributes of these columns may be any of the [column types](https://laravel.com/docs/migrations#creating-columns) and [column modifiers](https://laravel.com/docs/migrations#column-modifiers) available in Laravel. You may define these as-is or using lowercase. + +For complex attributes, you may use a `key:value` pair. From these example above, `string:400` defines a `string` column type with a maximum length of `400` characters. Other examples include `enum:'foo','bar','baz'` or `decimal:10,2`. + +By default, each model will automatically be defined with an `id` and _timestamps_ columns. To disable these columns you may define them with a `false` value. For example, `timestamps: false`. + +Blueprint also offers additional _shorthands_ which will be expanded into valid YAML. Shorthands include an `id` data type, as well as defining [soft deleting](https://laravel.com/docs/eloquent#soft-deleting) models. + +For example: + +```yaml +models: + Comment: + user_id: id + softDeletes + # ... +``` + +Using these shorthands, Blueprint will generate a `Comment` class using the `SoftDeletes` trait. It will also create a `user_id` column with the appropriate data type for an integer foreign key. + +Blueprint also inspects columns and assigns them to `fillable`, `casts`, and `dates` properties, as well as generate relationships methods. + +By default, all columns except for `id` and _timestamps_ will be added to the `fillable` property. + +Where appropriate, Blueprint will [cast](https://laravel.com/docs/5.8/eloquent-mutators#attribute-casting) columns to `integer`, `boolean`, and `decimal` types. Any _date_ columns will be added to the `dates` properties. + +Columns which use an `id` data type or end with `_id` will be used to generate `belongsTo` relationships. By default, Blueprint uses the column name prefix for the related model. If you define a relationship for a different model, you may use a `id:model` syntax. + +For example: + +```yaml +models: + Post: + author_id: id:user + # ... +``` + + +### Controllers +Similar to `models`, you may also define multiple `controllers`. Within the `controllers` section you define a _controller_ by name. Each controller may define multiple `actions` which contain a list of [statements](#statements). + +Expanding on the example above, this draft file defines multiple controllers: + +```yaml +controllers: + Post: + index: + query: all + render: post.index with:posts + create: + render: post.create + store: + validate: title, content + save: post + redirect: post.index + + Comment: + show: + render: comment.show with:show + + # additional controller... +``` + +From this definition, Blueprint will generate two controllers. A `PostController` with `index`, `create`, and `store` actions. And a `CommentController` with a `show` action. + +While you may specify the full name of a controller, Blueprint will automatically suffix names with `Controller`. + +Blueprint encourages you to define [resource controllers](https://laravel.com/docs/controllers#resource-controllers). Doing so allows Blueprint to infer details and generate even more code automatically. + + +#### Statements +Blueprint comes with an expressive set of statements which implicitly define additional components to generate. Each statement is a `key: value` pair. + +The `key` defines the _type_ of statement to generate. Currently, Blueprint supports the following types of statements: + +