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 Astrotomic Laravel Package

fnx-software/filament-astrotomic

A Filament plugin for Astrotomic Translatable models that simplifies multilingual content management. Edit translations directly in Filament forms and tables with locale-aware fields, tabs, and validation, reducing custom code and making translated records easy to maintain across your admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

This package extends Filament's form/table/infolist components so translated model attributes work out of the box with spatie/laravel-translatable-style models. You get three main building blocks: TranslatableSelect (form field), TranslatableColumn (table column), and TranslatableEntry (infolist entry).

  1. Install and publish config (if applicable), then confirm your translatable models use the package's translation trait/table setup.
  2. Start with the simplest case — a TranslatableSelect on a relationship whose label lives in the translation table:
TranslatableSelect::make('department_id')
    ->label('Department')
    ->translatableRelationship('department', 'name')
    ->searchable()
    ->preload();
  1. First real-world use case: a form select for a related record (department, category, author) that must show the label in the current panel locale, and must be searchable by that translated label.

In v2.1.0 the recommended starting point for anything beyond a single translated attribute is the new composite-label API, since it removes the old assumption that translated attributes exist as base-table columns:

TranslatableSelect::make('person_id')
    ->translatableRelationship('person', 'first_name')
    ->translatableLabelUsing(fn (Person $record, string $locale): string => collect([
        $record->translate($locale)?->first_name,
        $record->translate($locale)?->father_name,
        $record->translate($locale)?->last_name,
    ])->filter()->implode(' '))
    ->translatableSearchAttributes(['first_name', 'father_name', 'last_name']);

Where to look first: the HasTranslatableRecordLabel concern (new in 2.1.0) if you want the same label logic reused across multiple resources instead of repeating closures.

Implementation Patterns

Single translated title attribute. The baseline pattern: pass the relationship name and the translated title attribute. Option loading, labels, and search now resolve through translated records rather than Filament's default relationship title column.

Composite translated labels. For names built from multiple translated parts, pair translatableLabelUsing() with translatableSearchAttributes(). The label closure receives the related record and the active locale, so you can call $record->translate($locale) yourself and filter()->implode(' ') to gracefully skip empty parts.

Shared label behavior via the concern. Use HasTranslatableRecordLabel when several selects/infolists need identical label composition. Implement the label logic once on the model (or a dedicated concern), then keep field definitions thin:

TranslatableSelect::make('person_id')
    ->translatableRelationship('person', 'first_name')
    ->translatableLabelUsing(fn (Person $r, string $locale) => $r->translatableRecordLabel($locale));

Keep search and label in sync. Whenever you customize the label, add translatableSearchAttributes() covering the same attributes. Otherwise users see a full name but can only search by the first part — a common support ticket.

Query customization. Use the third modifyQueryUsing argument on translatableRelationship() for scoping and ordering. This is the sanctioned extension point and still works in 2.1.0:

->translatableRelationship(
    relationship: 'department',
    titleAttribute: 'name',
    modifyQueryUsing: fn ($query) => $query->where('active', true)->orderBy('order'),
)

Locale-aware forms. Because the label closure receives the active locale, avoid caching composed labels across locales. Treat the closure as pure and cheap; it runs per option render.

Mix with tables/infolists. TranslatableColumn and TranslatableEntry are unchanged in 2.1.0 — keep using your existing setup for list/detail views, and rely on TranslatableSelect only for form input.

Gotchas and Tips

  • Upgrade payoff for Unknown column errors. If you previously hit Unknown column 'related_table.name' in 'field list', 2.1.0 fixes it by no longer requiring translated attributes to exist on the base table. Upgrading is the fix; you don't need a workaround query anymore.
  • titleAttribute is still required. Even with translatableLabelUsing(), the signature expects a title attribute; keep it pointing at a sensible primary translated field so fallbacks and search defaults behave.
  • Search attributes vs. label closure are independent. Defining a custom label does not automatically make those attributes searchable. Wire translatableSearchAttributes() explicitly, including base-table attributes if you want them searchable too.
  • Null translations. $record->translate($locale) can return null; always null-safe chain (?->first_name) and filter() before implode() to avoid " " labels or stray spaces.
  • Eager loading. Composite labels that touch several translated attributes can N+1 across option lists. Constrain with modifyQueryUsing(fn ($q) => $q->with('translations')) when option counts are large.
  • Don't assume columns on the base table. The 2.1.0 change means query customization that references translated columns directly (e.g. orderBy('name')) may still fail. Order by base-table columns, or join translations deliberately in modifyQueryUsing.
  • Scope is limited. Only TranslatableSelect changed in 2.1.0. Don't expect the new label/search APIs on TranslatableColumn or TranslatableEntry.
  • Debugging empty option lists. Check modifyQueryUsing scopes first, then confirm the active locale actually has translations for the record — a missing translation row silently produces blank labels.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core