Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Types Module Laravel Package

tomatophp/filament-types-module

A Filament module from TomatoPHP for managing reusable types across your application. Create, edit, and organize type records in a clean admin interface, then attach them to any model for flexible categorization and classification. Lightweight, easy to install, and simple to integrate into existing...

View on GitHub
Deep Wiki
Context7

Getting Started

This is the first stable (v1.0.0) release of the TomatoPHP Types module, a Filament plugin that gives you a reusable "type" system (think tags/categories/taxonomies) that can be attached polymorphically to any Eloquent model. Since there is no prior assessment to diff against, treat this as a baseline review.

Minimal setup:

  1. Install via Composer — the package is published as tomatophp/filament-types (repo: filament-types-module):
    composer require tomatophp/filament-types
    
  2. Publish and run migrations/config:
    php artisan vendor:publish --tag=filament-types-config
    php artisan vendor:publish --tag=filament-types-migrations
    php artisan migrate
    
  3. Register the plugin in your panel provider (AdminPanelProvider / AppPanelProvider):
    use TomatoPHP\FilamentTypes\FilamentTypesPlugin;
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugins([
                FilamentTypesPlugin::make(),
            ]);
    }
    

Where to look first:

  • config/filament-types.php — toggles navigation group, resource registration, and (if you enable them) translation hooks.
  • TomatoPHP\FilamentTypes\Models\Type — the core model; this is what you will query.
  • TomatoPHP\FilamentTypes\Traits\HasTypes — trait you add to any model to attach types.

First use case: open the generated Types resource in your Filament panel, create a few entries (e.g. Category → News, Category → Blog), then attach the HasTypes trait to a model and sync a type ID onto it. That gives you an admin-managed taxonomy with zero custom migrations on the consuming model.

Implementation Patterns

Attaching types to a model. Add the trait and use the built-in relation:

use TomatoPHP\FilamentTypes\Traits\HasTypes;

class Post extends Model
{
    use HasTypes;
}

$post->types()->attach($typeId);
$post->types; // Collection<Type>
$post->types()->sync([$id1, $id2]);

Filament multi-select in your own resources. Because the relation is a standard BelongsToMany via the morph pivot, you can drop it straight into a form:

use TomatoPHP\FilamentTypes\Models\Type;

Select::make('types')
    ->relationship('types', 'name')
    ->multiple()
    ->preload()
    ->options(fn () => Type::query()->pluck('name', 'id'));

Filter by group in the option query if you only want a subset (e.g. categories, not tags) using the type column on types.

Querying by type. Since it is a morph relation, prefer whereHas over joins to keep morph type constraints intact:

Post::whereHas('types', fn ($q) => $q->where('slug', 'news'))->get();

Cache the type IDs on boot/request scope if you're filtering lists heavily — the extra join is cheap but not free.

Seeding for repeatable environments. Seed your canonical types in a TypeSeeder and use updateOrCreate keyed on slug so deployments are idempotent and re-runs don't duplicate. This matters if you're using the package as a fixed taxonomy rather than as an editor-managed one.

Groups as a scoping mechanism. The type column on the types table is a lightweight grouping bucket. If you're not using it already, adopt it early: Type::where('type', 'category') and Type::where('type', 'tag') keeps a single typeables table serving several concerns without new tables.

Integration with translations. If you composer require tomatophp/filament-translations alongside this, the Type resource should pick up multilingual name editing automatically — you get translated type labels in admin forms and in your Select if you call ->searchable() on it. Verify the translation config is loaded before the types config if you hit a "no locale" error.

Gotchas and Tips

Pivot table is typeables, not type_type. If you're writing manual SQL or migrating data across, do not guess. Check the migration the package published; it's typeables with type_id and typeable_id / typeable_type.

Morph map collisions. If your models use a custom morph map (Relation::enforceMorphMap), make sure the HasTypes::types() relation resolves to the same alias. Otherwise $post->types returns empty even though rows exist. Symptom: pivot rows present, relation empty. Fix: add the alias to the morph map or drop enforcement on models using this trait.

Config and migration publishing tags. --tag=filament-types-migrations and --provider="TomatoPHP\FilamentTypes\FilamentTypesServiceProvider" both work, but the tag is idempotent and re-publishable; use the tag. If you change migrations after publishing, don't re-publish without backing up your edited copy — the tag overwrites.

Production caches. The plugin registers a Filament resource and reads config at boot. After php artisan config:cache in CI, any dynamic toggles in filament-types.php (navigation group, resource visibility) become immutable. Toggle via env vars, or clear and re-cache.

Registering the plugin vs. the service provider. Filament v3/v4 auto-discovers the plugin via ->plugins([...]). If you're on an older Filament version, you may need to add the service provider manually to config/app.php and then register the resource in ->resources([...]). Check your Filament major version against the package's composer.json requirements before installing.

Editing the model. The Type model is shipped, but you can extend it: create App\Models\Type extending TomatoPHP\FilamentTypes\Models\Type, then bind it in your service provider with $this->app->bind(...). Use this to add accessors, custom casts, or scopes — but do this before the migration runs in a fresh install to avoid confusion.

Seeded types + deleted types. When a type is deleted, pivot rows cascade if the FK was set up with cascadeOnDelete. Verify this on your install; some earlier TomatoPHP packages shipped without cascade and left orphaned pivot rows. If you're upgrading into v1.0.0 from an earlier dev branch, run a one-time cleanup of typeables where type_id no longer exists.

Test isolation. If you write feature tests for models using HasTypes, RefreshDatabase plus the package's migration should be enough — but remember the trait's relation is loaded lazily; use $post->load('types') before asserting to avoid an extra query skewing assertQueryCount assertions.

Extension points to know. The Filament resource is registered through the plugin; to customize it (add columns, reorder form fields), use Filament's resource override mechanism rather than editing vendor files. The plugin's make() typically accepts chained configuration (navigation group, slug) — inspect the class before reaching for reflection.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect