lokalise / i18n-ally

๐ŸŒ All in one i18n extension for VS Code
https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally
MIT License
4.04k stars 326 forks source link

[Framework Request] Laravel #193

Closed ghost closed 4 years ago

ghost commented 4 years ago

What framework do you want to have? Please provide links of its i18n solution/package. The Laravel Framework.
Here are the docs for the i18n solution.

Please provide some overall screenshots about how the i18n usage would be like I assume it would work just like Vue ally. The way it works is a bit similar.

Laravel uses __() and trans(). There is also trans_choice for multiple options.

There is also @lang() which is used in blade templates, which is a DSL (pretty much like vue templates).

Please provide a minimal starter project Well, laravel/laravel has a starter project that everyone uses. You could go from there.

antfu commented 4 years ago

No problem. Will support soon :)

antfu commented 4 years ago

Hi @phiter-monetizze I have saw there are php format and json format for store locale messages. Which one is more common in use for Laravel? The php one can be much harder to implement since we are only doing static analysis.

ghost commented 4 years ago

Oh damn. I think PHP format is the most used, since it's the default in the laravel boilerplate.

antfu commented 4 years ago

Ok, I think I found something interesting https://github.com/rmariuzzo/php-array-loader. It would take a little longer to implement. Please keep tuned.

antfu commented 4 years ago

@phiter-monetizze The experimental support is landed in v1.12.3. Please check it out.

BTW I have noticed Laravel has something like namespace (similar to #122), not sure how it works. Can you try the new version out and share me some details? Thanks.

tyler36 commented 4 years ago

Also interested in Laravel support. Since it's still a work in progress, I'll check in on Monday with my experience.

tyler36 commented 4 years ago

Given the following blade template and 'en' translation file demo.blade.php

<div>
    <p>Expected: "These credentials do not match our records."</p>
    <p>{{ __('example.failed') }}</p>
    <p>{{ trans('example.failed') }}</p>
    <p>@lang('example.failed')</p>
</div>

<!-- Injection -->
<div>
    <p>Expected: "The email is not a valid date."</p>
    <p>{{ __('example.date', ['attribute' => 'email']) }}</p>
    <p>{{ trans('example.date', ['attribute' => 'email']) }}</p>
    <p>@lang('example.date', ['attribute' => 'email'])</p>
</div>

<div>
    <p>Expected: "The count must be greater than 5."</p>
    <p>{{ __('example.gt.numeric', ['attribute' => 'count', 'value' => 5]) }}</p>
    <p>{{ trans('example.gt.numeric', ['attribute' => 'count', 'value' => 5]) }}</p>
    <p>@lang('example.gt.numeric', ['attribute' => 'count', 'value' => 5])</p>
</div>

<!-- Pluralisation -->
<div>
    <p>Expected: "There is one apple. There are many apples."</p>
    <p>{{ trans_choice('example.apples', 1) }}</p>
    <p>{{ trans_choice('example.apples', 2) }}</p>
    <p>@choice('example.apples', 1)</p>
    <p>@choice('example.apples', 2)</p>
</div>

example.php

<?php

return [
    'failed' => 'These credentials do not match our records.',
    'date' => 'The :attribute is not a valid date.',
    'apples' => 'There is one apple.|There are many apples.',

    'gt' => [
        'numeric' => 'The :attribute must be greater than :value.',
        'file' => 'The :attribute must be greater than :value kilobytes.',
        'string' => 'The :attribute must be greater than :value characters.',
        'array' => 'The :attribute must have more than :value items.',
    ],
];
  1. UI always shows i18n key "example.failed" not exists message with blue line for ALL translations. not exists

  2. Translation progress shows inconsistent stats for languages. This project ONLY has 'en' & 'ja' translation files but the extensions is finding other languages. 'go' & 'cs' should all marked as 0%. I'm not sure why it finds 'cs' at 40.1% but 'go' at 13.4% inconsistant stas

  3. Updating translations should be outputting as an PHP array style (example.php), instead it wrote the file as JSON. Below is my attempt to update 'example.failed' to 'banana' using the 'flat' option:

    
    {
    "failed": "These credentials do not match our records.",
    "date": "The :attribute is not a valid date.",
    "apples": "There is one apple.|There are many apples.",
    "gt": {
    "numeric": "The :attribute must be greater than :value.",
    "file": "The :attribute must be greater than :value kilobytes.",
    "string": "The :attribute must be greater than :value characters.",
    "array": "The :attribute must have more than :value items."
    },
    "example.apples": "banana"
    }```

The above is intended as feedback on the work-in-progress Laravel support. I and others thank you for creating and maintaining this extension!!!

tyler36 commented 4 years ago

Some links: Official Laravel translation page: https://laravel.com/docs/master/localization

Community translations: https://github.com/caouecs/Laravel-lang Laravel only includes English translations out-of-the-box. This site has 73 other language translations. It might be handy as a reference for other locales or testing encoding.

antfu commented 4 years ago

Hi @tyler36, thanks for the feedback!

  1. Ok, can confirm, I will try to make the namespace work then.

  2. Can you share your translation file structure?

  3. Wondering how you make it updating? The PHP format should work in READONLY mode, which means you can not write any changes to them.

tyler36 commented 4 years ago
  1. Translation file structure: /resources/lang/{locale}/
/resources
    /lang
        /en
            example.php
        /ja
            example.php

So, the example.php file above would be found at /resources/lang/en/example.php

<?php

return [
    'failed' => 'These credentials do not match our records.',
    ...
];

If I have Japanese translation files (ja), they would be found at /resources/lang/ja/example.php

<?php

return [
    'failed'   => 'ใ“ใ‚Œใ‚‰ใฎ่ณ‡ๆ ผๆƒ…ๅ ฑใฏๅฝ“็คพใฎ่จ˜้Œฒใจไธ€่‡ดใ—ใพใ›ใ‚“ใ€‚',
    ...
];
tyler36 commented 4 years ago
  1. Sorry, I don't understand your question. When I said "update" the translation, I meant I clicked on the pencil icon ("edit translation") on the ar right of the current file panel (visible in the inconsistant stas.jpg image above
antfu commented 4 years ago

Hey guys, the namespace support (a.k.a filename as root key) is landed in v1.12.4. Please check it out :)

cc @phiter-monetizze @tyler36

antfu commented 4 years ago

@tyler36

  1. Translation progress shows inconsistent stats for languages. This project ONLY has 'en' & 'ja' translation files but the extensions is finding other languages. 'go' & 'cs' should all marked as 0%. I'm not sure why it finds 'cs' at 40.1% but 'go' at 13.4%

I can't tell why you got this behavior. If it's possible, could you please share me a minimal reproduce repo?

  1. Sorry, I don't understand your question. When I said "update" the translation, I meant I clicked on the pencil icon ("edit translation") on the ar right of the current file panel

We don't currently support output to PHP file (PRs are welcome). Which means you shouldn't see the "pencil" icon. Wondering why you can do that XD.

tyler36 commented 4 years ago

@antfu Updated to version 1.12.4 Oops ... I now get an VS Codee error when the extension starts.

"i18n Ally Error: TypeError: Cannot read property 'split' of undefined"

Looking at the logs shows:

๐Ÿ“‚ Loading locales under %path%\vendor\scrivo\highlight.php\Highlight\languages Invalid locale code "1c" RangeError: Invalid language tag: 1c

๐Ÿ› ERROR: TypeError: Cannot read property 'split' of undefined TypeError: Cannot read property 'split' of undefined at getKeyname (.././src/utils/utils.ts:44:26)

tyler36 commented 4 years ago
  1. UI always shows i18n key "example.failed" not exists message with blue line for ALL translations.

Nice. This seems to be resolved ๐Ÿ‘

  1. Translation progress shows inconsistent stats for languages. This project ONLY has 'en' & 'ja'

A basic project only shows translation for 'en' and 'ja', as expected. ๐Ÿ‘ Thought: I opened another project and noticed that it also scanned the vendor folders. Personally, I would prefer an option to disable this. Some vendors were very comprehensive in their translations and some not so much. The upshot being my the progress panel now shows the progress of 17 languages. Granted, I can disable them it would be nice to have an easier option. ๐Ÿ˜Š

  1. Pencil icon

    We don't currently support output to PHP file (PRs are welcome). Which means you shouldn't see the "pencil" icon. Wondering why you can do that XD.

Pencil icon no longer show ๐Ÿ‘ . The is an "edit" icon when I hover over translations (as shown in the 1. screenshot above). If PHP is not supported, perhaps this should be disabled as well?

antfu commented 4 years ago

@tyler36 Is the 1c file intends to be in the languages folder? I fix the problem in 1.12.5. It will now ignore the invalid file instead of crashing.

antfu commented 4 years ago

it also scanned the vendor folders. Personally, I would prefer an option to disable this

Is there a common folder/pattern of vendor folders in Laravel? I can make it ignore them like node_modules for node.js.

The is an "edit" icon when I hover over translations

That's wired. Will investigate.

tyler36 commented 4 years ago

@antfu No 1c file. In the vendor directory, there is a \vendor\scrivo\highlight.php\Highlight\languages\1c.json file which contains themes for programing languages. Is this extension detecting the 'languages' in the path and assuming a spoken language?

tyler36 commented 4 years ago

@antfu PHP composer uses a vendor folder which is the NPM equivalent of node_modules. Disabling this folder (through option or default) would also resolve the issue in the above comment.

antfu commented 4 years ago

Is this extension detecting the 'languages' in the path and assuming a spoken language?

Yes. And it should follow the BCP47 Standard. That's the scenario in your use case?

PHP composer uses a vendor folder

Thanks. I will make enable it by default.

tyler36 commented 4 years ago

Is this extension detecting the 'languages' in the path and assuming a spoken language?

Yes. And it should follow the BCP47 Standard. That's the scenario in your use case?

OK. The extensions is getting caught up on a package: scrivo/highlight.php

highlight.php is a server-side syntax highlighter written in PHP that currently supports 185 languages. It's a port of highlight.js by Ivan Sagalaev that makes full use of the language and style definitions of the original JavaScript project.

Looks like a .1C file is

The 1C file type is primarily associated with Apple II operating system.

OK so it seems like it should be a valid file. Once the vendor folder is ignored, it won't be an issue.

Thanks for the quick follow-ups!!!

antfu commented 4 years ago

I see. I think you can check out the i18n-ally.localePaths field of your setting and remove the paths of the vendor folder.

tyler36 commented 4 years ago

Perfect ๐ŸŽ‰

Once I ignored the vendor folder, the Translation progress shows inconsistent stats for languages issue disappeared too since the "programming languages" were no longer being scanned, the GO, HY "translations" were no longer missing.

Thanks again for follow-through and work. Not sure how @phiter-monetizze feels, but I'd say you can close this.

ghost commented 4 years ago

Hey! Sorry for not following this thread much.

I tested the extension in our project and it works fine! Thank you.

Now I have to convince the back-end guys in my team to use VSCode instead of Sublime and Atom lol.

I see that editting is not working yet, I believe this is due to the files being PHP and not JSON as the app is built for, but that's not a issue. Being able to see the translation is already a big step.

antfu commented 4 years ago

Good to hear that you get it working. I am closing this for now, if you got any questions free free to reopen it. Thanks

yob-yob commented 3 years ago

is there a way this can support Laravel and Vue at the same time?

I'm currently using a package called "Laravel Localization For Vue" which exports Laravel Language files to .json file.

this file is then found under resources/js/locales it is then imported using webpack in for the Vue app.js

when I'm using this extension in only detects files under resources/lang, I assumed this is because it knows that it is on a laravel project so it just looks for locales inside that directory.

is it possible to add LocalePath ? and add path for .vue files?

sstottelaar commented 2 years ago

@yob-yob I'm running into the same issue, did you manage to get it working?

MSnoeren commented 2 years ago

@yob-yob @sstottelaar I'm using Inertia with Laravel. Both the frontend and backend use the same JSON file named lang/en.json. I simply import it in my javascript.

My configuration (in .vscode/settings.json) to make this work is:

{
    "i18n-ally.localesPaths": [
        "lang"
    ],
    "i18n-ally.enabledFrameworks": [
        "vue",
        "laravel"
    ],
    "i18n-ally.keystyle": "flat",
    "i18n-ally.sourceLanguage": "en",
    "i18n-ally.enabledParsers": [
      "json"
    ]
}

The output JSON will be flat and not very pretty, but it allows you to use a single translation file for both back- and frontend. Hope this helps!

rafaelrglima commented 1 year ago

I guess editing for php files is not available yet. Translation file structure:

So, the example.php file above would be found at /resources/lang/en/example.php If I have translation files (pt-br), they would be found at /resources/lang/pt-br/example.php when I try to edit via UI, I get: Error: Writing in readonly mode is disabled.

Putr commented 1 year ago

I'm not a 100% if it's not my local issue, but I think that l18n-ally does not support subfolders in laravel.

So a translation found in the lang/emails/marketing.php file would be accessed like this: @lang('emails/marketing.hello-email.subject').

This does not seem to work on my install - reports the slugs as "not found", also translates the emails/marketing... part into emails.marketing.... But translations in the "root" files work ok.

rev4324 commented 10 months ago

I'm not a 100% if it's not my local issue, but I think that l18n-ally does not support subfolders in laravel.

So a translation found in the lang/emails/marketing.php file would be accessed like this: @lang('emails/marketing.hello-email.subject').

This does not seem to work on my install - reports the slugs as "not found", also translates the emails/marketing... part into emails.marketing.... But translations in the "root" files work ok.

I know I'm late, but try this config option - "i18n-ally.namespace": true