Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/spatie/laravel-view-models

View models in Laravel
https://github.com/spatie/laravel-view-models

laravel models php view

Last synced: 3 months ago
JSON representation

View models in Laravel

Awesome Lists containing this project

README

        

# View models in Laravel

[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-view-models.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-view-models)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-view-models/run-tests.yml?branch=main&label=Tests&style=flat-square)
[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-view-models.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-view-models)

Have you ever made a controller where you had to do a lot of work to prepare variables to be passed to a view? You can move that kind of work to a so called view model. In essence, view models are simple classes that take some data, and transform it into something usable for the view.

You'll find a more detailed explanation and some good examples in [this blogpost on Stitcher.io](https://stitcher.io/blog/laravel-view-models).

Laravel's native view composers are not the same as the view models provided by this package. To learn more about the differences head over to [this blogpost on Stitcher.io](https://stitcher.io/blog/laravel-view-models-vs-view-composers).

## Support us

[](https://spatie.be/github-ad-click/laravel-view-models)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

## Installation

You can install the package via composer:

```bash
composer require spatie/laravel-view-models
```

## Usage

A view model is a class where you can put some complex logic for your views. This will make your controllers a bit lighter. You can create a view model by extending the provided `Spatie\ViewModels\ViewModel`.

```php
class PostViewModel extends ViewModel
{
public $user;

public $post;

public $indexUrl = null;

public function __construct(User $user, Post $post = null)
{
$this->user = $user;
$this->post = $post;

$this->indexUrl = action([PostsController::class, 'index']);
}

public function post(): Post
{
return $this->post ?? new Post();
}

public function categories(): Collection
{
return Category::canBeUsedBy($this->user)->get();
}
}
```

Then you can use the view model class in your controller like this:

```php
class PostsController
{
public function create()
{
$viewModel = new PostViewModel(
current_user()
);

return view('blog.form', $viewModel);
}

public function edit(Post $post)
{
$viewModel = new PostViewModel(
current_user(),
$post
);

return view('blog.form', $viewModel);
}
}
```

In a view you can do this:

```blade

@foreach ($categories as $category)
{{ $category->name }}
@endforeach

Back
```

All public methods and properties in a view model are automatically exposed to the view. If you don't want a specific method to be available in your view, you can ignore it.

```php
class PostViewModel extends ViewModel
{
protected $ignore = ['ignoredMethod'];

// …

public function ignoredMethod() { /* … */ }
}
```

All PHP's built in magic methods are ignored automatically.

#### View models as responses

It's possible to directly return a view model from a controller.
By default, a JSON response with the data is returned.

```php
class PostsController
{
public function update(Request $request, Post $post)
{
// …

return new PostViewModel($post);
}
}
```

This approach can be useful when working with AJAX submitted forms.

It's also possible to return a view directly:

```php
class PostsController
{
public function update(Request $request, Post $post)
{
// …

return (new PostViewModel($post))->view('post.form');
}
}
```

Note that when the `Content-Type` header of the request is set to JSON,
this approach will also return JSON data instead of a rendered view.

#### Exposing view functions

View models can expose functions which require extra parameters.

```php
class PostViewModel extends ViewModel
{
public function formatDate(Carbon $date): string
{
return $date->format('Y-m-d');
}
}
```

You can use these functions in the view like so:

```blade
{{ $formatDate($post->created_at) }}
```

### Making a new view model

The package included an artisan command to create a new view model.

```bash
php artisan make:view-model HomepageViewModel
```

This view model will have the `App\ViewModels` namespace and will be saved in `app/ViewModels`.

or into a custom namespace, say, `App\Blog`

```bash
php artisan make:view-model "Blog/PostsViewModel"
```

This view model will have the `App\Blog\ViewModels` namespace and will be saved in `app/Blog/ViewModels`.

### Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

## Contributing

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

### Security

If you've found a bug regarding security please mail [[email protected]](mailto:[email protected]) instead of using the issue tracker.

## Credits

- [Brent Roose](https://github.com/brendt)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.