Coder Social home page Coder Social logo

kkomelin / laravel-translatable-string-exporter Goto Github PK

View Code? Open in Web Editor NEW
294.0 7.0 38.0 194 KB

Translatable String Exporter for Laravel

License: MIT License

PHP 99.95% Blade 0.05%
laravel translations export exporter json localization translation

laravel-translatable-string-exporter's Introduction

Translatable String Exporter for Laravel

Tests Status Badge PHPStan Status Badge Code Styles Check Badge

You can use __('Translate me') or @lang('Translate me') with translations in JSON files to translate strings. Translatable String Exporter is aimed to collect all translatable strings of an application and create corresponding translation files in JSON format to simplify the process of translation.

Versions

Package PHP
<=1.15.1 5.6
>1.15.1 ^7.2|^8.0
>1.18.0 ^8.0

Even though we drop support for PHP versions in minor releases, Composer ensures that users with previous versions of PHP don't get not-yet-supported PHP code.

Installation

Normally, it's enough to install the package as a development dependency.

composer require kkomelin/laravel-translatable-string-exporter --dev

Configuration

To change project defaults, use the following command to create a configuration file in your config/ folder and make necessary changes in there:

php artisan vendor:publish --provider="KKomelin\TranslatableStringExporter\Providers\ExporterServiceProvider"

Usage

Export translatable strings

php artisan translatable:export <lang>

Where <lang> is a language code or a comma-separated list of language codes. For example:

php artisan translatable:export es
php artisan translatable:export es,bg,de

The command with the "es,bg,de" parameter passed will create es.json, bg.json, de.json files with translatable strings or update the existing files in the lang/ folder of your project.

Find untranslated strings in a language file (command)

To inspect an existing language file (find untranslated strings), use this command:

php artisan translatable:inspect-translations fr

The command only supports inspecting one language at a time.

To export translatable strings for a language and then inspect translations in it, use the following command:

php artisan translatable:inspect-translations fr --export-first

Find untranslated strings in a language file (IDE)

An alternative way to find untranslated strings in your language files is to search for entries with the same string for original and translated. You can do this in most editors using a regular expression.

In PhpStorm and VSCode, you can use this pattern: "([^"]*)": "\1"

Persistent strings

Some strings are not included in the export, because they are being dynamically generated. For example:

{{ __(sprintf('Dear customer, your order has been %s', $orderStatus)) }}

Where $orderStatus can be 'approved', 'paid', 'cancelled' and so on.

In this case, you can add the strings to the <lang>.json file manually. For example:

  ...,
  "Dear customer, your order has been approved": "Dear customer, your order has been approved",
  "Dear customer, your order has been paid": "Dear customer, your order has been paid",
  ...

In order for those, manually added, strings not to get removed the next time you run the export command, you should add them to a json file named persistent-strings.json. For example:

[
  ...,
  "Dear customer, your order has been approved",
  "Dear customer, your order has been paid",
  ...
]

License & Copyright

MIT, (c) 2017-present Konstantin Komelin and contributors

laravel-translatable-string-exporter's People

Contributors

blair2004 avatar dacoto97 avatar efriandika avatar g3z avatar hannoma avatar kkomelin avatar kohlerdominik avatar laravel-shift avatar mabdelrahman91 avatar phh avatar remcom avatar t1sh0o avatar taoufiqaitali avatar tommyschmiedel avatar wilsenhc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-translatable-string-exporter's Issues

Strings containing round brackets are truncated improperly

Problem/Motivation:

As reported here #44

The string with round brackets

throw new ExternalCrmException(sprintf(__('A required parameter ("%s") was not found.'), $requiredParameter));

results in the following:

{
    "A required parameter (\"%s": "A required parameter (\"%s",
}

Proposed Resolution

Use greedy approach for the search regular expression.

string with variable gets exported as well

ex.

__("Hello $someVar")

$someVar == "one,two,three" which we already have a key per each

"Hello one": "Hello one",
"Hello two": "Hello two",
"Hello three": "Hello three",

atm we will also get

"Hello $someVar": "Hello $someVar",

is there a way to ignore such a case ?

Exclude short translation keys from export

Thank you for the excellent tool.

Would it be possible to exclude patterns that use short keys? For example, I use __('menus.tickets') for my menus and there is a corresponding short key file like this:

<?php
// resources/lang/ja/menus.php

return [
    'tickets'     => 'チケット',
];

However, when I run php artisan translatable:export ja it creates this line:

"menus.tickets": "menus.tickets",

which I then have to remove manually.

I'm aware it's tricky to detect whether a short key exists but maybe an option to ignore [a-z]+.[a-z]+ patterns would catch most cases. Or ignore the patterns if the file exists

  1. php artisan translatable:export ja
  2. Pattern is ([a-z]+).[a-z]+ such as menu.tickets
  3. If \1 exists such as lang/ja/menus then ignore.

This could be set as an option.

inspect-translations not working, only if I export

Hi i'm using php artisan translatable:inspect-translations eng, that is a json file that I have with some translations, then I added a few more with @lang('blabla') on my blades, running ths command says: Did not find any untranslated strings in the eng.json file. shouldn't it add the new ones?

Btw is there any way to add new translations but with empty string instead of the key?

EDIT: Doing php artisan translatable:export eng solved the problem

Not adding new string on inspect-translations

Hello I'm running inspect-translations command but it is not detecting the new unstranslated string, is there any :fresh command or something? I already tried running cache clear but still won't work.

Split short-keyed translations into separate directories/files?

Would it be possible to export translation strings to multiple different directories/files based on the dot-notation syntax?

The idea is that a string like products.list.add-product string would be exported to lang/en/products/list.json. This would make this package usable with short keys, which would allow breaking the files up by context.

Support for Laravel 7

It would be great if this supported Laravel 7 :)

- kkomelin/laravel-translatable-string-exporter 1.9.0 requires illuminate/translation ^5.4|^6 -> satisfiable by laravel/framework[v6.17.1], illuminate/translation[5.7.17, 5.7.18, 5.7.19, v5.4.0, v5.4.13, v5.4.17, v5.4.19, v5.4.27, v5.4.36, v5.4.9, v5.5.0, v5.5.16, v5.5.17, v5.5.2, v5.5.28, v5.5.33, v5.5.34, v5.5.35, v5.5.36, v5.5.37, v5.5.39, v5.5.40, v5.5.41, v5.5.43, v5.5.44, v5.6.0, v5.6.1, v5.6.10, v5.6.11, v5.6.12, v5.6.13, v5.6.14, v5.6.15, v5.6.16, v5.6.17, v5.6.19, v5.6.2, v5.6.20, v5.6.21, v5.6.22, v5.6.23, v5.6.24, v5.6.25, v5.6.26, v5.6.27, v5.6.28, v5.6.29, v5.6.3, v5.6.30, v5.6.31, v5.6.32, v5.6.33, v5.6.34, v5.6.35, v5.6.36, v5.6.37, v5.6.38, v5.6.39, v5.6.4, v5.6.5, v5.6.6, v5.6.7, v5.6.8, v5.6.9, v5.7.0, v5.7.1, v5.7.10, v5.7.11, v5.7.15, v5.7.2, v5.7.20, v5.7.21, v5.7.22, v5.7.23, v5.7.26, v5.7.27, v5.7.28, v5.7.3, v5.7.4, v5.7.5, v5.7.6, v5.7.7, v5.7.8, v5.7.9, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.36, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].

[feature-request] per function transformation

I'm using filament and it's possible and it would be nice to get translations for filament's fields/columns created like this TextColumn::make('extra.articles_count')

the transformation filament uses is

Str::of($this->getName())
            ->afterLast('.')
            ->kebab()
            ->replace(['-', '_'], ' ')
            ->ucfirst()

I would like to configure this in config/laravel-translatable-string-exporter.php or via a Facade

something like

'functions' => [
   '__',
   '_t',
   '@lang',
   'make' => fn($s)=> \Str::of($s)->afterLast('.')->kebab()->replace(['-', '_'], ' ')->ucfirst(),
],

ore use a facade in my AppServiceProvider
like

LTSE::function('make', fn($s)=> \Str::of($s)->afterLast('.')->kebab()->replace(['-', '_'], ' ')->ucfirst())

if you are ok with either I can make a PR

Prepare for 1.18.0

Goal

  • Remove outdated PHP features and update the code.
  • Enable some useful options in the config by default.

Roadmap

Does not support new Laravel 9 directory structure

Since Laravel 9.x, the lang folder has been moved.

The old folder structure still works, however the new one does not.

I made a quick and dirty fix both structure, however, I have more ideas how to improve it (and also add some tests!).

  • Could be an ENV and config for language folder structure
  • Could use the lang_path() Laravel helper and fallback to the resource_path('lang')

Made a PR for the fix if you want. I won't have the time to take it any further this week - so here is to Open Source if somebody wants to finish it up :)

Have a nice weekend!

Separate translation file for frontend strings

The motivation

When we load and translate strings on the frontend level through JS, we shouldn't load translations for strings collected from PHP code. We can save bandwidth and time if we only load translations for strings found in JS code.

The solution

It would be great if we have two files for each language:

  • es.json - used by Laravel translation system through PHP on backend
  • es.frontend.json - used by JS code to translation strings found in JS code only

Importing placeholders as well?

Hi again, testing I noticed that if you have a string like that

@lang('Hello ', ['Name' => 'Cristian'])

it wont import in to your json like that:

"Hello ": "Hello :Name"

Any posibility to implement this? (If isn't alredy implemented)

JSON File

Hello first, this is a great package, thanks for publishing it!

As the title says, it would be nice to have the untranslated strings at the top of the JSON file, followed by the other strings, all in alpha order.

This would be a config option... Is it possible?

Add Support for Laravel 6.3.x and 6.4.x

Hello @kkomelin

Is it possible to add shortly the support for Laravel 6.3.x ?

Using version ^1.5 for kkomelin/laravel-translatable-string-exporter
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for kkomelin/laravel-translatable-string-exporter ^1.5 -> satisfiable by kkomelin/laravel-translatable-string-exporter[1.5.0].
    - Conclusion: remove laravel/framework v6.3.0
    - Conclusion: don't install laravel/framework v6.3.0
    - ...

Thanks,

Strings with quotes get truncated or escaped again

I'm using Laravel v. 5.7.28 and laravel-translatable-string-exporter v. 1.10.0.

When I run php artisan translatable:export pt-BR, some strings with double-quotes get truncated in my pt-BR.json file.

Example code:

throw new ExternalCrmException(sprintf(__('A required parameter ("%s") was not found.'), $requiredParameter));

Generated pt-BR.json (relevant line shown):

{
    "A required parameter (\"%s": "A required parameter (\"%s",
}

Also, some strings get escaped again or miss-escaped (this depends whether the original string is within single- or double-quotes).

Example code:

throw new \Exception(sprintf(__("The geolocation API has returned an error: \"%s\"."), $error));
// ...
return $this->error(400, __('The given parameters are invalid and can\'t be processed by this endpoint.'));
// ...
$string = __('We\'re sorry you chose to cancel your subscription.');

Generated pt-BR.json (relevant lines shown):

{
    "The geolocation API has returned an error: \\\"%s\\\".": "The geolocation API has returned an error: \\\"%s\\\".",
    "The given parameters are invalid and can\\'t be processed by this endpoint.": "Os parâmetros fornecidos são inválidos e não podem ser processados por este serviço.",
    "We\\'re sorry you chose to cancel your subscription.": "Lamentamos que escolheu cancelar sua assinatura.",
}

And they should be:

{
    "The geolocation API has returned an error: \"%s\".": "The geolocation API has returned an error: \"%s\".",
    "The given parameters are invalid and can't be processed by this endpoint.": "Os parâmetros fornecidos são inválidos e não podem ser processados por este serviço.",
    "We're sorry you chose to cancel your subscription.": "Lamentamos que escolheu cancelar sua assinatura.",
}

Should I change the way I quote my strings, or it there another way I can avoid these problems altogether?

Undetected strings if "key"-argument starts on new line

I'm not sure wether this is a bug or intended behaviour; for me it's a bug as it's an issue with code style, but there might be reasons for it.

When starting the key on a new line, it's not detected. For example like this:

$collector->pushGenericFeedback(__(
    "This is some generic key with a :var1 and :var2 in it",
    ["var1" => "variable", "var2" => "another variable"]
));

The key is detected like this, though:

$collector->pushGenericFeedback(
    __("This is some generic key with a :var1 and :var2 in it",
    ["var1" => "variable", "var2" => "another variable"]
));

It cannot handle `__('Search...')`

It parses it as resources/lang/en/Search.php:

It should skip empty strings.

<?php

return array(
    '' => array(
        '' => array(
            '' => '',
        ),
    ),
);

Ability to add comments that provide enhanced features

This is a feature request 🤓, not an issue request.

It would be convenient, if directly before a translation, a comment could be added to explain what the text is. This could open up a few possibilities on managing how the script interacts directly inside the code, such as allowing a string, or set of strings to exist inside the comment block that get added to the lang files. Let me provide an example:

For simplicity sake, here is an array of strings:
$words = ['hello', 'world'];

Let's say we use it in our blade:

@foreach($words as $word)
    {{ __($word) }}
@endforeach

That is just for simplicity for the concept. The above of course won't work, but what if it was:

{{-- translatable: array ['hello', 'world'] --}}
@foreach($words as $word)
    {{ __($word) }}
@endforeach

In the second example above, the string exporter could create new key/value pairs ("hello":"hello", etc) based on the comment.

Another example:

{{-- translatable:  sprintf --}}
{{ sprintf( __("Your name is %s and you are awesome!"), $name) }}

In the above example, it could be used to let the string exporter know that it is a sprintf and should be parsed as such by the string exporter (ignoring the replacement variables and simply storing the string with the format characters).

I believe this type of feature opens up a few nice possibilities, such as even something like:

{{-- translatable: langonly es --}}
{{ __("Only translate me to Spanish") }}

Love the tool, thanks!

Allow new lines in translations

Currently translatable doesn't allow for new lines in translations. I have a few translations that include newlines and would like the code parser to pick these up.

There are two possible solution, the easiest would be to add the s modifier to the regex pattern.
in the file Core\CodeParses.php change:
protected $pattern = '/([FUNCTIONS])\(\h*[\'"](.+)[\'"]\h*[\),]/U';
to:
`protected $pattern = '/([FUNCTIONS])(\h*'"['"]\h*[),]/Us';

Or if you don't want to change the default behavior it could be made an optional settings in config/laravel-translatable-string-exporter.php which could default to false. Something along the lines of:

    // Indicates weather new lines are allowed in translations.
    'allow-newlines' => true,

I'm happy to write this and submit a pull request if you like.

Release 1.16.0

What about making a new release?

I can do it myself or leave it to you @phh

excluded-directories does not work as expected

Hi

I have the following in the config

    'excluded-directories' => [
        'resources/views/vendor',
    ],

however, strings from the /resources/views/vendor/scribe is still added to the .json file when doing export:

php artisan translatable:export en

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.