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

Translate Plugin Laravel Package

rainlab/translate-plugin

RainLab Translate adds multilingual support to October CMS sites. Translate CMS pages, menus, static content, and model records with per-locale fields, language switching, and a straightforward workflow for building and managing localized websites.

Deep Wiki
Context7

Getting Started

This is not a vanilla Laravel package. rainlab/translate-plugin is an October CMS plugin (namespace RainLab\Translate) built on october/rain. Don't composer require it into a plain Laravel app — it wires into October's plugin registry, backend controllers, CMS Twig runtime and migration system.

Minimal path:

composer require rainlab/translate-plugin
php artisan plugin:enable RainLab.Translate
php artisan october:migrate        # creates rainlab_translate_messages / _attributes / _indexes

Then, in the backend:

  1. Settings → Localization — add locales (e.g. en, fr, de), set the default and fallback locale, and choose whether the URL carries a locale prefix.
  2. Settings → Translate → Messages — the catalogue of translatable strings scraped by the |_ filter.
  3. Add the trait to your first model and wrap a theme string with |_:
class Post extends Model
{
    use \RainLab\Translate\Traits\Translatable;

    public $translatable = ['title', 'content'];
}
<h1>{{ 'Latest news'|_ }}</h1>

The first realistic use case is a two-locale brochure site: add fr, set /fr/... prefixes, translate CMS pages (Static Pages integration adds per-locale tabs automatically), translate a couple of plugin models, and drop {% component 'localePicker' %} into your layout.

Implementation Patterns

Model attribute translation. Read through the current locale; write through a locale-scoped proxy:

$post->title = 'Hello';
$post->save();

$post->translate('fr')->title   = 'Bonjour';
$post->translate('fr')->content = '...';
$post->translate('fr')->save();          // save the proxy, not the parent

Frontend string translation. Three tiers, in fallback order: theme/plugin lang files, the DB-backed message catalogue, then the literal key.

{{ 'Add to cart'|_ }}
{{ 'Hello :name'|_({ name: 'Sam' }) }}
use RainLab\Translate\Models\Message;
echo Message::trans('Hello :name', ['name' => 'Sam']);

The backend Messages screen is the day-to-day workflow for non-developers: they see the source English string, type the target, and the value is stored in rainlab_translate_messages. Import/export there is the practical way to ship translations between environments.

CMS/Static Pages integration. Page titles, content, metadata, and menu item labels get locale tabs in the editor. Translated URLs are generated per locale when the prefix setting is on, so /about and /fr/a-propos can coexist. Pages are resolved by the locale-aware router rather than a hand-rolled middleware.

Locale plumbing. The plugin's middleware resolves locale from the URL prefix (or session, if configured) and calls App::setLocale(). For SEO, include the built-in alternate-hreflang component in your <head>:

{% component 'alternateHrefLangElements' %}

Programmatic switching in components/console code:

use RainLab\Translate\Classes\Translator;
Translator::instance()->setLocale('fr');

Keep that call at the top of any job/command that writes translated data.

Gotchas and Tips

  • Silent non-translation. Only attributes listed in $translatable are translated. A missing entry doesn't error — it just returns the base value, which is easy to miss in review.
  • Proxy saves. Writing $post->translate('fr')->title = ... and then calling $post->save() won't persist. Save the translated model instance.
  • No such thing as an intentional blank. With fallback enabled, an empty translation falls back to the default locale. If you need a deliberately empty value, use a sentinel or store the translation disabled.
  • Slugs and routes. Translated slugs need Sluggable-style generation per locale plus route rebuilds. After changing page URLs or locale prefixes: clear the October cache (php artisan cache:clear) and rebuild the CMS route cache, or you'll chase phantom 404s.
  • Exact-match keys. 'Add to cart'|_ is keyed on the literal string. Editing the English word orphans the translation. For anything long-lived, use dot-keyed messages ('shop.cart.add') instead of prose.
  • Queue/console context. Workers start with app.locale, not the request locale. A job that translates models without setting the locale will happily overwrite the default-language values.
  • Trait interaction. Other behaviors that hook attribute get/set (Sluggable, sortable, translatable relations) can conflict; verify save order and slug generation on each locale, and look at Traits/Translatable.php when a value appears to round-trip incorrectly.
  • Caching. Message lookups and locale config are cached. If you edit rainlab_translate_messages directly or via seeder, flush the cache or you'll debug a translation that "is in the DB but not showing".
  • Backend stays in the default locale — the locale middleware runs on frontend CMS routes. Don't expect the backend edit form to switch language automatically.
  • Extension points: Message::extend() and model events on RainLab\Translate\Models\Message are the natural hooks for custom catalogue loading (e.g. pulling strings from an external translation service); the localePicker component and hreflang component can be overridden in your theme/plugin.
  • Licensing/pin. Composer reports NOASSERTION — read the LICENSE file before commercial use. The last tagged release is October 2022, so test against your October version rather than assuming current-version parity.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo