vnuswilliams / laravel-autolang
Automatically scan blade files, extract hardcord UI text, wrap laravel trasnlation helpers, and generate JSON and/or PHP trasnlations files
Requires
- php: ^8.2||^8.3||^8.4
- illuminate/console: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/filesystem: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0 || ^13.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0 || ^11.0
- phpunit/phpunit: ^10.0 || ^11.0 || ^12.0 || ^13.1
- dev-main
- v1.2.1
- 1.0.0
- dev-codex/remove-prefixes-from-translation-keys
- dev-codex/update-translation-key-generation-rules
- dev-codex/update-command-for-lang-auto-functionality
- dev-codex/update-handle-function-for-document-rescan
- dev-codex/add-dev-dependency-and-output-format-option
- dev-codex/add-tests-for-validation
- dev-codex/ignore-php-tags-during-scan
- dev-codex/mettre-a-jour-le-document-readme.md
- dev-codex/generate-phpdoc-for-src-directory
- dev-codex/add-locale-flag-to-lang-auto-command
- dev-codex/create-laravel-package-for-auto-translation
This package is auto-updated.
Last update: 2026-05-25 02:43:49 UTC
README
Laravel AutoLang
Laravel AutoLang automates the internationalization of your Blade views by:
- detecting hardcoded text inside
*.blade.phptemplates, - replacing this text with
{{ __('...') }}, - automatically adding missing entries into
lang/<locale>.jsonorlang/<locale>/<file>.php.
The goal is to reduce manual work when setting up or maintaining multilingual support in a Laravel project.
Table of Contents
- Features
- Requirements
- Installation
- Configuration
- Available Command
- Usage Examples
- Supported Scenarios
- Ignored Cases / Known Limitations
- Recommended Team Workflow
- Troubleshooting
- Laravel i18n Best Practices
Features
- Scan one or multiple Blade view directories.
- Detect text segments between HTML tags.
- Automatically replace text with
{{ __('Text') }}. - Generate/update translations in JSON or PHP format.
- Automatically name PHP translation files based on scanned Blade filenames.
- Deduplicate existing translation keys.
- Preview mode (
--dry) before writing changes. - Interactive confirmation (disable with
--force).
Requirements
- PHP version compatible with your Laravel version.
- A Laravel project using the standard structure (
resources/views,lang, etc.). - Write permissions for view files and language directories.
Installation
composer require --dev vnuswilliams/laravel-autolang
Configuration
Publish the configuration file:
php artisan vendor:publish --provider="VnusWilliams\\LaravelAutoLang\\LaravelAutoLangServiceProvider" --tag=config
The config/lang-auto.php file exposes:
return [ 'paths' => [ resource_path('views'), ], 'extensions' => [ '.blade.php', ], 'locale' => 'en', 'output' => 'json', ];
paths
List of directories to scan for *.blade.php files.
Example with multiple locations:
'paths' => [ resource_path('views'), base_path('Modules/Blog/resources/views'), ],
extensions
List of allowed file extensions during scanning.
Default:
'extensions' => ['.blade.php'],
locale
Target locale for translation files.
'locale' => 'fr',
output
Output format: json (default) or php.
When output = php, the PHP translation filename is automatically derived from the scanned Blade filename — no extra configuration is required.
Automatic PHP Translation File Naming
When output = php, the translation file name is generated from the Blade filename according to these rules:
| Blade File | Translation File |
|---|---|
welcome.blade.php |
lang/<locale>/welcome.php |
leave-balance.blade.php |
lang/<locale>/leavebalance.php |
⚡welcome-to.blade.php |
lang/<locale>/welcometo.php |
My_Cool View.blade.php |
lang/<locale>/mycoolview.php |
Applied rules:
- Extensions are removed (
.blade.php→ two passes). - The result is converted to lowercase.
- Any non-Unicode letter or digit character is removed.
With --all, each Blade file produces its own PHP translation file.
Available Command
php artisan lang:auto {path?}
path(optional): relative path fromresources/views(or configured root path), without extension.- If
pathis missing, the command asks interactively. - If the provided path starts with
/, the leading slash is automatically removed.
Example paths:
welcome⟶ searchesresources/views/welcome.blade.phppages/welcome⟶ searchesresources/views/pages/welcome.blade.php
Options:
--all: scan the entire configured directory recursively.--locale=fr: temporarily override the output locale.--output=json|php: choose output format (overrides config).--dry: simulate execution without modifying files.--force: apply changes without confirmation.
With --all, an extra confirmation is requested before starting the global scan (unless --force is present).
Full signature:
php artisan lang:auto {path?} {--all} {--locale=} {--output=} {--dry} {--force}
Usage Examples
1) First Translation Migration (JSON)
php artisan lang:auto --locale=fr
- The package detects hardcoded strings.
- Displays detected strings and impacted files.
- After confirmation, updates views and
lang/fr.json.
2) PHP Output — Automatic Naming
php artisan lang:auto leave-balance --locale=fr --output=php --force
- Scans
resources/views/leave-balance.blade.php. - Automatically creates/updates
lang/fr/leavebalance.php.
3) Global PHP Scan
php artisan lang:auto --all --locale=fr --output=php --force
-
Scans all views.
-
Each view generates its own PHP translation file:
welcome.blade.php→lang/fr/welcome.phphr/leave-balance.blade.php→lang/fr/leavebalance.php
4) Verification Before Commit (Local CI)
php artisan lang:auto --dry
- No files modified.
- Allows reviewing pending changes before applying them.
5) Non-Interactive Execution (Scripts / CI)
php artisan lang:auto --force
Supported Scenarios
Simple HTML Text
Before:
<h1>Welcome</h1>
After:
<h1>{{ __('Welcome') }}</h1>
Preserving Surrounding Spaces
Before:
<p> Hello world </p>
After:
<p> {{ __('Hello world') }} </p>
Apostrophes
Before:
<span>It's ready</span>
After:
<span>{{ __('It\'s ready') }}</span>
JSON Translation Deduplication
If a key already exists in lang/<locale>.json, it is not duplicated.
The file is alphabetically sorted to keep clean diffs.
Ignored Cases / Known Limitations
To avoid false positives, some blocks are ignored during extraction:
<script>...</script><style>...</style>@php ... @endphpblocks- Blade expressions
{{ ... }}and{!! ... !!} - Blade directives (
@if,@foreach, etc.) - Blade components
<x-... />and<x-...>...</x-...>
Important Limitations
-
The package targets text between tags (
>text<).- HTML attributes are not automatically translated (
placeholder,title, etc.).
- HTML attributes are not automatically translated (
-
The package does not translate content:
- it creates key=value entries (example:
"Hello": "Hello").
- it creates key=value entries (example:
-
For highly dynamic or unusual Blade structures, always review changes before committing.
Recommended Team Workflow
-
Create a dedicated branch.
-
Run a dry-run:
php artisan lang:auto --dry
-
Execute for real:
php artisan lang:auto --force
-
Review diffs for:
- modified Blade views,
lang/<locale>/*.phporlang/<locale>.jsonfiles.
-
Commit clearly (example:
chore(i18n): auto-wrap blade strings).
Troubleshooting
"No Blade files found."
- Check paths in
config/lang-auto.php(paths). - Ensure directories exist and contain
*.blade.phpfiles.
"No new translatable strings found."
- Strings may already be translated.
- Content may be inside ignored blocks (
script,style, components, dynamic Blade).
PHP translation file is not created
- Check write permissions for the
lang/directory. - Verify the selected locale (
--localeor config).
Laravel i18n Best Practices
- Use stable and consistent phrases.
- Avoid string concatenation inside views.
- Prefer Laravel placeholders (
__('Welcome :name', ['name' => $name])) for dynamic content. - Add QA/product review for translations.
License
MIT
Reverse Command — --reverse
The --reverse command allows reverting changes: it reads translation values, replaces {{ __('...') }} helpers with raw text in Blade views, then removes used keys from translation files.
php artisan lang:auto {path?} --reverse
php artisan lang:auto --all --reverse
The flag does not take any value. Everything relies on the configuration (locale, output).
Workflow Depending on output
json mode
- Load
lang/<locale>.json - In targeted Blade files, resolve each
{{ __("...") }}→ replace with raw value - Remove used keys from the
.jsonfile and rewrite it
php mode
- List available
.phpfiles inlang/<locale>/and ask for selection interactively - Load translations from the selected file
- In targeted Blade files, resolve each
{{ __("...") }}→ replace with raw value - Remove used keys from the
.phpfile and rewrite it
Key Resolution
The last segment after the final . is used as the lookup key inside translation files.
| Blade Helper | Resolved Key |
|---|---|
{{ __("welcome") }} |
welcome |
{{ __("messages.welcome") }} |
welcome |
{{ __("a.b.c.myKey") }} |
myKey |
If a key is not found in the translation file, the helper remains unchanged.
Full Example
Blade before:
<h1>{{ __("welcome") }}</h1> <p>{{ __("messages.farewell") }}</p>
lang/fr.json:
{
"farewell": "Goodbye",
"welcome": "Welcome"
}
After:
php artisan lang:auto welcome --reverse --locale=fr
Blade result:
<h1>Welcome</h1> <p>Goodbye</p>
lang/fr.json after cleanup:
{}
Compatible Options With --reverse
| Option | Behavior |
|---|---|
--dry |
Preview without modifying files |
--force |
Apply without confirmation |
--all |
Process all configured views |
--locale=fr |
Temporarily override locale |
--output=json|php |
Temporarily override output format |
Limitations
- Only keys present in the selected translation file are resolved.
- HTML attributes (
placeholder,title, etc.) are not handled — consistent with forward behavior. - If
lang/<locale>/contains no.phpfiles, the command stops with a warning.