hyperlinkgroup/linguist
Linguist Connector for Laravel
A package to help you manage your translation files with Linguist — A better way to manage your language files.
Installation
You can install the package via composer:
composer require hyperlinkgroup/linguist
You can optionally publish the config file with:
php artisan vendor:publish --tag="linguist-config"
Quick Start (Setup Wizard)
The easiest way to get started is using the interactive setup wizard:
php artisan linguist:setup
This wizard will guide you through:
- API Token - Enter your Linguist API token
- Project Selection - Choose an existing project or create a new one
- Sync Mode - Select how you want to synchronize translations:
- Sync: Merge local and remote translations (two-way)
- Pull: Download from Linguist (overwrite local)
- Push: Upload local translations to Linguist
- Options - Configure setup preferences and optional auto-translation
Configuration
The published config file (config/linguist.php):
return [
/*
|--------------------------------------------------------------------------
| Linguist API URL
|--------------------------------------------------------------------------
*/
'url' => env('LINGUIST_URL', 'https://api.linguist.eu/v2'),
/*
|--------------------------------------------------------------------------
| Linguist Project Slug
|--------------------------------------------------------------------------
*/
'project' => env('LINGUIST_PROJECT', ''),
/*
|--------------------------------------------------------------------------
| Linguist API Token
|--------------------------------------------------------------------------
*/
'token' => env('LINGUIST_TOKEN', ''),
/*
|--------------------------------------------------------------------------
| Linguist API Token Settings URL
|--------------------------------------------------------------------------
*/
'api_tokens_url' => env('LINGUIST_API_TOKENS_URL', 'https://app.linguist.eu/settings/api-tokens'),
/*
|--------------------------------------------------------------------------
| Temporary Directory for Translations while processing
|--------------------------------------------------------------------------
*/
'temporary_directory' => 'tmp/translations',
/*
|--------------------------------------------------------------------------
| Pull Minified
|--------------------------------------------------------------------------
| When enabled, pulled translation files are written as minified JSON.
| By default, files are pretty-printed for readability and easier diffing.
|--------------------------------------------------------------------------
*/
'pull_minified' => env('LINGUIST_PULL_MINIFIED', false),
];
The setup wizard automatically writes these values to your .env file.
LINGUIST_URL should point to the versioned API base URL (for example https://api.your-domain.com/v2).
LINGUIST_API_TOKENS_URL is the URL opened when users follow the Linguist API settings link printed before the token prompt (clickable in terminals that support hyperlinks; otherwise the label is still shown as plain text).
LINGUIST_PULL_MINIFIED controls whether pulled translation files are written as minified JSON. Defaults to false (pretty-printed).
Commands
linguist:setup
Interactive wizard for initial setup and configuration. Handles project creation/selection, sync mode configuration, and API token management.
linguist:sync
Runs translation synchronization in one of three modes (sync, pull, push).
php artisan linguist:sync
If run interactively, the command prompts for mode selection (same choices as setup).
For scheduler/non-interactive execution, the command defaults to sync mode unless you pass an explicit mode flag:
php artisan linguist:sync --sync
php artisan linguist:sync --pull
php artisan linguist:sync --push
Alternatively, use the --mode option:
php artisan linguist:sync --mode=sync
php artisan linguist:sync --mode=pull
php artisan linguist:sync --mode=push
Mode-specific options:
# sync mode options
php artisan linguist:sync --sync --prune-remote-keys
php artisan linguist:sync --sync --no-activate-missing-languages
php artisan linguist:sync --sync --sync-source=local
php artisan linguist:sync --sync --sync-source=remote
# push mode options
php artisan linguist:sync --push --overwrite
php artisan linguist:sync --push --languages=EN,DE
--prune-remote-keys deletes remote keys that no longer exist locally before upload (sync mode).
--no-activate-missing-languages skips activating local languages that are not yet active in the remote project. Applies to all modes. If omitted, the command prompts interactively or activates automatically in non-interactive contexts.
--sync-source controls which side wins for existing keys in sync mode: remote (default) keeps the remote value, local overwrites with the local value.
Sync Modes
Sync Mode (Recommended)
Performs a two-phase sync:
- Uploads local keys first (
push) - Downloads the resulting remote state (
pull) into local files
Pull Mode
Downloads all translations from Linguist and overwrites local files:
- Fetches all active languages
- Downloads translation files
- Replaces local files entirely in Laravel native locale JSON format (
lang/en.json,lang/de.json, ...)
Push Mode
Uploads local translations to Linguist:
- Reads all local translation files
- Creates/updates keys on remote
- Preserves remote-only keys
Events
The package dispatches Laravel events after successful operations:
Hyperlinkgroup\Linguist\Events\SyncCompletedHyperlinkgroup\Linguist\Events\PullCompletedHyperlinkgroup\Linguist\Events\PushCompleted
Each event contains:
$projectSlug(string)$result(Hyperlinkgroup\Linguist\DTO\SyncResult)
Example listener:
use Hyperlinkgroup\Linguist\Events\SyncCompleted;
use Illuminate\Support\Facades\Event;
Event::listen(SyncCompleted::class, function (SyncCompleted $event): void {
logger()->info('Linguist sync completed', [
'project' => $event->projectSlug,
'keys_processed' => $event->result->keysProcessed,
]);
});
Advanced Usage
Using Actions Directly
For custom implementations, you can call the provided actions directly:
use Hyperlinkgroup\Linguist\Services\LinguistApiClient;
use Hyperlinkgroup\Linguist\Actions\SyncTranslations;
// API Client
$client = app(LinguistApiClient::class);
$projects = $client->listProjects()->json('data');
// Sync Action
$result = SyncTranslations::run(
projectSlug: 'my-project',
pruneRemoteKeys: true,
);
echo $result->getSummaryMessage();
Data Transfer Objects
The package provides typed DTOs for configuration:
use Hyperlinkgroup\Linguist\DTO\SetupInput;
use Hyperlinkgroup\Linguist\DTO\SetupResult;
use Hyperlinkgroup\Linguist\DTO\SyncResult;
$input = new SetupInput(
apiToken: 'your-token',
projectSlug: 'my-project',
syncMode: 'sync',
pruneRemoteKeys: false,
activateMissingLanguages: true,
);
// From array
$input = SetupInput::fromArray([
'api_token' => 'your-token',
'project_slug' => 'my-project',
]);
// Setup results
$setupResult = app(\Hyperlinkgroup\Linguist\Services\SetupOrchestrator::class)->execute($input);
$setupResult->configPersisted; // bool
$setupResult->projectCreated; // bool
$setupResult->projectSlug; // ?string
$setupResult->syncResult; // ?SyncResult
$setupResult->autoTranslate; // bool
$setupResult->hasErrors(); // bool
// Sync results
$result = SyncTranslations::run(projectSlug: 'my-project');
$result->overallSuccess; // bool
$result->hasPartialSuccess(); // bool
$result->getFailedLanguages(); // array
$result->getSummaryMessage(); // string
Error Handling and Reporting
All sync operations return detailed SyncResult objects with:
- Per-language results: Success/failure status for each language
- Partial success detection: Identify which languages succeeded or failed
- Detailed error messages: Specific failure reasons per language
- Key counts: Total processed and failed key counts
Example output:
Sync Results:
Partial sync completed. 2 languages successful, 1 languages failed. (150 keys processed, 3 failed)
Per-language results:
✓ EN
✓ DE
✗ FR: Failed to download translations
API Endpoints
The package communicates with Linguist's REST API (/v2):
GET /v2/projects- List available projectsPOST /v2/projects- Create new projectGET /v2/projects/{project}- Get project details (including source language)PATCH /v2/projects/{project}- Update projectGET /v2/projects/{project}/languages- List project languagesGET /v2/projects/{project}/export/json/{language}- Get export URLGET /v2/projects/{project}/translation-keys- List translation keysPOST /v2/projects/{project}/translation-keys- Create/update keyPATCH /v2/projects/{project}/translation-keys/{key}- Update keyDELETE /v2/projects/{project}/translation-keys/{key}- Delete keyPOST /v2/projects/{project}/translate- Trigger auto-translation
All endpoints require Bearer token authentication.
Testing
composer test
The test suite includes:
- Unit tests for actions and core orchestration logic
- DTO validation tests
- Legacy integration tests
- HTTP mocking for API interactions
License
The MIT License (MIT). Please see License File for more information.
Related Packages
Powerful PHP database abstraction layer (DBAL) with many features for database s...
Laravel Serializable Closure provides an easy and secure way to serialize closur...
Cli error handling for console/command-line PHP applications.
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| 2.0.0 | ^8.3 | ^12.0| | MIT | |
| 1.0.0 | ^8.1 | ^10.0| | MIT | |
| v0.3.0 | ^8.1 | ^10.0| | MIT | |
| v0.2.1 | ^8.1 | ^10.0 | MIT | |
| v0.2 | ^8.1 | ^10.0 | MIT | |
| v0.1.1 | ^8.1 | ^10.0 | MIT | |
| v0.1 | ^8.1 | ^10.0 | MIT |