Search by

amarenkov / laravel-mutable-content-filament

amarenkov

Filament 5 admin panel for laravel-mutable-content: forms and tables built from field definitions, screens to manage fields and lists of values, change log authorship.

Package info

github.com/amarenkov/laravel-mutable-content-filament

pkg:composer/amarenkov/laravel-mutable-content-filament

Statistics

Installs: 18

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 1

v0.6.1 2026-10-10 14:38 UTC

This package is auto-updated.

Last update: 2026-10-10 18:22:04 UTC


README

tests Packagist coverage

A Filament 5 admin panel for amarenkov/laravel-mutable-content.

Builds forms, infolists and tables from model field definitions and makes sure every change made in the admin panel lands in the change log with its author.

Screenshots

A demo bicycle catalog. Nothing below is written by hand: the resources only set the model.

Table built from the field definitions: LOV items with icons, object titles, weight and lengths in their display units. "Gears" and "Color" were added in the admin panel.

Bicycles table

Form: a select with icons for a LOV item, a searchable select for an object reference, inputs in display units.

Bicycle form

Fields of a class: the lock marks fields declared in code, which cannot be deleted; fields added in the admin panel can.

Fields screen

Lists of values: items with icons, added one by one or as a list of labels.

LOV items screen

Features

  • Forms and tables from field definitions. The component is chosen by field type: a toggle for booleans, a select for lists of values and object references, a date picker for dates, a text input by default. Required and immutable flags are applied automatically.
  • Change log. Base pages and actions set the author and the path the change was made from; both go to the core change log table.
  • System records protection. Deletion is hidden, and fields marked "immutable for system objects" are locked on records created by the seeders.
  • Management screens for fields, their usage in classes, lists of values and their items: an administrator adds new fields without a developer and without migrations.
  • Unlisted codes. Codes that are not in a list of values (when the field allows them) are marked in tables and forms, with a filter to find such records.

Requirements

  • PHP 8.4
  • amarenkov/laravel-mutable-content
  • filament/filament ^5.0

Installation

composer require amarenkov/laravel-mutable-content-filament

The management screens are registered explicitly; resource discovery does not find them:

use Amarenkov\MutableContentFilament\Filament\Resources\Fields\FieldResource;
use Amarenkov\MutableContentFilament\Filament\Resources\Fields\Resources\Usage\UsageResource;
use Amarenkov\MutableContentFilament\Filament\Resources\Lovs\LovResource;
use Amarenkov\MutableContentFilament\Filament\Resources\Lovs\Resources\Items\ItemResource;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->resources([
            FieldResource::class,
            UsageResource::class,
            LovResource::class,
            ItemResource::class,
        ]);
}

Usage

Extend resources, pages and actions from this package instead of plain Filament ones:

use Amarenkov\MutableContentFilament\Filament\Resources\Base\Resource;

class ProjectResource extends Resource
{
    protected static ?string $model = Project::class;
    protected static ?string $recordTitleAttribute = 'code';

    public static function getPages(): array
    {
        return [
            'index'  => ListProjects::route('/'),
            'create' => CreateProject::route('/create'),
            'view'   => ViewProject::route('/{record}'),
            'edit'   => EditProject::route('/{record}/edit'),
        ];
    }
}
use Amarenkov\MutableContentFilament\Filament\Resources\Base\Pages\CreateRecord;

class CreateProject extends CreateRecord
{
    protected static string $resource = ProjectResource::class;
}

There is no need to define form(), infolist() or table(): they are built from the field definitions.

Tuning a single component

formComponentsFromFields() returns components keyed by field code, so you can adjust one component without rebuilding the form:

protected static function formComponentsFromFields(?array $scopes = null)
{
    $components = parent::formComponentsFromFields($scopes);

    $components['field_type']->live();

    $components['lov_code']->hidden(
        fn (Get $get) => $get('field_type') !== FieldType::TYPE_LOV_ITEM
    );

    return $components;
}

Saving

Wrap custom saves in SaveHelper::save(): a unique constraint violation or a DomainException thrown by the model is shown as a notification instead of a server error, and the transaction is rolled back.

Translations

UI strings are in lang/{en,ru}/ui.php under the mutable-content-filament namespace. Publish them to override:

php artisan vendor:publish --tag=mutable-content-filament-lang

Caveats

Extending plain Filament classes instead of the ones from this package does not throw, but silently breaks three things: forms get raw jsonb instead of flat fields, the change log loses the author, and deletion of system records is no longer blocked.

License

MIT. See LICENSE.