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

Translatablebootforms Laravel Package

typicms/translatablebootforms

TranslatableBootForms extends Laravel’s BootForms to simplify multilingual form building. It generates locale-aware translatable fields, often with language tabs, so TypiCMS and Laravel apps can edit content across languages in one Bootstrap-styled form.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the stack first. This package was last released in 2015 and targets the Laravel 5 / BootForms era. Before installing, check that your app is on a compatible Laravel version and that typicms/translatable-style models are in use. On modern Laravel, expect to fork or copy the pattern rather than use the package as-is.

Minimal setup:

  1. Require the package and its BootForms dependency, pinning versions if your app is old enough to use it:
    composer require typicms/translatablebootforms
    
  2. Register the package service provider and facade alias. This package predates Laravel package discovery, so add them manually in config/app.php following the package source/readme. Register it after the BootForms provider.
  3. Confirm which locale configuration the package reads. In TypiCMS projects this is usually a TypiCMS locale list, but verify in the service provider or form-builder class; the package does not ship extensive docs.
  4. Ensure your model uses the TypiCMS translatable trait, declares $translatable, and has a translations relationship.

Where to look first:

  • src/ for the service provider and the class extending BootForms.
  • The form-builder methods for translatable* helpers or locale-tab rendering.
  • The package views, if tabs are rendered by Blade rather than PHP.
  • Your model’s translate($locale) / translation accessor behavior.

First use case: an admin edit form for a translatable Page model. Assuming the facade alias is TranslatableBootForm and the standard BootForms API is available:

{!! BootForm::open()->put()->action(route('admin.pages.update', $page))->bind($page) !!}

{!! TranslatableBootForm::text('title', 'Title') !!}
{!! TranslatableBootForm::textarea('body', 'Body') !!}

{!! BootForm::submit('Save') !!}
{!! BootForm::close() !!}

The important behavior is that each translatable field is rendered once per locale, with names like title[en], and existing values are read from the model’s translation for that locale. Verify the exact helper names in the package source; the public API is small and the README is thin.

Implementation Patterns

Tabbed locale editing. Use the package helpers for fields you want inside locale tabs, and keep non-translatable fields outside the tab group. This gives editors a single form with one tab per language while preserving Bootstrap markup.

{!! BootForm::open()->put()->action(route('admin.pages.update', $page))->bind($page) !!}

{!! BootForm::text('slug', 'Slug') !!}

{{-- One translatable field group per locale, typically rendered as tabs --}}
{!! TranslatableBootForm::text('title', 'Title') !!}
{!! TranslatableBootForm::textarea('body', 'Body') !!}

{!! BootForm::submit('Save') !!}
{!! BootForm::close() !!}

Manual locale loop fallback. If the helper does not cover a field type, or you need custom markup, bypass the helper and generate locale-keyed fields yourself. This is also the safest pattern if you are reimplementing the package on a newer stack:

@foreach (config('typicms.locales') as $locale)
    <div class="tab-pane" id="locale-{{ $locale }}">
        {!! BootForm::text(
            "title[$locale]",
            "Title ($locale)",
            $page->translate($locale)->title ?? null
        ) !!}
    </div>
@endforeach

Controller binding and eager loading. Bind the model in the controller and load translations before rendering. For an edit form, binding the model is what lets the package resolve each locale’s existing translation. For create forms, bind a new model instance so the helpers still have something to inspect.

public function edit(Page $page)
{
    $page->load('translations');

    return view('admin.pages.edit', compact('page'));
}

Validation by locale. Because inputs are arrays keyed by locale, validation rules should be locale-aware, for example title.en, title.fr, or array rules such as title.*. Render errors beside the field for the matching locale rather than dumping all errors at the top of the form.

'title.en' => 'required|string|max:255',
'title.fr' => 'required|string|max:255',
'body.*'   => 'nullable|string',

Old input and repopulation. Check that old input survives validation redirects. With locale-keyed names, the relevant keys are usually old('title.'.$locale) or old("title.$locale"), depending on how your form builder flattens names. If the package does not repopulate old input correctly, fall back to the manual loop and pass old input explicitly.

Mix translatable and shared fields. Keep fields such as status, parent ID, template, or publish date outside the locale tabs. Only language-specific content belongs in the translatable group. This keeps the form scannable and avoids duplicating non-translatable controls per locale.

Reusable Blade partial. If several resources need the same multilingual form, extract a partial that loops locales and renders a tab pane per locale. Pass the model, the field definitions, and the active locale. This gives you control over tab IDs and error placement.

Gotchas and Tips

This is an old, low-adoption package. Last release in 2015 and zero dependents means it is effectively unmaintained. Pin versions, expect incompatibilities with modern Laravel, Laravel Collective HTML, and Bootstrap 4/5 markup, and be prepared to fork the small form-builder class.

Locale source mismatch is the most likely failure. The package may read locale configuration from a TypiCMS config key rather than your app config. If tabs are missing or extra locales appear, inspect the service provider and form-builder constructor before changing anything else.

Field names are arrays, not flat strings. A translated field named title is posted as title[en], title[fr], etc. This affects validation rules, old-input keys, error display, and any JavaScript that targets inputs by name. Inspect the generated HTML early.

The model must be genuinely translatable. The helper expects TypiCMS-style translation methods and a translations relation. If translate() is missing or $translatable does not list the field, you will get null values or exceptions. Verify with:

dd($page->translatable, $page->translate('en'));

Null translations and fallback behavior. A model may not have a translation row for every configured locale. Decide whether blank fields are acceptable or whether you want fallback values from the default locale. Do not assume the package handles fallback beyond what your model accessor does.

Provider and alias order. Register the package after BootForms and after the TypiCMS translatable provider. A missing or conflicting facade alias produces “class not found” or a form builder without the translatable helpers.

Tab IDs and Bootstrap JavaScript. If tabs are generated, ensure IDs are unique when multiple translatable forms appear on one page. Bootstrap tab markup is version-specific; old Bootstrap 3 markup will not activate correctly under Bootstrap 5 without attributes such as data-bs-toggle.

Debugging checklist. Dump the resolved locales, dump $model->translate($locale), inspect the rendered input names, and confirm old input after a failed validation request. Most issues are locale config, missing translation rows, or array-name handling rather than the form builder itself.

Extension point. The cleanest long-term approach is to subclass or wrap the form builder, or extract the locale-tab pattern into your own Blade component. BootForms itself supports macros in many versions; use a macro for repeated translatable field groups if the package API is too limited.

Consider a modern replacement for new work. For new projects, the same outcome is straightforward with Laravel Collective or plain Blade plus a locale loop and a small tab component. The package’s real value is the pattern—locale-aware field names, model translation binding, and grouped tabs—not the 2015 implementation.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons