{"id":13563549,"url":"https://github.com/spatie/nova-translatable","last_synced_at":"2025-05-14T22:08:12.817Z","repository":{"id":33111032,"uuid":"150127712","full_name":"spatie/nova-translatable","owner":"spatie","description":"Making Nova fields translatable","archived":false,"fork":false,"pushed_at":"2024-12-18T10:57:22.000Z","size":964,"stargazers_count":224,"open_issues_count":0,"forks_count":27,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-13T14:19:11.526Z","etag":null,"topics":["laravel","nova","php","translatable","translations"],"latest_commit_sha":null,"homepage":"https://murze.be/making-nova-fields-translatable","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spatie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://spatie.be/open-source/support-us"}},"created_at":"2018-09-24T15:47:46.000Z","updated_at":"2025-04-04T04:41:05.000Z","dependencies_parsed_at":"2024-06-07T05:50:42.065Z","dependency_job_id":"6d325ea7-b372-43b1-80fe-a9657a72e057","html_url":"https://github.com/spatie/nova-translatable","commit_stats":{"total_commits":94,"total_committers":27,"mean_commits":"3.4814814814814814","dds":0.5,"last_synced_commit":"c51f2ca0f8876a60ad385699db0f727b2b04811c"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fnova-translatable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fnova-translatable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fnova-translatable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fnova-translatable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spatie","download_url":"https://codeload.github.com/spatie/nova-translatable/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235698,"owners_count":22036963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","nova","php","translatable","translations"],"created_at":"2024-08-01T13:01:20.498Z","updated_at":"2025-05-14T22:08:07.787Z","avatar_url":"https://github.com/spatie.png","language":"PHP","funding_links":["https://spatie.be/open-source/support-us"],"categories":["PHP"],"sub_categories":[],"readme":"# Making Nova fields translatable\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/nova-translatable.svg?style=flat-square)](https://packagist.org/packages/spatie/nova-translatable)\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spatie/nova-translatable/run-tests.yml?branch=main\u0026style=flat-square\u0026label=Tests)\n![Check \u0026 fix styling](https://img.shields.io/github/actions/workflow/status/spatie/nova-translatable/php-cs-fixer.yml?branch=main\u0026style=flat-square\u0026label=Check%20%26%20fix%20styling)\n[![Total Downloads](https://img.shields.io/packagist/dt/spatie/nova-translatable.svg?style=flat-square)](https://packagist.org/packages/spatie/nova-translatable)\n\nThis package contains a `Translatable` class you can use to make any Nova field type translatable.\n\nImagine you have this `fields` method in a `Post` Nova resource:\n\n```php\npublic function fields(Request $request)\n{\n    return [\n        ID::make()-\u003esortable(),\n\n        Translatable::make([\n            Text::make('title'),\n            Trix::make('text'),\n        ]),\n    ];\n}\n```\n\nThat `Post` Nova resource will be rendered like this.\n\n![screenshot]( https://spatie.github.io/nova-translatable/screenshot.png)\n\n## Support us\n\n[\u003cimg src=\"https://github-ads.s3.eu-central-1.amazonaws.com/nova-translatable.jpg?t=1\" width=\"419px\" /\u003e](https://spatie.be/github-ad-click/nova-translatable)\n\nWe invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).\n\nWe highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).\n\n## Requirements\n\nThis Nova field requires Nova 4 or 5 specifically and MySQL 5.7.8 or higher.\n\n## Installation\n\nFirst you must install [spatie/laravel-translatable](https://github.com/spatie/laravel-translatable) into your Laravel app. In a nutshell, this package will store translations for your model in a json column in your table. On top of that, it provides many handy functions to store and retrieve translations. Be sure to read [the entire readme of laravel-translatable](https://github.com/spatie/laravel-translatable/blob/master/README.md) before using this Nova package.\n\nNext, you can install this Nova package into a Laravel app that uses [Nova](https://nova.laravel.com) via composer:\n\n```bash\ncomposer require spatie/nova-translatable\n```\n\n## Usage\n\nIn order to use the package you must first let `Translatable` know which locales your app is using using the `Translatable::defaultLocales()` method. You can put this code in `AppServiceProvider` or a dedicated service provider of your own.\n\n```php\n// in any service provider\n\n\\Spatie\\NovaTranslatable\\Translatable::defaultLocales(['en', 'fr']);\n```\n\nNext, you must prepare your model [as explained](https://github.com/spatie/laravel-translatable#making-a-model-translatable) in the readme of laravel-translatable. In short: you must add `json` columns to your model's table for each field you want to translate. Your model must use the `Spatie\\Translatable\\HasTranslations` on your model. Finally, you must also add a `$translatable` property on your model that holds an array with the translatable attribute names.\n\nNow that your model is configured for translations, you can use `Translatable` in the related Nova resource. Any fields you want to display in a multilingual way can be passed as an array to `Translatable. \n\n```php\npublic function fields(Request $request)\n{\n    return [\n        ID::make()-\u003esortable(),\n\n        Translatable::make([\n            Text::make('title'),\n            Trix::make('text'),\n        ]),\n    ];\n}\n```\n\n### Making translations searchable\n\nEvery translation of the translated fields should be added into the `$search` array separately.\n\n```php\n/**\n * The columns that should be searched.\n *\n * @var array\n */\npublic static $search = [\n    'id', 'name-\u003een', 'name-\u003efr',\n];\n```\n\n### Customizing the locales per translatable\n\nIf you have a Nova resource where you want different locales than the ones configured globally, you can call the `locales` method on `Translatable`.\n\n```php\nTranslatable::make([\n    Text::make('title'),\n    Trix::make('text'),\n])-\u003elocales(['de', 'es']),\n```\n\nThese fields will now use the `de` and `es` locales.\n\n### Customizing the name of a translatable\n\nBy default translatable fields get ` ($locale)` appended to their name. You can customize this behaviour globally by providing a closure to `displayLocalizedNameByDefaultUsing` on `Translatable`. This callback will be used to render the localized field names.\n\n```php\nTranslatable::displayLocalizedNameByDefaultUsing(function(Field $field, string $locale) {\n   return ucfirst($field-\u003ename) . \" [{$locale}]\";\n})\n```\n\nWith this in place all names of translatable fields will get ` [$locale]` appended.\n\nYou can also customize the localized field name per resource by passing a closure the `displayLocalizedNameUsing` function. \n\n```php\nTranslatable::make([\n    Text::make('title'),\n    Trix::make('text'),\n])-\u003edisplayLocalizedNameUsing(function(Field $field, string $locale) {\n   return ucfirst($field-\u003ename) . \" --- {$locale}]\";\n}),\n```\n\nWith this in place, the localized field names will be suffixed with ` --- $locale`.\n\nOf course you can still customize the name of a field as usual.\n\n```php\nTranslatable::make([\n    Text::make('My title', 'title'),\n    Trix::make('text'),\n])-\u003edisplayLocalizedNameUsing(function(Field $field, string $locale) {\n   return ucfirst($field-\u003ename) . \" [{$locale}]\";\n}),\n```\n\nUsing the code about above the name for the `title` field will be \"My title ['en']\".\n\n### Customizing the rules of a translatable\n\nYou may use the regular Nova functionality to define rules on the fields inside your Translatable fields collection. However, this will apply those rules to all locales. If you wish to define different rules per locale you can do so on the Translatable collection.\n\n```php\nTranslatable::make([\n    Text::make('My title', 'title'),\n    Trix::make('text'),\n])-\u003erules([\n        'title' =\u003e ['en' =\u003e 'required', 'nl' =\u003e 'nullable'],\n        'text' =\u003e ['en' =\u003e 'required|min:10', 'nl' =\u003e 'nullable|min:10'],\n    ]\n),\n```\n\nYou may also use the more fluent `rulesFor()` method, which allows you to define rules per field per locale.\n\n```php\nTranslatable::make([\n    Text::make('My title', 'title'),\n    Trix::make('text'),\n])-\u003erulesFor('title', 'en', 'required')\n-\u003erulesFor('title', 'nl', 'nullable'),\n```\n\nThere are also methods for update and creation rules called `creationRules()`, `updateRules()`, `creationRulesFor()` and `updateRulesFor()`. They function in the same way as the `rules()` and `rulesFor()` methods.\n\n## On customizing the UI\n\nYou might wonder why we didn't render the translatable fields in tabs, panels or with magical unicorns displayed next to them. The truth is that everybody wants translations to be displayed a bit different. That's why we opted to keep them very simple for now.\n\nIf Nova gains the ability to better structure a long form natively, we'd probably start leveraging that in a new major version of the package.\n\n### Testing\n\n```bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.\n\n### Security\n\nIf you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.\n\n## Credits\n\n- [Freek Van der Herten](https://github.com/freekmurze)\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Fnova-translatable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspatie%2Fnova-translatable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Fnova-translatable/lists"}