zpmlabs/i18n-engine-laravel

Laravel package for i18n engine integration.

Installs: 4

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/zpmlabs/i18n-engine-laravel

v1.0.0 2026-02-26 17:41 UTC

This package is auto-updated.

Last update: 2026-02-26 17:44:14 UTC


README

Laravel i18n engine package for translation-table based querying.

Namespace

ZPMLabs\\I18nEngine

Install

composer require zpmlabs/i18n-engine-laravel

Model usage

use ZPMLabs\I18nEngine\Contracts\HasTranslationTable;
use ZPMLabs\I18nEngine\Traits\InteractsWithTranslationTable;

class Article extends Model implements HasTranslationTable
{
	use InteractsWithTranslationTable;

	protected $table = 'articles';
	protected $fillable = ['title'];

	public function translatedColumns(): array
	{
		return ['title'];
	}
}

Query macros

  • withTranslations(?string $locale = null)
  • withTranslationsList()

Configuration

Publish config:

php artisan vendor:publish --tag=i18n-engine-config

Config file: config/i18n-engine.php

return [
	'default_locale' => 'en',
	'query_param' => 'lang',
	'header' => 'Accept-Language',
	'normalize_locale' => true,
	'foreign_key' => 'foreign_id',
	'locale_key' => 'language',
	'table_suffix' => '_translations',
	'skip_locale_changes_for_routes' => [],
	'request_locale_handler' => \ZPMLabs\I18nEngine\Handlers\FilamentLocaleRequestHandler::class,
];

Key notes:

  • table_suffix: suffix for translation tables (example: articles_translations).
  • foreign_key: FK column in translation tables pointing to base model PK.
  • locale_key: locale column in translation tables.
  • normalize_locale: normalizes values like sr-RS,sr;q=0.9 to sr.
  • request_locale_handler: optional class implementing LocaleRequestHandler for custom request-specific locale resolution (Filament handler is default).

Custom request locale handler

If you want to fully control locale detection for specific requests, create your own handler:

namespace App\I18n;

use ZPMLabs\I18nEngine\Contracts\LocaleRequestHandler;

final class AdminLocaleHandler implements LocaleRequestHandler
{
	public function canHandle(object $request): bool
	{
		return method_exists($request, 'is') && $request->is('admin/*');
	}

	public function resolveLocale(object $request, string $queryParam, string $headerName): ?string
	{
		return (string) $request->query($queryParam, 'en');
	}
}

Then set it in config:

'request_locale_handler' => \App\I18n\AdminLocaleHandler::class,

The package calls resolveLocale() on the configured handler and uses the returned value as the locale candidate. Return null (or an empty value) from your handler when you want the default i18n-engine locale flow to continue.

Migration example

Generate migration command

Use the package command to generate a translation-table migration from an existing model table:

php artisan i18n-engine:make App\\Models\\Article

Common options:

  • --connection=: inspect a specific DB connection
  • --path=database/migrations: custom output path
  • --stub=database/stubs/create_translation_table.stub: custom stub path
  • --module=: write migration to Modules/<Module>/Database/Migrations
  • --id-type=uuid|ulid|int: force FK type
  • --all: include all columns except meta/key columns

Examples:

php artisan i18n-engine:make App\\Models\\Article --connection=mysql
php artisan i18n-engine:make App\\Models\\Article --module=Blog
php artisan i18n-engine:make App\\Models\\Article --path=database/migrations/custom --id-type=uuid

The generated migration name pattern is:

  • YYYY_MM_DD_HHMMSS_create_<base_table>_translations_table.php

The command reads package config keys (i18n-engine.table_suffix, i18n-engine.foreign_key, i18n-engine.locale_key) while generating output.

Example for base table articles and translated column title:

Schema::create('articles_translations', function (Blueprint $table) {
	$table->bigIncrements('translation_id');
	$table->unsignedBigInteger('foreign_id');
	$table->string('language', 8);

	$table->string('title')->nullable();

	$table->timestamps();

	$table->unique(['foreign_id', 'language']);
	$table->index('language');
});

This layout matches the package defaults (foreign_id, language, _translations).

Testing

composer test

Test logs are written to:

  • tests/logs/query-builder.log (translation table snapshots + query results)
  • tests/logs/junit.xml (JUnit report)