Laravel Nova - A Complete Overview
Tags: laravel, programming, beginners, nova
Published: 2023-03-01 18:04:00

Laravel Nova is a premium admin panel for Laravel applications that provides a simple and elegant way to build custom administration panels. It is a part of the Laravel ecosystem, and it is built on top of Laravel's powerful tools and features. Nova has been designed to work with Laravel 5.6 and above and it is created by the same team that created Laravel.

In this post, we will explore the various features of Laravel Nova and how it can be used to create custom administration panels for your Laravel applications.

## Installation

The first step in using Laravel Nova is to install it in your Laravel application. To include the Composer repository in your '_composer.json_' file, simply enter the following command in your command-line interface (CLI):

```sh
composer config repositories.nova '{"type": "composer", "url": "https://nova.laravel.com"}' --file composer.json
```
Afterwards, you can add laravel/nova to the list of required packages in your composer.json file using the following command:

```json
"require": {
    "php": "^8.0",
    "laravel/framework": "^9.0",
    "laravel/nova": "~4.0"
```

Once you have updated your composer.json file, execute the following command in your console terminal to update your dependencies using Composer:

```sh
composer update --prefer-dist
```
After the installation is complete, you need to register the Nova service provider. You can do this by adding the following line of code to the _'providers'_ array in your _'config/app.php'_ file:

```php
'providers' => [
    // ...
    Laravel\Nova\NovaServiceProvider::class,
],
```

Once you have registered the Nova service provider, you need to publish the Nova assets using the following command:

```bash
php artisan nova:install
```

This command will publish the necessary assets for Nova to work, including the Nova configuration file and the Nova service provider.

## Creating a Resource


A resource is a class that defines the data that will be displayed in Nova. You can create a new resource using the '_nova:resource_' Artisan command:

```bash
php artisan nova:resource Post
```

This command will create a new resource file at '_app/Nova/Post.php_'. In this file, you can define the fields that will be displayed for each Post.

```php
<?php

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Http\Requests\NovaRequest;

class Post extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = 'App\Post';

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),

            Text::make('Title')
                ->sortable()
                ->rules('required', 'max:255'),

            Textarea::make('Content')
                ->hideFromIndex()
                ->rules('required'),

            BelongsTo::make('User')
                ->searchable()
                ->sortable(),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param/**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }
}
```

In the '_fields()_' method, we have defined four fields: '_ID_', '_Title_', '_Content_', and '_User_'. The '_ID_' field is an auto-incrementing ID, while the '_Title_' field is a text input field. The '_Content_' field is a textarea input field, and we have used the '_hideFromIndex()_' method to hide it from the index view. The '_BelongsTo_' field is a relationship field that allows us to select a user for each post.

## Registering a Resource

Once we have created a resource, we need to register it with Nova. We can do this by adding it to the '_$resources_' array in the '_NovaServiceProvider_' class. Here is an example:

```php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Laravel\Nova\Cards\Help;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;

class NovaServiceProvider extends NovaApplicationServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        parent::register();

        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerResources();

        parent::boot();
    }

    /**
     * Register the Nova resources for the application.
     *
     * @return void
     */
    protected function registerResources()
    {
        Nova::resources([
            \App\Nova\Post::class,
        ]);
    }

    /**
     * Get the cards that should be displayed on the default Nova dashboard.
     *
     * @return array
     */
    protected function cards()
    {
        return [
            new Help,
        ];
    }

    /**
     * Get the extra dashboards that should be displayed on the Nova dashboard.
     *
     * @return array
     */
    protected function dashboards()
    {
        return [
            // ...
        ];
    }
}

```

In the '_registerResources()_' method, we have registered the '_Post_' resource that we created earlier. We can register multiple resources in this method by adding them to the '_$resources_' array.

## Creating a CRUD Interface

Once we have registered a resource with Nova, we can create a CRUD interface for it. Nova provides a default index view, create view, and edit view for each resource.

To access the CRUD interface for a resource, we need to add it to the navigation menu. We can do this by adding it to the '_navigation_' method in the '_NovaServiceProvider_' class:

```php
/**
 * Get the navigation menu for Nova.
 *
 * @return array
 */
protected function navigation()
{
    return [
        [
            'text' => 'Dashboard',
            'url' => '/nova',
            'icon' => 'home',
        ],
        [
            'text' => 'Posts',
            'url' => '/nova/resources/posts',
            'icon' => 'file-text',
        ],
    ];
}
```

In this example, we have added a link to the 
'_Posts_' resource. When we click on this link, we will be taken to the index view for the '_Post_' resource.

## Customizing a Resource

We can customize a resource by adding methods to the resource class. For example, we can add a '_title()_' method to define the title that will be displayed for each resource item:

```php
<?php

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Http\Requests\NovaRequest;

class Post extends Resource
{
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = 'App\Models\Post';

    /**
     * Get the displayable label of the resource.
     *
     * @return string
     */
    public static function label()
    {
        return __('Posts');
    }

    /**
     * Get the displayable singular label of the resource.
     *
     * @return string
     */
    public static function singularLabel()
    {
        return __('Post');
    }

    /**
     * Get the title for the resource.
     *
     * @return string
     */
    public function title()
    {
        return $this->title;
    }

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),

            Text::make(__('Title'), 'title')
                ->sortable()
                ->rules('required', 'max:255'),

            Textarea::make(__('Content'), 'content')
                ->hideFromIndex()
                ->rules('required'),

            BelongsTo::make(__('User'), 'user', User::class)
                ->searchable()
                ->sortable()
                ->rules('required'),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }
}
```

In this example, we have added a '_title()_' method that returns the '_title_' attribute of the post model. This method is called by Nova when displaying each item in the index view and when displaying the title of an item in the edit view.

We can also add methods to customize the behavior of other parts of the resource, such as the cards, filters, and lenses. For example, we can add a '_cards()_' method to define the cards that will be displayed for the resource:

```php
/**
 * Get the cards available for the request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function cards(Request $request)
{
    return [
        new Metrics\PostsPerDay,
        new Metrics\PostsPerUser,
    ];
}
```

In this example, we have added two custom cards: '_PostsPerDay_' and '_PostsPerUser_'. These cards will be displayed in the resource index view.

## Conclusion

Laravel Nova is a powerful administration panel for Laravel applications that provides a convenient and intuitive way to manage your application's data. With its wide range of features and customization options, Laravel Nova can greatly simplify the process of creating and managing complex applications.

In this article, we have covered some of the key features of Laravel Nova, including resource management, customization, and authorization. We have also provided examples of how to create and customize resources in Laravel Nova.

By following the examples provided in this article, you can start using Laravel Nova to build your own powerful administration panel for your Laravel application. Whether you are building a small project or a large-scale application, Laravel Nova can help you streamline your development process and improve the user experience of your application.

We hope you found this article helpful and informative. Happy coding!

Thank you,
J-Sandaruwan.
[linkedin](https://www.linkedin.com/in/j-sandaruwan/)