Search by

ccast / tagixo-filament

Makrid87

Filament SDK for Tagixo: one admin resource per record type the installed builders register. Succeeds ccast/tagixo-filament 1.x.

Package info

github.com/c-cast/tagixo-filament

pkg:composer/ccast/tagixo-filament

Statistics

Installs: 74

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v2.0.0 2026-11-07 20:59 UTC

README

Filament 5 SDK for Tagixo. One package for every builder: each record type the installed builders register becomes a Filament resource, and the builders you did not buy leave no trace in the panel.

Installation

composer require tagixo/filament

Enable the plugin in your panel provider:

use Tagixo\Filament\TagixoFilamentPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->path('admin')
        ->plugin(TagixoFilamentPlugin::make());
}

Registering the plugin also turns the core's own record CRUD off (Tagixo::disableManagementApi()): two ways in means two sets of rules, and the panel manages records now. What the editor needs — /tagixo/builder/*, the mount page, the record payload and the save — stays on, and the resources link to it. A guest who reaches one of those routes lands on the panel's own login page, in an application that has no login route of its own too.

php artisan migrate
php artisan vendor:publish --tag=tagixo-assets
php artisan filament:assets

The first creates the tables of the core and of every installed builder. The second publishes the builder's own bundle under public/vendor/tagixo/, one directory per package. The third publishes this SDK's stylesheet — the utilities its Blade views are written in, which Filament's own stylesheet does not carry; without it the Theme Builder, the media gallery and the menu tree render as unstyled markup.

What you get

One resource per registered record type: pages, popups, global blocks, layouts, forms, mails, documents, sliders — whichever of them are installed. Each one lists, creates, edits the metadata of and deletes its records, opens the builder, and offers a preview when the type issues preview URLs.

Nothing in here describes a page or a mail: the resource asks the type (Tagixo\Core\Contracts\BuilderTypeContract) for its model, its listing query, its fields and its rules. A builder released tomorrow is administered the day it is installed.

What each builder adds

Beyond its records, a builder can bring the panel features of its own. They are capabilities: each one checks whether its package is there, so nothing has to be configured and nothing breaks when a builder is not installed. Here they are opt-in — the media gallery, the menus, the Theme Builder and the app form target are off until you ask for them.

Form builder, with withAppForms(). The panel is where the interactive layouts of a form — tabs, wizard, groups — are native, so the app form target is offered: the editor proposes them, and its Preview of an app form opens the panel's own page, which renders it as a real Filament form. Every field also gains a Table tab in the editor, where it says how its answers look in a listing.

Use a form the editor drew anywhere in the panel:

use Tagixo\Filament\Forms\FilamentFormColumns;
use Tagixo\Filament\Forms\FilamentFormFilters;
use Tagixo\Filament\Forms\FilamentFormStyles;
use Tagixo\Filament\Forms\Form;

$schema->components(Form::components('contact-us'));          // its fields, as Filament ones

$table->columns(FilamentFormColumns::from('contact-us'))      // the columns the fields asked for
      ->filters(FilamentFormFilters::from('contact-us'));     // and the filters they allow

FilamentFormStyles::scriptFrom('contact-us');                  // the look the editor gave them

Each of those helpers also takes a record id instead of a slug, with forForm($id).

Media library, with withMediaGallery(). The panel gets a section to browse the library, edit what a file says about itself (title, alt text, description, folder) and delete it; uploading goes through the core's MediaService, so thumbnails, variants and the folder rules stay its business. Any Filament form can use the picker of the editor without that section — the same dialog, browsing, upload and external URL included:

use Tagixo\Filament\Forms\Fields\MediaPickerField;

MediaPickerField::make('cover')->images();
MediaPickerField::make('gallery')->images()->multiple()->maxFiles(6);

Page builder, with withThemeBuilder() and withMenus(). The Theme Builder: every template with its three zones — header, body, footer — each saying whether it has been built and opening the editor where that zone actually lives. A header and a footer belong to the template, so they open the layout itself; a body belongs to a page, and a template scoped to a model stands for that model's archive or single page, created the moment its body is first opened. Layouts are a record type of their own (layouts), so they are listed, created and deleted like everything else. withMenus() adds the menus of the site, items and sub-items included.

Document builder. The listing of the documents offers the printed file, from the builder's own download route.

Tuning it

TagixoFilamentPlugin::make()
    ->navigationGroup('Content')          // one group for every Tagixo resource
    ->except(['global-blocks'])            // manage those only from inside the builder
    ->only(['pages', 'forms'])             // or the other way round
    ->icons(['pages' => 'heroicon-o-document'])
    ->resource('pages', MyPageResource::class)    // your own screens for a type
    ->withMediaGallery()                          // the library section
    ->withMenus()                                 // the menus of the site
    ->withThemeBuilder()                          // the Theme Builder
    ->withAppForms()                              // the `app` form target
    ->lockFormTarget('app')                       // or: every form is a panel form
    ->withoutCapability('form-builder');          // nothing from that package at all

config/tagixo-filament.php (publish it with php artisan vendor:publish --tag=tagixo-filament-config) holds the same defaults, plus the resource class of a record type of your own, a capability of your own, the per-model policy map and the Filament mapper of a form field of your own:

'resources' => [
    'recipes' => App\Filament\Resources\RecipeResource::class,
],

A resource of your own extends Tagixo\Filament\Resources\TagixoRecordResource and names its type; override table(), form() or the labels to go further.

class RecipeResource extends TagixoRecordResource
{
    protected static string $tagixoType = 'recipes';
}

The strings of the panel are published with php artisan vendor:publish --tag=tagixo-filament-translations.

Requirements

  • PHP 8.2+
  • filament/filament ^5.0
  • tagixo/core ^0.1, plus at least one builder

The editor routes of the core use config('tagixo.route_middleware') (['web', 'auth'] by default). A panel behind another guard should set that config accordingly, so the same people who reach the panel reach the builder.

Development

The package is developed against the Tagixo monorepo next to it: the path repository in composer.json points at ../../Projects/tagixo/packages/*. Tests boot a Filament panel with the core and the builders:

composer test

The browser suite drives a real panel — ../../Projects/tagixo-filament-sandbox, a Laravel app with Filament, the core, every builder and this package:

npm install
npm run test:e2e

It boots that app with APP_ENV=e2e (so its own database is untouched), seeds the records the specs drive and checks what no PHP test can: that the navigation shows the builders installed, that a row opens the editor of the core and comes back, that a metadata form saves through the type, that a menu tree survives a reload, and that a guest is sent to the panel's login instead of an error.

License

MIT