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

routes.translation event listen doesn't work #322

Closed
f-liva opened this issue Jun 14, 2016 · 9 comments
Closed

routes.translation event listen doesn't work #322

f-liva opened this issue Jun 14, 2016 · 9 comments

Comments

@f-liva
Copy link

f-liva commented Jun 14, 2016

I have a language switch bar that has to generate the URL for the current page in all supported languages.

To do that I have to subscribe to the routes.translation event, but isn't so simple.

When I execute this

LaravelLocalization::getLocalizedURL($localeCode); // Where $localeCode is "en", "fr", etc.

with this

Event::listen('routes.translation', function ($locale, $attributes)
{
    foreach ($attributes as $name => $value)
    {
        $attributes[$name] = $translatedValue; // get the transated attribute for the given $locale
    }

    return $attributes;
});

I get this error

ErrorException in routes.php line 38:
Missing argument 2 for App\Providers\RouteServiceProvider::{closure}() (View: D:\Progetti\instalmec.it\Instalmec\resources\views\header.blade.php) (View: D:\Progetti\instalmec.it\Instalmec\resources\views\header.blade.php)

Why? I followed your docs but doesn't work as expected.
I see that the first parameter is the attributes array, but should be the second, right?

See entire logs if needed.

@f-liva
Copy link
Author

f-liva commented Jun 17, 2016

+1

@mcamara
Copy link
Owner

mcamara commented Jun 18, 2016

To print a language switcher you just need to add this code to your blade template.

@foreach (LaravelLocalization::getSupportedLocales() as $key => $language)
    <a href="{{ LaravelLocalization::getLocalizedURL($key) }}">
        {{ $language['name'] }}
    </a>
@endforeach

Why are you using events for this?

@f-liva
Copy link
Author

f-liva commented Jun 19, 2016

I am using the event because I have to translate the parameters present in the URL, as well as the routes themselves.

We are in /gasoline/cars and through the LaravelLocalization::getLocalizedURL('it') I want to generate the right translated URL in Italian (which is /benzina/macchine). The routes are:

/resources/lang/en/routes.php

return [
    'cars' => '{fuel}/cars'
];

/resources/lang/it/routes.php

return [
    'cars' => '{fuel}/macchine'
];

The strange behaviors are two.

  1. If there is no listener for routes.translation event, the routes are translated correctly but not the parameters (as expected): /it/gasoline/macchine
  2. If the listener exists, not only the translated parameters returned by it are ignored, nor the routes are translated but the prefix of the language is added: /it/gasoline/cars instead of /it/benzina/macchine as expected.

Morover, the routes.translation event is fired with only one parameter, the attributes, so I really don't understand how the listener should know which locale use to translate the attributes (now I forced to italian)

@f-liva
Copy link
Author

f-liva commented Jun 21, 2016

Any news here? I debugged the code but I some help to fix this issue

@f-liva
Copy link
Author

f-liva commented Jun 24, 2016

+1 please, I need to solve the problem and I can pay for an help!

@r4y7s
Copy link
Contributor

r4y7s commented Sep 23, 2016

@fede91it the problem is in the file

LaravelLocalization.php # L855

$response = event('routes.translation', [ $attributes ]);

The event is triggered only with an argument when the documentation says they are two $ locale, $ attributes

@mcamara hopefully can fix the bug please!

@r4y7s
Copy link
Contributor

r4y7s commented Sep 26, 2016

@fede91it @mcamara pull request #362

@mcamara mcamara closed this as completed Sep 21, 2017
@marcbelletre
Copy link

marcbelletre commented Feb 7, 2018

I have the exact same problem as @fede91it.
I'm trying to use the event listener in order to translate slugs when using getLocalizedUrl. For example I would like to have the following routes:

  • /fr/programmation/spectacles
  • /en/program/shows

In my routes translation file I have the following line:

return [
   'program' => 'programmation/{category?}',
];

I'm displaying the language switcher using this:

@foreach( LaravelLocalization::getSupportedLocales() as $localeCode => $properties )
   <li>
      <a rel="alternate" hreflang="{{ $localeCode }}" href="{{ LaravelLocalization::getLocalizedURL($localeCode) }}"{!! LaravelLocalization::getCurrentLocale() === $localeCode ? 'class="active"' : '' !!}>{{ $localeCode }}</a>
   </li>
@endforeach

And finally my event listener in EventServiceProvider.php

Event::listen('routes.translation', function($locale, $attributes) {
   if( array_key_exists('category', $attributes) ) {
      $category = Category::whereTranslation('slug', $attributes['category'])->first();

      if( $category && $category->hasTranslation($locale) ) {
         $attributes['category'] = $category->translate($locale)->slug;
      }
   }
   return $attributes;
});

I know the event is firing because I can dump my Category model. However it doesn't change anything in the localized URL.
I get the same behaviors described by @fede91it here. Without the event listener I get:

  • /fr/programmation/spectacles
  • /en/program/spectacles

But I get these results with the event listener whatever I write in it:

  • /fr/programmation/spectacles
  • /en/programmation/spectacles

I know this issue has been closed but it looks like it still hasn't been solved. Or maybe I'm doing something wrong?
I'm using the lastest version (1.3.4) with Laravel 5.5.34.

UPDATE

Unfortunately I didn't manage to solve this issue but I found the origin of the problem.
In the function findTranslatedRouteByUrl, there is a loop going through all translated routes and checking for each one if the corresponding URL is equal to the URL we are trying to translate.

$routeName = $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes);

if ($this->getNonLocalizedURL($routeName) == $this->getNonLocalizedURL($url)) {
   return $translatedRoute;
}

In my case, $url is equal to /programmation/spectacles but $routeName is equal to /programmation/shows because the attributes have been replaced by its english translation.

I guess my only solution here is to overwrite this function so it can look for the attributes translations.

@lukkoro
Copy link

lukkoro commented Jun 12, 2019

I guess my only solution here is to overwrite this function so it can look for the attributes translations.

Did you manage to solve this issue? I have the same problem where I'm trying to pull localized slug from the database and I know the event is firing but still doesn't translate..

EDIT
It seems as if the routes.translation event was firing at the wrong place. I have fixed it by firing the event in the getURLFromRouteNameTranslated function and now anything that I put in the event works flawlessly, and it changes the links as supposed to.

@mcamara pull request #636

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

5 participants