Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Last active July 18, 2022 18:18
Show Gist options
  • Save innocenzi/9da86be35d8de07a90856b8eb964c5d8 to your computer and use it in GitHub Desktop.
Save innocenzi/9da86be35d8de07a90856b8eb964c5d8 to your computer and use it in GitHub Desktop.
VITL translations
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
/**
* Generates a JSON file with all translations.
*/
class GenerateI18n extends Command
{
protected $signature = 'i18n:generate';
protected $description = 'Generates i18n files.';
public function handle(): int
{
if ($success = $this->writeTranslations()) {
$this->info("Translations written to <comment>{$this->getTranslationFilePath()}</comment>.");
}
return $success ? 0 : 1;
}
/**
* Recursively loads translations in the given directory.
*
* @see https://github.com/GENL/matice
*/
protected function makeFolderFilesTree(string $directory): array
{
$tree = [];
if (! $files = scandir($directory)) {
return [];
}
foreach ($files as $fileName) {
if (Str::startsWith($fileName, '.')) {
continue;
}
$extension = '.' . Str::afterLast($fileName, '.');
$fileName = basename($fileName, $extension);
$tree[$fileName] = [];
if (is_dir($directory . '/' . $fileName)) {
$tree[$fileName] = $this->makeFolderFilesTree($directory . '/' . $fileName);
}
if (is_file($pathName = $directory . '/' . $fileName . $extension)) {
if ($extension === '.json') {
$existingTranslations = $tree[$fileName] ?? [];
$tree[$fileName] = array_merge(
$existingTranslations,
json_decode(File::get($pathName), true)
);
}
if ($extension === '.php') {
$tree[$fileName] = require($pathName);
}
}
}
return $tree;
}
/**
* Gets the translations as an array.
*/
protected function getTranslations(): array
{
return $this->makeFolderFilesTree(resource_path('lang'));
}
/**
* Gets the path to the translation file.
*/
protected function getTranslationFilePath(): string
{
return str_replace('/', \DIRECTORY_SEPARATOR, resource_path('scripts/i18n.json'));
}
/**
* Writes the translations to the file system.
*/
protected function writeTranslations(): bool
{
return (bool) File::put(
$this->getTranslationFilePath(),
preg_replace('/:(\w+)/', '{${1}}', json_encode($this->getTranslations()))
);
}
}
import { createI18n } from 'vue-i18n'
import messages from '../i18n.json'
// ../i18n.json is exported via i18n:generate
// it is also .gitignore'd
// i18n is imported as a Vue plugin in main.ts
export const i18n = createI18n({
locale: 'fr',
fallbackLocale: 'en',
messages,
})
<?php
// ....
/*
|--------------------------------------------------------------------------
| Commands
|--------------------------------------------------------------------------
| Defines the list of artisan commands that will be executed when
| the development server starts.
*/
'commands' => [
'vite:aliases',
'typescript:generate',
'i18n:generate',
'routes:generate',
],
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment