Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] How to use __('hello world') with package specific translations #17923

Closed
marktopper opened this issue Feb 14, 2017 · 12 comments
Closed

[5.4] How to use __('hello world') with package specific translations #17923

marktopper opened this issue Feb 14, 2017 · 12 comments

Comments

@marktopper
Copy link
Contributor

  • Laravel Version: 5.4.11
  • PHP Version: 7.0.15
  • Database Driver & Version: N/A

Description:

How can we have package specific translations to support the use of the new translation method in Laravel 5.4.

__('Hello world!')
@marktopper marktopper changed the title How to use __('hello world') with package specific translations [5.4] How to use __('hello world') with package specific translations Feb 15, 2017
@themsaid
Copy link
Member

Actually there isn't a way to read package translations using the JSON loader since the loader is not namespaced, do you have a suggested solution for this?

@marktopper
Copy link
Contributor Author

marktopper commented Feb 15, 2017

Idea

Maybe it could work like this:

Adding translations (like normall)

    public function boot()
    {
        $this->loadTranslationsFrom(__DIR__.'/translations', 'namespace');
    }

Then it could also look for *.json files in that directory.

Getting name-spaced translation:

__('namepace::Hello world!');

If not exists, it could look for __('Hello world!').
If that does not exists rather, then it could fallback to the text Hello world!.

@marktopper
Copy link
Contributor Author

Or to make it simple it should just be possible to load translations json files via the service provider.

Then the JSON could look like this:

{
    "namespace::Hello world!": "Hello world!"
}

Or even

{
    "namespace": {
        "Hello world!": "Hello world!"
    }
}

@themsaid
Copy link
Member

I think it's better not to namespace JSON translations, like __("Hello") is hello everywhere, the whole point is to make the translation keys natural so that you can use them without having to manage namespaces and keys.

For cases like you mentioned I think it's better to use the other loader, the array loader, rather than the JSON one.

@marktopper
Copy link
Contributor Author

I am cool with using it without a namespace. But would it become possible to load JSON translations from a package then, like if a package have some predefined translations for specific languages that a user can always overwrite by making their own translations.

@themsaid
Copy link
Member

Yes that seems like a good idea, I'll look into that :)

@marktopper
Copy link
Contributor Author

Any progress @themsaid 😄

@akazorg
Copy link

akazorg commented Mar 7, 2017

Hello @themsaid, what's the status on this?
This is a great feature, please make it happen!! :)
Thanks

@abdgad
Copy link

abdgad commented Mar 11, 2017

Ideas:

  • Ability to set a loader on the translator.
  • Ability to set translations path on the loader.
protected function loadsTranslationsFrom($path, $namespace = '*') {
    if ($namespace == '*') {
        $this->app['translator']->getLoader()->setPath($path);
    } else {
      $this->app['translator']->addNamespace($namespace, $path);
    }
}

Edit:

class MultipleFileLoader extends FileLoader
{
    public function __construct(Filesystem $files, $paths)
    {
        $this->path = (array) $paths;
        $this->files = $files;
    }

    /**
     * Load a locale from the given JSON file paths. 
     *
     * @param  array  $paths
     * @param  string  $locale
     * @return array
     */
    protected function loadJsonPath($paths, $locale)
    {
        $translations = [];

        foreach ($paths as $path) {
            if ($this->files->exists($full = "{$path}/{$locale}.json")) {
                $translations[] = (array) json_decode($this->files->get($full), true);
            }
        }

        return array_merge(...$translations);
    }
}

In the service provider:

protected function registerTranslator()
    {
        $this->app->extend('translator', function ($translator, $app) {
            $paths = [
                dirname(__DIR__)."/publishable/translations",
                $app['path.lang'],
                // maybe pull more translation paths from the config....
            ];

            $loader = new MultipleFileLoader($app['files'], $paths);

            $translator->setLoader($loader);

            return $translator;
        });
    }

@sangnguyenplus
Copy link
Contributor

I hope this feature can update soon. I'm developing packages too. JSON translation should be namespaced because the language can differ with the same key.

@vibrantBits
Copy link

Maybe in L5.5? That would be a nice surprise.

@themsaid
Copy link
Member

Here you go: #20599

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants