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 Translatable Fields Laravel Package

asignua/filament-translatable-fields

Filament Translatable Fields adds locale-aware form fields and table columns to Filament resources, making it easy to edit, display, and manage multilingual content in your admin panel without writing custom UI for every language.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Filament-oriented translation layer: it gives you translatable form tabs, table columns, infolist entries, and model helpers for the same attribute across multiple locales. Treat v1.0.2 as a correctness-focused patch release: no advertised breaking API change, but several real-world bugs around rich editors, Repeaters/Builders, array state, and RelationManagers are fixed.

Minimal setup:

  1. Install via Composer using the package README.
  2. Add the translatable trait/contract to models that store locale maps as JSON or arrays.
  3. Define supported locales once in config or on the component, and reuse that list for forms, columns, entries, and validation labels.
  4. Build one resource form with per-locale tabs, then add a matching table column and infolist entry.

Look first at:

  • README examples for translatable form tabs, TranslatableColumn, and TranslatableEntry.
  • HandlesTranslatableFields for locale helpers, translatableModel(), and requiredAny().
  • Release notes/tests for the v1.0.2 fixes, especially rich-editor empty state and Repeater/Builder context.

First use case: a Post model with title and body translation maps. Create one tab per locale, make at least one locale required with requiredAny(), and use a rich editor for body. Add a table column and infolist entry for quick localized display. This gives immediate day-to-day value without building custom translation UI.

Implementation Patterns

Use the package components instead of hand-rolling locale loops. They carry the record, locale list, and validation context for you.

Typical model setup:

use HandlesTranslatableFields;

class Post extends Model
{
    use HandlesTranslatableFields;

    protected $guarded = [];
}

Form pattern: bind fields to attribute.locale and let the translatable tabs component provide $record, locales(), and requiredAny() context.

// Shape: one schema callback per locale
fn (string $locale) => [
    TextInput::make("title.$locale")
        ->requiredAny(),

    RichEditor::make("body.$locale")
        ->requiredAny()
        ->columnSpanFull(),
]

Validation pattern: use requiredAny() when at least one locale must be filled. In v1.0.2 this now treats an empty Tiptap document as empty, so a post with every body translation empty fails validation as expected. Use normal per-field rules for stricter requirements, such as requiring the default locale.

Tables and infolists:

TranslatableColumn::make('title')
    ->locales(['en' => 'English', 'ru' => 'Русский']);

TranslatableEntry::make('title')
    ->locales(['en' => 'English', 'ru' => 'Русский']);

Repeater/Builder pattern: place translatable tabs inside the repeated schema and use the item's own context. v1.0.2 builds tabs from the injected component rather than a captured $this, so each item should use its own Get, $record, locales(), and requiredAny() context. Do not capture the outer form component in a closure when the field belongs to a repeated item.

RelationManagers: HandlesTranslatableFields::translatableModel() now returns the related model in a RelationManager / ManageRelatedRecords page. If the package cannot infer the model in a custom page, expect a clear exception; override or provide the model resolution explicitly.

Localized validation messages: the factory's own validationAttribute() remains the base of the language-aware message, e.g. заголовок (English). Customize labels on the field/factory if you want a different base name.

Gotchas and Tips

  • v1.0.2 is a patch release, but it can surface previously hidden validation failures. A post that used to save with empty rich-editor translations may now correctly fail requiredAny(). Update tests and expectations accordingly.
  • Rich editor empty state is not just null or ''. The package now recognizes an empty Tiptap document as empty for requiredAny(). Do not add custom “is empty” checks unless you also account for the editor's empty document shape.
  • In Repeaters/Builders, avoid stale closures. Use the injected component and the current item's record/state. If a tab shows the last item's data, check for captured $this or outer $record references.
  • TranslatableEntry and TranslatableColumn now read the entry's own record or array state. For JSON RepeatableEntry items, the translation map should be the item's map, not the parent's attribute. When using ->state([...]) or array records, keep the state keyed by locale.
  • translatableModel() is now safer in relation contexts, but it still needs a resolvable model. If you use a custom page or nonstandard relation manager, verify the related model and provide an explicit override if needed.
  • The composer description no longer promises a chosen-locale API that does not exist. Do not build against an assumed locale()-style helper; check the actual source and README for available locale methods.
  • Debug translation issues by inspecting each item's $record, the component's locales(), and the raw field state per locale. In Repeaters, log inside the item schema callback rather than the parent form.
  • After upgrading, clear cached views/config in the usual Laravel way and run the form/table tests that exercise rich editors, repeaters, and relation managers.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin