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

Language switcher and parameter translation. #27

Closed
jartaud opened this issue Jan 13, 2016 · 11 comments
Closed

Language switcher and parameter translation. #27

jartaud opened this issue Jan 13, 2016 · 11 comments
Assignees

Comments

@jartaud
Copy link

jartaud commented Jan 13, 2016

Hello,
Say I have http://local.dev/category-slug, when i switch the language, I have http://local.dev/fr/category-slug. How can I grab the correct category translation from the DB so when i change the language, I can get something like http://local.dev/fr/categorie-slug or http://local.dev/es/categoria-slug?

// routes.php
Route::get('{category_slug}/{per_page}?', []);
@jartaud jartaud changed the title Language switcher and parameter translation. Language switcher and parameter translation. question help Jan 13, 2016
@arcanedev-maroc
Copy link
Member

Hi @jartaud, thanks for using this package.

BTW good question, did you checked this section about the events ?

@arcanedev-maroc arcanedev-maroc changed the title Language switcher and parameter translation. question help Language switcher and parameter translation. Jan 13, 2016
@jartaud
Copy link
Author

jartaud commented Jan 13, 2016

@arcanedev-maroc, thanks for your help.
Yeah i was playing with it, but i'm not quite sure i understand this part:

// You can store these translation in you database
$translations = [
    'view'  => [
        'en'    => [
            'slug'  => 'hello',
        ],
        'es'    => [
            'slug'  => 'hola',
        ],
        'fr'    => [
            'slug'  => 'salut',
        ],
    ],
];
// model: id, name, slug,  lang

How to transform this into eloquent->toArray() ?
Will i still have to use Route::transGet() ?

@arcanedev-maroc
Copy link
Member

You're welcome @jartaud,

In your case, you need to replace this dummy code:

$translations = [
    'view'  => [
        'en'    => [
            'slug'  => 'hello',
        ],
        'es'    => [
            'slug'  => 'hola',
        ],
        'fr'    => [
            'slug'  => 'salut',
        ],
    ],
];

// This is just a dummy thing to fetch and merge the translation.
if (
    isset($translations[$route]) && isset($translations[$route][$locale])
) {
    $attributes = array_merge($attributes, $translations[$route][$locale]);
}

By using a custom helper or directly by using an eloquent model.

As you can see, the event listener gives you three arguments ($locale,$route & $attributes).

So you can do something like this:

Event::listen('routes.translation', function ($locale, $route, $attributes) {
    switch ($route) {
        case 'route-name-for-categories':
            $attributes = YourEloquentModel::customTranslateMethod($locale, $attributes);
            break;

        case 'another-route-name':
            $attributes = CustomHelper::translateMethod($locale, $attributes);
            break;

        //...

        default:
            // Do nothing if does not match any route
            // no break
    }

    return $attributes;
});

The main goal is to translate the $attributes argument.

And YES, you need to use the Route::transGet() for the translated routes.

@jartaud
Copy link
Author

jartaud commented Jan 13, 2016

What's the route name in this piece of code ??

Do you have any real example combining the switcher with routes.translation event ?

Event::listen('routes.translation', function ($locale, $route, $attributes) {
    // You can store these translation in you database
    // or using the laravel's localization folders
    $translations = [
        'view'  => [
            'en'    => [
                'slug'  => 'hello',
            ],
            'es'    => [
                'slug'  => 'hola',
            ],
            'fr'    => [
                'slug'  => 'salut',
            ],
        ],
    ];

    // This is just a dummy thing to fetch and merge the translation.
    if (
        isset($translations[$route]) && isset($translations[$route][$locale])
    ) {
        $attributes = array_merge($attributes, $translations[$route][$locale]);
    }

    return $attributes;
});

@arcanedev-maroc
Copy link
Member

This is a full example how to use it:

// routes.php
Route::localizedGroup(function () {
    // Other routes ...

    Route::transGet('routes.view', [
        'as'   => 'view-route',
        'uses' => function ($slug) {
            return 'The slug has been translated : ' . $slug;
        },
    ]) ;
});

Localization:

// resources/lang/en/routes.php
<?php

return [
    'view'  => 'view/{slug}'
];

// resources/lang/es/routes.php
<?php

return [
    'view'  => 'ver/{slug}'
];

// resources/lang/fr/routes.php
<?php

return [
    'view'  => 'afficher/{slug}',
];

And register the event listener:

Event::listen('routes.translation', function ($locale, $route, $attributes) {
    // You can store these translation in you database
    // or using the laravel's localization folders
    $translations = [
        'view-route'  => [
            'en'    => [
                'slug'  => 'hello',
            ],
            'es'    => [
                'slug'  => 'hola',
            ],
            'fr'    => [
                'slug'  => 'salut',
            ],
        ],
    ];

    // This is just a dummy thing to fetch and merge the translation.
    if (
        isset($translations[$route]) && isset($translations[$route][$locale])
    ) {
        $attributes = array_merge($attributes, $translations[$route][$locale]);
    }

    return $attributes;
});

And also make sure that localized-routes and translation-redirect are enabled.

And if you're not sure what is the current route in the event listener, you just dd($route) to see what is your route name of a specific url.

If you want to understand how its done behind scene, check TranslationRedirect Middleware.

@jartaud
Copy link
Author

jartaud commented Jan 14, 2016

Thank you so much dude!

@jartaud jartaud closed this as completed Jan 14, 2016
@arcanedev-maroc
Copy link
Member

You're welcome 👍

@jartaud
Copy link
Author

jartaud commented Jan 14, 2016

In order to use event translation with Eloquent, I use an Artisan Command to create an array of translations: https://gist.github.com/jartaud/195d050304892df51542

What do you think?

@jartaud jartaud reopened this Jan 14, 2016
@arcanedev-maroc
Copy link
Member

Great work @jartaud, but it's a little bit complicated in my opinion.

Don't do the same thing what i've done in the event listener, my example is just a dummy code for demonstration.

I'm sure you can do better than this (without artisan command), try to create a custom Helper like ModelTranslator to translate your models dynamically instead of generating a file (you can also use the caching system).

You are free to do whatever is good for your project, just be more creative & keep it simple.

I going to close this because the issue/question was solved.

But feel free to create a new issue or a PR to contribute to this package.

@jartaud
Copy link
Author

jartaud commented Jan 14, 2016

Thanks again. I've been fooled by a slow homestead on Windows. Yeah i'll refactor

Great package 💯

@jasperjorna
Copy link

How can we have the correct URL already show up inside the navbar language switcher?

Translating slugs with the Event::listen method works when actually hitting the URL, as it then redirects to the correct one. But the alternative URL's initially show up in the current language in the language switcher. vrachtwagens is the variable slug in this example.

<ul class="nav navbar-nav navbar-right">
  <li>
    <a href="http://local.dev/stock/vrachtwagens" rel="alternate" hreflang="en">
      English
    </a>
  </li>
  <li class="active">
    <a href="http://local.dev/nl/aanbod/vrachtwagens" rel="alternate" hreflang="nl">
      Nederlands
    </a>
  </li>
</ul>

The URL for English however should be pointing to http://local.dev/stock/trucks.
When clicking on it, it does redirect to that URL.

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

No branches or pull requests

3 participants