spatie/laravel-view-models

repository·main·Indexed 22 days ago

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

A Laravel package that introduces View Models to encapsulate the logic required to prepare data for views, helping to clean up controllers. It allows public properties and methods of classes extending Spatie\ViewModels\ViewModel to be automatically exposed to Blade templates. Includes the make:view-model Artisan command for scaffolding and supports returning view models as either rendered views or JSON responses.

Tokens
1.4K
Snippets
7
Records
7
Agent score
28%

What's inside spatie/laravel-view-models

  1. How view models work in Laravel

    main

    A view model is a class used to transform data and encapsulate complex logic required by a view, making controllers lighter.

    To create one, extend Spatie\ViewModels\ViewModel. All public properties and methods are automatically exposed to the view.

    Key Behaviors:

    • Automatic Exposure: Any public property or method can be accessed directly in Blade using the variable name (e.g., $property or $method()).
    • Ignoring Methods: If you want to prevent a public method from being accessible in the view, add its name to the $ignore protected property.
    • Function Arguments: You can expose methods that require parameters. In Blade, these are called using the syntax {{ $methodName($argument) }}.
    • Magic Methods: PHP's built-in magic methods are automatically ignored and not exposed to the view.
    class PostViewModel extends ViewModel
    {
        protected $ignore = ['ignoredMethod'];
    
        public $post;
    
        public function __construct(Post $post)
        {
            $this->post = $post;
        }
    
        public function ignoredMethod() { /* Not available in view */ }
    
        public function formatDate(\Carbon $date): string
        {
            return $date->format('Y-m-d');
        }
    }
  2. Use a view model in a controller

    main

    You can use view models in two primary ways within your controllers:

    1. Passing to a view

    Instantiate the view model and pass it as the second argument to the view() helper. All public data will be available in the Blade template.

    2. Returning as a response

    • JSON Response: If you return the view model instance directly from a controller method, it will return a JSON response containing the view model's data. This is useful for AJAX requests.
    • Rendered View: To return a specific view instead of JSON, call the ->view('view.name') method on the view model instance. Note: If the request has a Content-Type: application/json header, this will still return JSON instead of the rendered view.
    // Passing to a view
    public function create()
    {
        $viewModel = new PostViewModel(current_user());
        return view('blog.form', $viewModel);
    }
    
    // Returning as a JSON response (useful for AJAX)
    public function update(Request $request, Post $post)
    {
        return new PostViewModel($post);
    }
    
    // Returning a specific view
    public function update(Request $request, Post $post)
    {
        return (new PostViewModel($post))->view('post.form');
    }
  3. Access view model data in Blade templates

    main

    Once a view model is passed to a view, you can access its public properties, methods, and even methods with arguments directly.

    {{-- Accessing a public property --}}
    <input type="text" value="{{ $post->title }}" />
    
    {{-- Iterating over a public method result --}}
    @foreach ($categories as $category)
        <option value="{{ $category->id }}">{{ $category->name }}</option>
    @endforeach
    
    {{-- Calling a method with arguments --}}
    {{ $formatDate($post->created_at) }}
    
    {{-- Accessing a property used as a URL --}}
    <a href="{{ $indexUrl }}">Back</a>
  4. Create a new view model using Artisan

    main

    Use the included Artisan command to scaffold a new view model class. By default, they are placed in the app/ViewModels directory with the App\ViewModels namespace.

    # Create a view model in the default namespace
    php artisan make:view-model HomepageViewModel
    
    # Create a view model in a custom sub-namespace
    php artisan make:view-model "Blog/PostsViewModel"