PHPackages                             unusualdope/filament-model-translatable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. unusualdope/filament-model-translatable

ActiveLibrary[Localization &amp; i18n](/categories/localization)

unusualdope/filament-model-translatable
=======================================

2.1.2.3(6mo ago)582MITPHPPHP ^8.1

Since Mar 27Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/geimsdin/filament-model-translatable)[ Packagist](https://packagist.org/packages/unusualdope/filament-model-translatable)[ RSS](/packages/unusualdope-filament-model-translatable/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (8)Dependencies (4)Versions (8)Used By (0)

Filament-Model-Translatable (plugin)
====================================

[](#filament-model-translatable-plugin)

DESCRIPTION
-----------

[](#description)

Adds the ability to insert translations in content using a language table. For example, you can create a main model that stores the object id and the data that is not translatable, on the lang model you have to define the foreign key for the main object(in this case post\_id) and the one for the language that has always to be "language\_id". Below an example of model definition in YAML for blueprint package:

```
  Post:
    user_id: string
    postStatus_id: string nullable
    relationships:
      belongsTo: PostStatus, \App\Models\User
      hasMany: PostLanguage

  PostLanguage:
    title: string:160
    content: string nullable
    post_id: unsignedInteger
    language_id: unsignedInteger
    relationships:
      belongsTo: Language
```

INSTALLATION
------------

[](#installation)

Simply install using composer

```
composer require unusualdope/filament-model-translatable
```

run then

```
php artisan fmt:install
```

and follow the prompts to publish and run the migrations and create the languages.

don't forget to register the plugin in your panel

```
use Unusualdope\FilamentModelTranslatable\FmtPlugin;
use Filament\Panel;

class AdminPanelProvider extends PanelProvider
{
   public function panel(Panel $panel): Panel
   {
       return $panel
           // ...
           ->plugin(
               FmtPlugin::make()
           );
   }
}
```

HOW TO USE IT
-------------

[](#how-to-use-it)

### MAIN MODEL

[](#main-model)

In the main model use the provided trait "HasTranslation":

```
use Unusualdope\FilamentModelTranslatable\Traits\HasTranslation;

class Post extends Model
{
    use HasTranslation;
}
    //...
```

The plugin assumes that the translatable model is named as the main model + "Language" and the foreign key is the main model name in CamelCase + "Language" (e.g. PostLanguage)

```
protected string $lang_model = __CLASS__ . 'Language';
```

if you want to change the language model name you can do so overwriting the property in your main model

```
    /**
     * Translatable props needed
     */

    protected $lang_model = 'App\Models\PostTranslated'; //fqn of the translatable model
```

the plugin assumes that the foreign key is the standard laravel foreign key (eg: post\_id), if you want to change it you can do so overwriting the property in your main model

```
    /**
     * Specify the foreign key if not the standard one
     */

    protected $lang_foreign_key = 'post_ext_id';
```

if for any reason you want to stop/pause the translat-ability of your model you can set the property $is\_translatable to false

```
    /**
     * Set to false in order to disable the translatable feature
     */

    protected bool $is_translatable = false;
```

On the main model you have to define the fields that will be translatable using standard Filament fields as you would do in a resource, specify them in method setTranslatableFilamentFields(), the make() method has to contain the field names that are present in the database on the Language table

```
    use Filament\Forms\Components\Textarea;
    use Filament\Forms\Components\TextInput;

    public function setTranslatableFilamentFields()
    {
        return [
            TextInput::make('name')
                ->required()
                ->label('Name'),
            TextInput::make('link_rewrite')
                ->maxLength(128)
                ->label('Link Rewrite'),
            TextInput::make('meta_title')
                ->maxLength(128)
                ->label('Meta Title'),
            Textarea::make('meta_description')
                ->maxLength(512)
                ->label('Meta Description'),
            //...
        ];
    }
```

### RESOURCE

[](#resource)

In the RESOURCE when defining the form insert the translatable fields where you want by using the method addTranslatableFieldsToSchema() and passing as parameter the field name exactly as defined in the database and in the main model

```
    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                //translatable
                FeatureGroup::addTranslatableFieldsToSchema('name'),
                //not translatable
                Forms\Components\TextInput::make('position')
                    ->required()
                    ->numeric()
                    ->hidden()
                    ->default(0),
                //translatable
                FeatureGroup::addTranslatableFieldsToSchema('tooltip'),

                //..

            ]);
    }
```

CREATE AND EDIT RESOURCE PAGES
------------------------------

[](#create-and-edit-resource-pages)

On the CREATE page extend

```
Unusualdope\FilamentModelTranslatable\Filament\Resources\Pages\FmtCreateRecord

class CreatePost extends FmtCreateRecord
{
    //..
}
```

instead of the standard `Filament\Resources\Pages\CreateRecord`

On the EDIT page extend

```
Unusualdope\FilamentModelTranslatable\Filament\Resources\Pages\FmtEditRecord

class EditPost extends FmtEditRecord
{
    //..
}
```

instead of the standard `Filament\Resources\Pages\EditRecord`

RESULT
------

[](#result)

You will get a tab that let you change language and fill the content for every language:

[![Fmt Preview Image 1](https://camo.githubusercontent.com/ac1d4916a994b74710acc1123a9f84fdd61a150b49dd7efbf6ea00c3d14c6fe5/68747470733a2f2f756e757375616c646f70652e636f6d2f666d74496d616765732f666d745f7072657669657730312e706e67)](https://camo.githubusercontent.com/ac1d4916a994b74710acc1123a9f84fdd61a150b49dd7efbf6ea00c3d14c6fe5/68747470733a2f2f756e757375616c646f70652e636f6d2f666d74496d616765732f666d745f7072657669657730312e706e67)[![Fmt Preview Image 2](https://camo.githubusercontent.com/e569422fa9a1becc8f16efd2c4e2f0a7432ac260a60b19310b0923a8b5323767/68747470733a2f2f756e757375616c646f70652e636f6d2f666d74496d616765732f666d745f7072657669657730322e706e67)](https://camo.githubusercontent.com/e569422fa9a1becc8f16efd2c4e2f0a7432ac260a60b19310b0923a8b5323767/68747470733a2f2f756e757375616c646f70652e636f6d2f666d74496d616765732f666d745f7072657669657730322e706e67)

DATA RETRIEVAL
--------------

[](#data-retrieval)

The trait HasTranslation provides a method to retrieve the translated data for the current language by using the defined HasOne relationship "currentLanguage", if you want to retrieve the post name in the current language in frontend you can do so by using the following code:

```
$post = Post::find(1);
$post->currentLanguage->name;
```

if you need to access all the data for all the languages you can use the HasMany relationship "languageData", you can do so by using the following code:

```
$post = Post::find(1);
$post->languageData;
```

ISSUES OR SUGGESTIONS
---------------------

[](#issues-or-suggestions)

Please feel free to give any suggestions for improvements or report any issue directly on the gitHub [plugin repository](https://github.com/geimsdin/filament-model-translatable)

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance66

Regular maintenance activity

Popularity14

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~95 days

Recently: every ~57 days

Total

7

Last Release

202d ago

Major Versions

1.0.0 → 2.0.12025-03-07

### Community

Maintainers

![](https://www.gravatar.com/avatar/5653ff5432abd53feee2b3ff11fe02098b9d6fe9175ea66296325d6d5b529244?d=identicon)[geimsdin](/maintainers/geimsdin)

---

Top Contributors

[![geimsdin](https://avatars.githubusercontent.com/u/46976508?v=4)](https://github.com/geimsdin "geimsdin (22 commits)")

### Embed Badge

![Health badge](/badges/unusualdope-filament-model-translatable/health.svg)

```
[![Health](https://phpackages.com/badges/unusualdope-filament-model-translatable/health.svg)](https://phpackages.com/packages/unusualdope-filament-model-translatable)
```

###  Alternatives

[vemcogroup/laravel-translation

Translation package for Laravel to scan for localisations and up/download to poeditor

135304.0k2](/packages/vemcogroup-laravel-translation)[mage-os/module-automatic-translation

Automatic AI content translation for Mage-OS.

277.1k](/packages/mage-os-module-automatic-translation)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
