15web/filament-tree

Tree builder for Eloquent models

1 2025-04-25 07:05 UTC

This package is auto-updated.

Last update: 2025-04-25 07:58:29 UTC


README

Latest Version on Packagist Build and check code status PHP Version Laravel Version Filament Version

Build the tree from your Eloquent model with Filament

This plugin offers a tree builder for the Filament admin panel, allows you to build menu, category tree and etc. and management.

Advantages of the plugin:

  • Isolation of elements (the tree is not rebuilt when editing, when changing a parent - only the changed nodes are re-rendered).
  • “Rememberability” of the collapse state. By default, all nodes are collapsed, as a result, the “children” are not rendered so the page loads quickly.
  • Display of any attributes (available here https://filamentphp.com/docs/3.x/infolists/entries/getting-started) of model in the tree, which can be useful for content visualization
  • The component is all-sufficient as a resource, there is no need for separate pages for creating, editing, listing models.
  • For integration, it is enough to add just a trait (or two, if there was no integration with Nested Set) to the model and specify the name of the attribute that will be used as the node header in the tree.

Dark Theme
Light Theme

Table of Contents:

Installation

Installation

You can install the package via composer:

composer require 15web/filament-tree

Add the plugin service provider to bootstrap/providers.php:

<?php

return [
    // ...
    Studio15\FilamentTree\FilamentTreeServiceProvider::class,
];

Prepare your model

Trait

A.

You have the existing model with Nested Set integration.
Just add InteractsWithTree trait.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Kalnoy\Nestedset\NodeTrait;
use Studio15\FilamentTree\Concerns\InteractsWithTree;

class AwesomeModel extends Model
{
    use NodeTrait;
    use InteractsWithTree;

B.

If your model are "clean", so please follow next steps.

  1. Add NodeTrait and InteractsWithTree traits to the model.
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Kalnoy\Nestedset\NodeTrait;
use Studio15\FilamentTree\Concerns\InteractsWithTree;

class AwesomeModel extends Model
{
    use NodeTrait;
    use InteractsWithTree;
  1. Create new migration
php artisan make:migration add_tree_to_awesome_model --table=awesome_model_table

And add columns:

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('awesome_model_table', function (Blueprint $table) {
            $table->nestedSet();
        });
    }

And run the migration:

php artisan migrate

Tree label attribute

Then please define attribute name of the nodes in your tree, eg. title, add method to the model:

public static function getTreeLabelAttribute(): string
{
    return 'title';
}

Your model is ready.

Create the tree page

To add the tree page to your admin panel,
call artisan command and input name of page and the model class:

php artisan make:filament-tree-page

You can setup fields you need while you create or edit any of tree record. Fill the getCreateForm and getEditForm in your tree page, eg.

public static function getCreateForm(): array
{
    return [
        TextInput::make('title')->required(),
        TextInput::make('slug')->required()->unique(ignoreRecord: true),
    ];
}

public static function getEditForm(): array
{
    return [
        TextInput::make('title')->required(),
        TextInput::make('slug')->required()->unique(ignoreRecord: true),
        Toggle::make('is_published'),
        TextInput::make('description')->nullable(),
    ];
}

Read more about form fields at
https://filamentphp.com/docs/3.x/forms/getting-started

Create Form
Edit form
Delete Confirmation

That's all!
Now you can manage your tree based on the model!

Configuration

  • allow-delete-parent
    You can restrict to delete nodes having children items.

  • allow-delete-root
    You can restrict to delete root nodes, even if 'allow-delete-parent' is true.

  • show-parent-select-while-edit
    If you want to see edit form as compact one, you able to remove parent's select from it. You still can drag'n'drop the nodes.

You can publish config with:

php artisan vendor:publish --tag="filament-tree-config"

Customization

Caption

To display any attribute as second line of node label, please add the method to you model and define the caption value:

public function getTreeCaption(): ?string
{
    return $this->description;
}

Infolist

To display any meta information next to node label, you able to fill the method of your page with Infolist entries, eg.

public static function getInfolistColumns(): array
{
    return [
        TextEntry::make('description')->label(fn(Category $record, Get $get) => $record->description !== null ? 'Desc' : ''),
        IconEntry::make('is_published')->boolean()->label(''),
    ];
} 

Read more at
https://filamentphp.com/docs/3.x/infolists/entries/getting-started#available-entries

Please note,
created tree page extends Filament Page, so all customizations are available.
Get know about at https://filamentphp.com/docs/3.x/panels/pages

Localization

You can publish translations with:

php artisan vendor:publish --tag="filament-tree-translations"

Optionally, you can publish the views using

php artisan vendor:publish --tag="filament-tree-views"

Advanced features

Scope

You can have as many models as you want in your project, and you can add a tree page for each one.
But what if your project has multiple menus (for example, in the header and footer) that have the same attributes? What if the menu items are stored in one table? You can create a separate page for each of your menus using scopes.

To do this, specify the attribute by which the item belongs to the menu (eg. menu_id), add method to your model:

public function getScopeAttributes(): array
{
    return ['menu_id'];
}

In you tree page, specify how exactly you need to get the menu items for a specific admin page:

final class AwesomeTree extends TreePage
{
    public static function getModel(): string|QueryBuilder
    {
        return AwesomeModel::scoped(['menu_id' => 2]);
    }

That's all!

Please read more at
https://github.com/lazychaser/laravel-nestedset?tab=readme-ov-file#scoping

Fix tree

If you have changed the structure of your tree, you need to rebuild the relationships of all nodes.
To do this, use the button "Fix tree" at the footer of your tree page.

Support and feedback

If you find a bug, please submit an issue directly to GitHub. Filament Tree Issues

As always, if you need further support, please contact us. https://www.15web.ru/contacts

Copyright and license

Copyright © Studio 15, 2012 - Present.
Code released under the MIT license.