A while ago I ditched the custom admin of this blog in favour of Laravel Nova. As you might have noticed every blog post on murze.be has some tags. Nova ships with many form fields but a field to use tags is not included out of the box. That's why I created my own tags field and released it as spatie/nova-tags-field. In this post I'd like to introduce it to you.

Using the field #

Using the tags field is very easy. You just have to add it to your Nova resource.

namespace App\Nova;

// ...

class BlogPost extends Resource
{
    // ...

    public function fields(Request $request)
    {
        return [
            // ...

            Tags::make('Tags'),

            // ...
        ];
    }
}

And that's all you need to do. This is what the field looks like:

Screenshot of the murze.be admin

When typing a tag, the field will autosuggest existing tags. If you don't want that autosuggesting you can turn it off like this:

return [
   Tags::make('Tags')->withoutSuggestions(),
];

Using types #

The field also has support for multiple tag types. If you want to use multiple tag fields on your resource you could do this:

return [
   Tags::make('Tags')->type('author'),
   Tags::make('Tags')->type('subject'),
];

The first tag field will now only suggest existing authors, the second one will suggest existing subjects.

Allowing only one tag #

If you want to allow only one tag the be picked, you can use the single method.

return [
   Tags::make('Tags')->single(),
];

The field will be rendered as a select form element. It will be populated by the names of the tags already saved.

Administering tags in Nova #

If you want to perform crud actions on the save tags, just create a Nova resource for it. Here's an example.

namespace App\Nova;

use Illuminate\Http\Request;
use Laravel\Nova\Fields\Text;
use Spatie\Tags\Tag as TagModel;

class Tag extends Resource
{
    public static $model = TagModel::class;

    public static $title = 'name';

    public static $search = [
        'name',
    ];

    public function fields(Request $request)
    {
        return [
            Text::make('Name')->sortable(),
        ];
    }
}

Working with tags programmatically #

Under the hood the nova field uses our laravel-tags package, which makes working with tags very easy. Here are a few examples:

// create a model with some tags
$post = Post::create([
   'name' => 'testModel',
   'tags' => ['tag', 'tag2'], //tags will be created if they don't exist
]);

$post->tags; // returns a collection with all attached tags

// attaching tags
$post->attachTag('tag3');
$post->attachTags(['tag4', 'tag5']);

// detaching tags
$post->detachTag('tag3');
$post->detachTags(['tag4', 'tag5']);

// syncing tags
$post->syncTags(['tag1', 'tag2']); // all other tags on this model will be detached

// retrieving models that have any of the given tags
Post::withAnyTags(['tag1', 'tag2']);

// retrieve models that have all of the given tags
Post::withAllTags(['tag1', 'tag2']);

Under the hood our nova-tags-field package will call these methods too.

Closing thoughts #

You'll find the installation instruction of the nova-tags-field on GitHub. If you like this nova field be sure to check out our other two Nova packages:

Even if you're not into Laravel Nova, you probably will find something for your next project in this big list of packages my team has made previously.