Giter Site home page Giter Site logo

chinleung / laravel-multilingual-routes Goto Github PK

View Code? Open in Web Editor NEW
394.0 10.0 26.0 196 KB

A package to handle multilingual routes in your Laravel application.

Home Page: https://github.com/chinleung/laravel-multilingual-routes-demo

License: MIT License

PHP 100.00%
laravel package localization composer-package laravel-multilingual-routes laravel-routes laravel-package hacktoberfest

laravel-multilingual-routes's Introduction

Laravel Multilingual Routes

Latest Version on Packagist Build Status Quality Score Total Downloads

A package to register multilingual routes for your application.

Versioning

Version Laravel Version
v4 10.x
v3 9.x
v2 Older than 9.x

Installation

You can install the package via composer:

composer require chinleung/laravel-multilingual-routes

To detect and change the locale of the application based on the request automatically, you can add the middleware to your app/Http/Kernel. It must be the first item in the web middleware group.

protected $middlewareGroups = [
    'web' => [
        \ChinLeung\MultilingualRoutes\DetectRequestLocale::class,
        // ...
    ]
];

Configuration

By default, the application locales are only going to be en and the default locale is not prefixed. If you want to prefix the default locale, please run the following command to publish the configuration file:

php artisan vendor:publish --provider="ChinLeung\MultilingualRoutes\MultilingualRoutesServiceProvider" --tag="config"

If your application supports different locales, you can either set a app.locales configuration or follow the configuration instructions from chinleung/laravel-locales.

Example

Instead of doing this:

Route::get('/', 'ShowHomeController')->name('en.home');
Route::get('/fr', 'ShowHomeController')->name('fr.home');

You can accomplish the same result with:

Route::multilingual('/', 'ShowHomeController')->name('home');

A demo repository has been setup to showcase the basic usage of the package.

Usage

Quick Usage

Once you have configured the locales, you can start adding routes like the following example in your routes/web.php:

Route::multilingual('test', 'TestController');

This will generate the following:

Method URI Name Action
GET|HEAD test en.test App\Http\Controllers\TestController
GET|HEAD fr/teste fr.test App\Http\Controllers\TestController

Note the URI column is generated from a translation file located at resources/lang/{locale}/routes.php which contains the key of the route like the following:

<?php

// resources/lang/fr/routes.php

return [
  'test' => 'teste'
];

To retrieve a route, you can use the localized_route(string $name, array $parameters, string $locale = null, bool $absolute = true) instead of the route helper:

localized_route('test'); // Returns the url of the current application locale
localized_route('test', [], 'fr'); // Returns https://app.test/fr/teste
localized_route('test', [], 'en'); // Returns https://app.test/test

To retrieve the current route in another locale, you can use the current_route(string $locale = null) helper:

current_route(); // Returns the current request's route
current_route('fr'); // Returns the current request's route in French version
current_route('fr', route('fallback')); // Returns the fallback route if the current route is not registered in French

Renaming the routes

Route::multilingual('test', 'TestController')->name('foo');
Method URI Name Action
GET|HEAD test en.foo App\Http\Controllers\TestController
GET|HEAD fr/teste fr.foo App\Http\Controllers\TestController

Renaming a route based on the locale

Route::multilingual('test', 'TestController')->names([
  'en' => 'foo',
  'fr' => 'bar',
]);
Method URI Name Action
GET|HEAD test en.foo App\Http\Controllers\TestController
GET|HEAD fr/teste fr.bar App\Http\Controllers\TestController

Skipping a locale

Route::multilingual('test', 'TestController')->except(['fr']);
Method URI Name Action
GET|HEAD test en.test App\Http\Controllers\TestController

Restricting to a list of locales

Route::multilingual('test', 'TestController')->only(['fr']);
Method URI Name Action
GET|HEAD fr/teste fr.test App\Http\Controllers\TestController

Changing the method of the request

Route::multilingual('test', 'TestController')->method('post');
Method URI Name Action
POST test en.test App\Http\Controllers\TestController
POST fr/teste fr.test App\Http\Controllers\TestController

Registering a view route

// Loads test.blade.php
Route::multilingual('test');
Method URI Name Action
GET|HEAD test en.test Illuminate\Routing\ViewController
GET|HEAD fr/teste fr.test Illuminate\Routing\ViewController

Registering a view route with a different key for the route and view

// Loads welcome.blade.php instead of test.blade.php
Route::multilingual('test')->view('welcome');
Method URI Name Action
GET|HEAD test en.test Illuminate\Routing\ViewController
GET|HEAD fr/teste fr.test Illuminate\Routing\ViewController

Passing data to the view

Route::multilingual('test')->data(['name' => 'Taylor']);
Route::multilingual('test')->view('welcome', ['name' => 'Taylor']);

Redirect localized route

Route::multilingual('support');
Route::multilingual('contact')->redirect('support');

Check localized route

Request::localizedRouteIs('home');

Signing localized routes

URL::signedLocalizedRoute('unsubscribe', ['user' => 1]);
URL::temporarySignedLocalizedRoute('unsubscribe', now()->addMinutes(30), ['user' => 1]);

Upgrading from 1.x to 2.x

To update from 1.x to 2.x, you simply have to rename the namespace occurrences in your application from LaravelMultilingualRoutes to MultilingualRoutes. The most common use case would be the DetectRequestLocale middleware.

Testing

composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

laravel-multilingual-routes's People

Contributors

abdullahfaqeir avatar chinleung avatar fukumori avatar fyrts avatar greatislander avatar iwaqarhussain avatar laravel-shift avatar mahersakka avatar ricardogobbosouza avatar romanzipp avatar stylecibot 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  avatar  avatar  avatar

laravel-multilingual-routes's Issues

Unable to register multiple Routes.

Hi I'm unable to register multiple routes. When I put that into web.php

Route::multilingual('/', function () {
    return view('layout');
})->name('home');

Route::multilingual('/products', 'ProductsController@show');

First url works with multiple languages, but when I type /products or /th/products I receive 404 all the time. When I changed second entry into ::get it works...

locale() method never return "en" for default (for fallback lang) route

Describe the bug

I setup and configured all by instruction, even inserted required row into $middlewareGroups in Kernel, and I have this language list in config/locales.php:

    'supported' => [
        'en',
        'de',
    ],

And that route:

/**
 * Main page
 */
Route::multilingual('/', 'IndexController@index')->name('index');

And when I request site via mysite.com/de, {{ locale() }} returns de. But when I access site via mysite.com, {{ locale() }} return me de too, not en. How to solve that? And is it right practice to make translation for whole page content via code like this (in Blade template of page):

@if (locale() == 'de')
    de content
@else
    en content
@endif

I want to create pages like FAQ, About us, Contacts and more, supporting multiple languages (I think I'll have only two langs).
Thank you so much.

Bug: missing support for where at registering route

According to the docs it should be possible to allow forward slashes in a parameter. See https://laravel.com/docs/6.x/routing#parameters-encoded-forward-slashes

When i register a multilingual route in the following way, i get an error. I can see this method is not implemented in the current implementation.

Route::multilingual('search/{filter?}', 'Frontend\SearchController@search') ->where('filter', '.*') ->name('frontend.search.results')

Call to undefined method ChinLeung\LaravelMultilingualRoutes\MultilingualRoutePendingRegistration::where()

How use multilingual for /{slug}

ERROR: Missing required parameters for [Route: pl.page.show] [URI: {slug}]
Missing required parameters for [Route: en.page.show] [URI: en/{slug}]

Route

Route::multilingual('{slug}', 'PagesController@show')->name('page.show');

page controller

      <?php
        
        namespace App\Http\Controllers;
        
        use Illuminate\Http\Request;
        use App\Realization;
        use App\Worker;
        use App\Page;
        
        class PagesController extends Controller
        {

    public function show($slug){


        $page = Page::findBySlug($slug);
        $workers = Worker::all();

        return view('pages.show', compact( 'page', 'workers'));
      

    }

    

   

}

Page model

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use TCG\Voyager\Traits\Translatable;


    class Page extends Model
    {
    use Translatable;
    protected $translatable = ['title', 'body', 'excerpt', 'meta_description', 'meta_keywords', 'seo_title', 'slug'];

    public static function findBySlug($slug){

        return static::whereTranslation('slug', $slug)->where('status', 'ACTIVE')->firstOrFail();

    }

    }

Inside blade
{{ localized_route('page.show') }}
or
{{ localized_route('page.show')->whereIn('id', [5]) }}
is not work

Routes with identical keys are overwritten

Description

Routes with identical keys are overwritten by the last locale's registration.

Code

resources/lang/en/routes.php

<?php

return [
    'product' => 'products/{product}',
];

resources/lang/fr/routes.php

<?php

return [
    'product' => 'produits/{product}',
];

resources/lang/nl/routes.php

<?php

return [
    'product' => 'products/{product}',
];

routes/web.php

Route::multilingual('product', 'TestController');

Output

Method URI Name Action
GET|HEAD products/{product} nl.product App\Http\Controllers\TestController
GET|HEAD produits/{product} fr.product App\Http\Controllers\TestController

Redirections

Add support for multilingual redirections.

Route::multilingual('contact')->redirect('support', 302);

To generate the following routes:

+------------------+--------------+---------------------------------------+
| URI              | Name         | Action                                |
+------------------+--------------+---------------------------------------+
| contact          | en.contact   | Illuminate\Routing\RedirectController |
| fr/nous-joindre  | fr.contact   | Illuminate\Routing\RedirectController |
+------------------+--------------+---------------------------------------+

current_route compatibility with spatie/laravel-translatable and spatie/laravel-sluggable?

Describe the bug

I'm using a model with a translatable name (using spatie/laravel-translatable) which is used as the source for a translatable slug (using the HasTranslatableSlug trait of spatie/laravel-sluggable).

However, a multilingual route for the model does not use the translated slug, but always uses the slug locale which matches the config value for app.locale.

To Reproduce

Steps to reproduce the behavior:

A model instance looks like this in Tinker:

>>> Organization::first()
=> App\Models\Organization {
     id: 1,
     created_at: "2022-05-05 17:35:25",
     updated_at: "2022-05-05 17:37:54",
     name: "{"en":"Canada Revenue Agency","fr":"Agence du revenu du Canada"}",
     slug: "{"en":"canada-revenue-agency","fr":"agence-du-revenu-du-canada"}",
}

In the model class, I specify the route key for the model (as explained in the laravel-sluggable docs):

    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName(): string
    {
        return 'slug';
    }

If I create a GET route and set the app locale to fr, the model view is displayed using the fr slug:

Route::get('/organizations/{organization}', [OrganizationController::class, 'show'])
    ->name('organizations.show');

config('app.locale') == 'fr':

http://laravel.test/organizations/agence-du-revenu-du-canada/

config('app.locale') == 'en':

http://laravel.test/organizations/canada-revenue-agency/

However, if I create a multilingual GET route, the slug uses the locale defined in config('app.locale') is used for both English and French routes:

Route::multilingual('/organizations/{organization}', [OrganizationController::class, 'show'])
    ->name('organizations.show');

config('app.locale') == 'fr':

http://laravel.test/en/organizations/agence-du-revenu-du-canada/
http://laravel.test/fr/organizations/agence-du-revenu-du-canada/

config('app.locale') == 'en':

http://laravel.test/en/organizations/canada-revenue-agency/
http://laravel.test/fr/organizations/canada-revenue-agency/

Expected behavior

A multilingual route should use the appropriately translated slug, if available.

Result of route:list:

  GET|HEAD  en/organizations/{organization} ....................................................................................................... en.organizations.show โ€บ OrganizationController@show
  GET|HEAD  fr/organizations/{organization} ....................................................................................................... fr.organizations.show โ€บ OrganizationController@show

Additional context

Not applicable.

Suggestion to add fallback for current_route helper

Thanks for the package, works well!

This is not so much an issue, but more a specific use case I ran into.

Only part of my app uses localized pages. In the footer of my site I have a language switcher dropdown. Within this dropdown I'm using the current_route helper.

Sometimes (it's rare, but it happens) a page is not localized and using the Route::multilingual() route registration.

When you then call current_route, this will result in a ViewException. I added a very simple helper to fallback on the current path of the request when that happens.

I'm not saying that this should be default behavior, since you might also think: why are you showing that dropdown in the first place. I still thought I'd share it.

/**
 * Try to get the current route.
 *
 * @param  string $locale The locale for the current route.
 * @return mixed
 */
function try_current_route($locale = null)
{
    try {
        return current_route($locale);
    } catch(\Exception $e) {
        return request()->path();
    }
}

Not detecting 'as' in routes

Describe the bug

Using 'as' in the route doesn't work and the blade file cannot find it.
Example

Route::multilingual('food', ['as' => 'food:list', 'uses' => 'FoodController@index']);

Getting Route [food:list] not defined. error

Shouldn't this work by default? it is only used so we don't need to change the route url in the blade files, but actually calling them by unique name.

Support for Group Routes and "espanol" as locale

I have two questions.

  1. Does this provide support for grouped routes?
  2. Is there a way to have espanol as locale instead es

E.g I want to have following routes:

EN Routes:

/blog/abc
/blog/mno
/blog/xyz

ESPANOL Routes:

espanol/blog/abc
espanol/blog/mno
espanol/blog/xyz

For using espanol, i can do it by using espanol instead of es altogether throughout the project but this make me use espanol as locale key instead of es.
I can add locales in config/app.php
'locales' => ['en' => 'English', 'espanol' => 'Espanol']
So instead of
resource/lang/es
I would need to do like this:
resource/lang/espanol

What i want is to have some mapper for using es as locale key instead of espanol.

@chinleung Any help will be much appreciated.

Home routes not working

Hi!
The package looks pretty cool but I can't get it work.

The multilingual route "en/" doesn't work. Each GET request to http://localhost/en results in a 404.
A GET request to http://localhost/ works fine.

To Reproduce
Laravel v6.12.0 (fresh and clean)
Problem occurs on apache and nginx. First i suspected a problem with the mod_rewrite in apache.
I've tried laravel-multilingual-routes v1.5.0 and 2.0.0

web.php

Route::multilingual('/', function(){
    return current_route();
})->name('home');

Config values

app.locale => 'de'
app.fallback_locale => 'de'
locales.supported => ['de', 'en']
MULTILINGUAL_ROUTES_DEFAULT_LOCALE=de
MULTILINGUAL_ROUTES_PREFIX_DEFAULT=false

Expected behavior
Each route should return its URI

Result of route:list:

+--------+----------+-----+---------+---------+------------+
| Domain | Method   | URI | Name    | Action  | Middleware |
+--------+----------+-----+---------+---------+------------+
|        | GET|HEAD |     | de.home | Closure | web        |
|        | GET|HEAD | en/ | en.home | Closure | web        |
+--------+----------+-----+---------+---------+------------+

Additional
With MULTILINGUAL_ROUTES_PREFIX_DEFAULT=true every route leads to a 404.

Add a slash at the end of multilingual Home routes

Hello,
After configuring and installing this package, I realized that Home multilingual routes don't have a trailing slash.

Example :
-> Desired route: https://www.example.com/fr/
-> Route generated: https://www.example.com/fr

routes/web.php
Route::multilingual('/', [ShowHomepage::class])->name('homepage');

php artisan route:list
GET|HEAD | /fr | fr.homepage | Closure | web |
...

Is there a way to tell the package to leave the slash at the end only for the Home route?

Thank you for this package which is perfect for multilingual websites!

Issue with / when the site is under a subdirectory

Hi Chin and thanks for your great work.

I've an issue with the / route when the site is under a subdirectory, e.g. :

http://local/mysite/

I've 2 locales ['en', 'fr'] and my base is "fr".

All my routes can switch between my locales, except the homepage, on http://local/mysite (in french) :

  • current_route("en") gives me : http://local/mysite/mysite, probably due to this line (my REQUEST_URI is mysite)

  • When I enter manually http://local/mysite/en, I've a 404 error.

Any idea to solve the problem ?

Thanks.

Franck.

Trim starting slash for translation key

When registering a route with a starting slash, the slash is not trimmed when loading from the translation files.

Route::multilingual('/products',  'ShowProductsController');

The above attempts to load routes./products instead of routes.products from the translations.

Allow passing data to view options

In order to replicate:

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

We have either use a controller, or use the defaults method:

Route::multilingual('welcome')->defaults([
    'data' => ['name' => 'Taylor'],
]);

However, it'd be nice to be able to pass the view data directly using the data method:

Route::multilingual('welcome')->data([
    'name' => 'Taylor',
]);

Or passing the data along with the view method:

Route::multilingual('welcome')->view('hello', [
    'name' => 'Taylor',
]);

Prefixed routes are malformed after route:cache command

Describe the bug

When one registers a route with a prefix and the route:cache command has been executed then the registered route uri becomes malformed; the prefix is duplicated and the locale is gone.

Steps to Reproduce

Register prefixed route

Route::prefix('prefix')->group(function() {

    Route::multilingual('/test-route', fn() => 'Test Route')
        ->name('test-route');

});
php artisan route:cache
php artisan route:list --name=test-route

Reproduction output

php artisan route:list --name=test-route
+--------+----------+----------------------+---------------+---------+------------+
| Domain | Method   | URI                  | Name          | Action  | Middleware |
+--------+----------+----------------------+---------------+---------+------------+
|        | GET|HEAD | en/prefix/test-route | en.test-route | Closure |            |
|        | GET|HEAD | fr/prefix/test-route | fr.test-route | Closure |            |
|        | GET|HEAD | nl/prefix/test-route | nl.test-route | Closure |            |
|        | GET|HEAD | sv/prefix/test-route | sv.test-route | Closure |            |
+--------+----------+----------------------+---------------+---------+------------+
php artisan route:cache
Route cache cleared!
Routes cached successfully!
php artisan route:list --name=test-route
+--------+----------+--------------------------+---------------+---------+------------+
| Domain | Method   | URI                      | Name          | Action  | Middleware |
+--------+----------+--------------------------+---------------+---------+------------+
|        | GET|HEAD | prefix/prefix/test-route | nl.test-route | Closure |            |
|        | GET|HEAD | prefix/prefix/test-route | en.test-route | Closure |            |
|        | GET|HEAD | prefix/prefix/test-route | fr.test-route | Closure |            |
|        | GET|HEAD | prefix/prefix/test-route | sv.test-route | Closure |            |
+--------+----------+--------------------------+---------------+---------+------------+
php artisan route:clear
Route cache cleared!
php artisan route:list --name=test-route
+--------+----------+----------------------+---------------+---------+------------+
| Domain | Method   | URI                  | Name          | Action  | Middleware |
+--------+----------+----------------------+---------------+---------+------------+
|        | GET|HEAD | en/prefix/test-route | en.test-route | Closure |            |
|        | GET|HEAD | fr/prefix/test-route | fr.test-route | Closure |            |
|        | GET|HEAD | nl/prefix/test-route | nl.test-route | Closure |            |
|        | GET|HEAD | sv/prefix/test-route | sv.test-route | Closure |            |
+--------+----------+----------------------+---------------+---------+------------+

Additional context

PHP 8.1
Laravel 8.X
Branch v2

Error when using Route::multilingual()->middleware()

Describe the bug

I have this route:

Route::multilingual('/test', [TestController::class, 'index'])->middleware(['can:open something'])->name('test.index');

And I am receiving this error:

Call to undefined method ChinLeung\MultilingualRoutes\MultilingualRoutePendingRegistration::middleware()

Without attached middleware routes working fine.

Improve behaviour for missing translations of fallback locale

Return the registration key if the translation is missing and the locale if the default locale.

For instance:

Route::multilingual('products', 'ShowProductsController');

Should generate /products instead of /routes.products if the translation does not exist.

Default Locale Index Route?

It seems like its not possible to have the default route "/" redirect to a the default locale route.

For example my app has german "de" and english "en", german is default locale, the routes generated by:
Route::multilingual('/', 'MainController@index')->name('index');

only include "/" and "/en" but not "/de". Any way to force the routing to create a locale based route for all routes including the default route? And then also redirect "/" to "/LOCALE"?

Route name prefix not applying properly

At the current moment, if you have a route name prefix, it is applied before the locale in the name:

Example

Route::name('prefix.')->group(function () {
    Route::multilingual('test');
});

Result

prefix.en.test
prefix.fr.test

Expected Result

en.prefix.test
fr.prefix.test

Error when Route not defined for this locale

Describe the bug

When defining an route that is only available in view locales it throws an Error when calling localized_route()

To Reproduce

Steps to reproduce the behavior:

  1. Define a Route Route::multilingual('test/', [TestController::class, 'show'])->name('myTest')->only(['en', 'nl']);
  2. Place localized_route('myTest') in a Blade-File
  3. Call the Page with some other locale e.g. fr
  4. See error Route [fr.myTest] not defined.

Expected behavior

No Error is thrown

Additional context

As an quick fix i copied the helper function into my own helper file and added following condition:

return Route::has("$locale.$name") ? route("$locale.$name", $parameters, $absolute) : '';

composer only install the old version

installing the packages via composer in a laravel 7.0 return installation of v 1.0.0, when we force to install the latest version 2.3.0 compser return the error

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
- The requested package chinleung/laravel-locales ^2.3.0 exists as chinleung/laravel-locales[dev-master, v1.0.0, v1.0.1, v1.0.2, v1.0.3, v1.0.4, v1.0.5, v1.1.0, v1.2.0] but these are rejected by your constraint.

Post method results in error 419, page expired

Describe the bug

This seems to be a very elegant solution to the localization problem, except that I can't get the post method to work. When I click the Submit button on a form, I get error 419, page expired.

To Reproduce

In my web.php file, I have:

Route::multilingual('message', 'SiteController@get_message');
Route::multilingual('message', 'SiteController@post_message')->method('post');

The implementations are in SiteController.php as follows:

public function get_message(Request $request)
{
	return view('message');
}

public function post_message(Request $request)
{
	\Log::debug('In post_message');
	return view('thanks');
}

This is the form in message.blade.php:

<form action="message">
	  <label for="message">{{trans('forms.message')}}:</label><br>
	  <input type="text" id="message" name="message"><br>
	  <input type="submit" value="Submit" formmethod="post">
</form>

Expected behavior

I expected the contents of thanks.blade.php to be displayed.

Result of route:list:

+--------+----------+-------------+-------------+--------------------------------------------------+------------+
| Domain | Method   | URI         | Name        | Action                                           | Middleware |
+--------+----------+-------------+-------------+--------------------------------------------------+------------+
|        | GET|HEAD |             | en./        | Closure                                          | web        |
|        | GET|HEAD | /fr         | fr./        | Closure                                          | web        |
|        | GET|HEAD | api/user    |             | Closure                                          | api        |
|        |          |             |             |                                                  | auth:api   |
|        | GET|HEAD | fr/message  | fr.message  | App\Http\Controllers\SiteController@get_message  | web        |
|        | POST     | fr/message  | fr.message  | App\Http\Controllers\SiteController@post_message | web        |
|        | GET|HEAD | fr/news     | fr.news     | Closure                                          | web        |
|        | GET|HEAD | fr/produits | fr.products | App\Http\Controllers\SiteController@get_products | web        |
|        | GET|HEAD | message     | en.message  | App\Http\Controllers\SiteController@get_message  | web        |
|        | POST     | message     | en.message  | App\Http\Controllers\SiteController@post_message | web        |
|        | GET|HEAD | news        | en.news     | Closure                                          | web        |
|        | GET|HEAD | products    | en.products | App\Http\Controllers\SiteController@get_products | web        |
+--------+----------+-------------+-------------+--------------------------------------------------+------------+

Additional context

The same thing happens if the route is defined as:

Route::post('message', 'SiteController@post_message');

What am I doing wrong?

Another Question - localized_route

Hi, i have another Q becouse i have something like this in href "{{ localized_route('front.index') }}" with this controller "Route::multilingual('/', 'FrontController@index')->name('front.index');" and it's work..without pl.front.index but why isn't work with other routes like this?

like:
Route::multilingual('/blog/wpis/{slug}', 'BlogController@show')->name('blog.show');
href ="{{ localized_route('blog.show') }}"

other problem:

image
image
image

Keep both prefixed and not-prefixed route

Hi, thank you for making such a clean and easy to use package.

I have a small question: when I declare my routes like Route::multilingual('test', 'TestController')->name('foo'); and have 'prefix_default' set to true, it will generate following routes:

Method URI Name Action
GET|HEAD en/test en.test App\Http\Controllers\TestController
GET|HEAD fr/teste fr.test App\Http\Controllers\TestController

Is that possible to simultaneously register the default route?

Method URI Name Action
GET|HEAD test test App\Http\Controllers\TestController

Thank you in advance!

Unable to localize the home route

Information

Cannot use multilingual on the / route.

How to reproduce

Change the supported locales to ['en', 'fr'].

Put the following in routes/web.php:

Route::multilingual('/', 'ShowFormController')->name('home');

Output

+--------+----------+------------+---------+-----------------------------------------+------------+
| Domain | Method   | URI        | Name    | Action                                  | Middleware |
+--------+----------+------------+---------+-----------------------------------------+------------+
|        | GET|HEAD | fr/routes. | fr.home | App\Http\Controllers\ShowHomeController | web        |
+--------+----------+------------+---------+-----------------------------------------+------------+

Add localized version of redirect->route()

Hey, I have another feature request, sorry for bothering you with them!

Usually when redirecting to a route we do someting like:
return Redirect::route('home.index');

but this doesn't work with multilingual routes. Instead, this work-around seems to do the job for now:
return Redirect::route(App::getLocale() . '.home.index');

My suggestion would be to add a localized version of this so that we can do something like:
return Redirect::localized_route('home.index');, or perhaps some sort of localized_redirect() helper function.

Add a way to get the current route name without the localization

Hi, it's me again ๐Ÿ˜….

I'm wanting to build links to different locale versions of the current route, based on whatever the current route is. This is for linking to different language versions for the current page in a generic manner. This is for use in a language dropdown selector.

This code works:
localized_route(substr(Route::currentRouteName(), 3), [], 'fr')
but is not such an elegant solution.

Route::currentRouteName() returns the localized version of the current route name, such as en.home.index. Maybe we need something which will return the current route name without the locale prefix? Route::parentRouteName() or similar? Or a parent_route_name() helper function. I struggled with how to name it, so perhaps there is a better way.

Or maybe even a simpler overall method, which will convert the current route to a different locale route. Something like: current_route('fr') which would return the French locale version of the current route.

Thanks for the help!

Add a localized and multilingual version of Request::routeIs()

In views, Request::routeIs() very useful for conditional matching of the current route. For instance when adding a class for a current active navigation link:
{!! Request::routeIs('home.index') ? ' class="active"' : '' !!}

This works nicely under a regular GET route like:
Route::GET('/', 'HomeController@index')->name('home.index');

However when we make the route multilingual:
Route::multilingual('/', 'HomeController@index')->name('home.index');

It no longer works so nicely, and now we need to handle it with something like:
{!! Request::routeIs(App::getLocale() . '.home.index') ? ' class="active"' : '' !!}

Maybe a new method could be a useful enhancement here to help with matching these multilingual routes. Perhaps something along the lines of Request::localizedRouteIs('home.index') or Request::multilingualRouteIs('home.index')? Or maybe something as simple as a new helper function such as localized_route_is('home.index')?

Thanks!

How to add parameter my route?

Can I add parameters multilingual URL. When I attach a parameter I get 404 error.

Route::multilingual('clinic-detail/{slug}', 'ClinicsController@details')->name('clinics.details');

Multi-segment route translation

I can only translate the first segment of each URL. For example:

return [
  'sonhos' => 'dreams',
  'contato' => 'contact',
  'sobre-nos' => 'about-us',
  'perguntas-frequentes' => 'common-questions',
  'termos-e-condicoes' => 'terms-and-conditions',
  'politica-de-privacidade' => 'privacy-policy',
  'idiomas' => 'languages',
];

So far it works normal. But when I need to translate this url for example: https://www.meempi.com/perfil/preferencias

I can't translate, how should I proceed in that case when the routes have more than one segment?

How to initiate this package?

"
UnexpectedValueException
Invalid route action: [App\Http\Controllers\FrontController].

App\Http\Controllers\FrontController is not invokable.
The controller class App\Http\Controllers\FrontController is not invokable. Did you forget to add the __invoke method or is the controller's method missing in your routes file?"

controller

Route::redirect('/', locale());
Route::multilingual('/', 'FrontController')->name('index');

Default route is not defined

My default home page route should be "en-us". However it is not working at all. When I try to access the route I get a 404 error. See:

My route:
Route::multilingual('/cadastrar', 'CadastroController@index')->name('cadastrar');

Configuration file:

return [

    'default' => env('MULTILINGUAL_ROUTES_DEFAULT_LOCALE', config('app.locale')),

    'prefix_default' => env('MULTILINGUAL_ROUTES_PREFIX_DEFAULT', true),

    'prefix_default_home' => env('MULTILINGUAL_ROUTES_PREFIX_DEFAULT_HOME', true),

    'name_prefix_before_locale' => env('MULTILINGUAL_ROUTES_NAME_PREFIX_BEFORE_LOCALE', false),
];

Config App:

'locale' => 'pt-br',

Because it does not work ?? if I change the locale to "en" then it works, but as "pt-br" it doesn't

Route constrains in different locale

Let's say for instance we have the following translation in the routes file:

return [
    'single-blog' => '{category}/{post}',
];

It is possible to constrain route parameters at the current time like this:

Route::multilingual()->where('category', 'food|music|aliments|musique');

This will allow the following routes:

https://example.test/food/slug-of-my-post
https://example.test/music/slug-of-my-post
https://example.test/aliments/slug-of-my-post
https://example.test/musique/slug-of-my-post
https://example.test/fr/food/slug-of-my-post
https://example.test/fr/music/slug-of-my-post
https://example.test/fr/aliments/slug-of-my-post
https://example.test/fr/musique/slug-of-my-post

However, in the english version of the website, we don't really want aliments or musique in the available categories. As for the french version, we wouldn't want food or music in the constrains.

Customize default locale for urls

Context

I have a site with the following locales: es (default), en (generic) and pt. The url structure should be as follows:

/nosotros //es
/en/about-us //en
/pt/sobre-nos //pt

That can be achieved by setting app.fallback_locale = 'es', however I need english to be the generic language.

Problem

Taking a look to the code, this function forces the default (hidden) url prefix, to be the same as the fallback_locale language.

protected function generatePrefixForLocale(string $key, string $locale) : ?string
    {
        if ($key == '/') {
            return null;
        }

        if ($locale != config('app.fallback_locale')) {
            return $locale;
        }

        return config('laravel-multilingual-routes.prefix_fallback')
            ? $locale
            : null;
    }

Potential fix

Just by adding a laravel-multilingual-routes.default_locale config param should do the trick. If you're happy with that, I can provide a PR.

Thanks

On 404 page, current_route with fallback throws an error

Describe the bug

When current_route() with a fallback is used in a template that is rendered on a 404 page, the helper throws an error rather than using the fallback route:

Call to a member function getName() on null

This is caused by the $route->getName() call on line 25:

$route = Route::getCurrentRoute();
$name = Str::replaceFirst(
locale().'.',
"{$locale}.",
$route->getName()
);

However, on a 404 page the result of Route::getCurrentRoute() is null so the method fails.

To Reproduce

Steps to reproduce the behavior:

  1. Try to access a non-existent page using a template which includes current_route() with a fallback.
  2. See error.

Expected behavior

The fallback should be returned if the current route is null.

Result of route:list:

Not applicable.

Additional context

Adding the following code appears to resolve the issue:

        $route = Route::getCurrentRoute();

+        if (! $route) {
+            return $fallback;
+        }

        $name = Str::replaceFirst(
            locale().'.',
            "{$locale}.",
            $route->getName()
        );

If this makes sense, I'd be happy to open a pull request.

Add support for view routes

Something like:

Route::multilingual('welcome');

To replace:

Route::view('welcome', 'welcome')->name('en.welcome');
Route::view('fr/welcome', 'welcome')->name('fr.welcome);

And to specify a view:

Route::multilingual('welcome')->view('app');

To replace:

Route::view('welcome', 'app')->name('en.welcome');
Route::view('fr/welcome', 'app')->name('fr.welcome');

Dependency clash with Laravel 11

Describe the bug

A clear and concise description of what the bug is.

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires chinleung/laravel-multilingual-routes ^4.1 -> satisfiable by chinleung/laravel-multilingual-routes[v4.1.0, v4.1.1].

    - Conclusion: don't install laravel/framework v11.0.2 (conflict analysis result)
    - chinleung/laravel-multilingual-routes[v4.1.0, ..., v4.1.1] require chinleung/laravel-locales ^2.0 -> satisfiable by chinleung/laravel-locales[v2.0.0, v2.0.1].
    - chinleung/laravel-locales v2.0.1 requires illuminate/support ^9.0|^10.0 -> satisfiable by illuminate/support[v9.0.0, ..., v9.52.16, v10.0.0, ..., v10.48.4].
    - chinleung/laravel-locales v2.0.0 requires illuminate/support ^9.0 -> satisfiable by illuminate/support[v9.0.0, ..., v9.52.16].
    - Only one of these can be installed: illuminate/support[v6.0.0, ..., v6.20.44, v7.0.0, ..., v7.30.6, v8.0.0, ..., v8.83.27, v9.18.0, ..., v9.52.16, v10.0.0, ..., v10.48.4, v11.0.0, ..., v11.2.0], laravel/framework[v11.0.0, ..., v11.2.0]. laravel/framework replaces illuminate/support and thus cannot coexist with it.

Steps to reproduce the behavior:

  1. Update composer.json ro require Laravel 11.
  2. composer update

Expected behavior

Dependencies to be updated.

Result of route:list:

Not applicable.

Additional context

Not applicable.

Crash with undefined offset after upgrading to Laravel 8

Describe the bug

Routes which directly display a view cause a crash at vendor\laravel\framework\src\Illuminate\Routing\ViewController.php:35, as seen in the attached trace back.
laravel.log

To Reproduce

Steps to reproduce the behavior:

  1. Create a new Laravel 8 app.
  2. Install laravel-multilingual-routes.
  3. Create app/locales.php with 'supported' => [ 'en', 'fr' ].
  4. In routes/web.php, add Route::multilingual('home')->view('welcome');
  5. Start PHP web browser in the public directory.
  6. Enter "http://localhost:8000/home" in web browser,

Expected behavior

The welcome page should have been displayed.

Result of route:list:

Please post the result of php artisan route:list here with the concerned routes.

+--------+----------+----------+---------+----------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------+---------+----------------------------------------------+------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api |
| | | | | | auth:api |
| | GET|HEAD | fr/home | fr.home | Illuminate\Routing\ViewController | web |
| | GET|HEAD | home | en.home | Illuminate\Routing\ViewController | web |
+--------+----------+----------+---------+----------------------------------------------+------------+

Additional context

Add any other context about the problem here.

Prefixed route results in 404

Describe the bug

When I group a route and prefix it, it throws a 404.

To Reproduce

Steps to reproduce the behavior:

  1. Go to 'routes/web.php'
  2. Make a grouped route
  3. Make a child route in the grouped route
  4. Navigate to child route
  5. See error

Expected behavior

Run controller method.

Result of route:list:

+--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------+
| Domain | Method   | URI                              | Name                  | Action                                               | Middleware    |
+--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------+
|        | GET|HEAD | /                                |                       | Closure                                              | web           |
|        | GET|HEAD | api/user                         |                       | Closure                                              | api           |
|        |          |                                  |                       |                                                      | auth:api      |
|        | GET|HEAD | blog/                            | en.blog.index         | App\Http\Controllers\BlogController@index            | web           |
|        | GET|HEAD | blog/create                      | en.blog.create        | App\Http\Controllers\BlogController@create           | web           |
|        | GET|HEAD | blog/edit/{post}                 | en.blog.edit          | App\Http\Controllers\BlogController@edit             | web           |
|        | GET|HEAD | blog/show/{post}                 | en.blog.show          | App\Http\Controllers\BlogController@show             | web           |
|        | GET|HEAD | livewire/livewire.js             |                       | Livewire\Controllers\LivewireJavaScriptAssets@source |               |
|        | GET|HEAD | livewire/livewire.js.map         |                       | Livewire\Controllers\LivewireJavaScriptAssets@maps   |               |
|        | POST     | livewire/message/{name}          | livewire.message      | Livewire\Controllers\HttpConnectionHandler           | web           |
|        | GET|HEAD | livewire/preview-file/{filename} | livewire.preview-file | Livewire\Controllers\FilePreviewHandler@handle       | web           |
|        | POST     | livewire/upload-file             | livewire.upload-file  | Livewire\Controllers\FileUploadHandler@handle        | web           |
|        |          |                                  |                       |                                                      | throttle:60,1 |
+--------+----------+----------------------------------+-----------------------+------------------------------------------------------+---------------+

My routes/web.php:

<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::group(['prefix' => 'blog'], function () {
    $c = App\Http\Controllers\BlogController::class;

    Route::multilingual('/', [$c, 'index'])->name('blog.index');
    Route::multilingual('/create', [$c, 'create'])->name('blog.create');
    Route::multilingual('/edit/{post}', [$c, 'edit'])->name('blog.edit');
    Route::multilingual('/show/{post}', [$c, 'show'])->name('blog.show');
});

If I navigate to /blog it throws a 404. And if I change the child route to get it works:

Route::get('/', [$c, 'index'])->name('blog.index');

Prefixed routes do not localize the URI

Describe the bug

The URI isn't properly localized when a the routes are use a prefix defined in a group. The outputted routes will use the unlocalized URI

To Reproduce
Say you define a route such as:

Route::prefix('test')
    ->group(function () {
        Route::multilingual('route', function () {
            return 'test';
        });
    });

And have a French translation file at resources/lang/fr/routes.php with something like:

<?php

return [
    'test/route' => 'teste/french-route',
];

The routes available are:

  • test/route
  • fr/test/route

Expected behavior

The route should be localized based on the translation file. With the above sample one would expect the following routes.

  • test/route
  • fr/teste/french-route

Additional context

If the routes are defined without the prefix and group they are localized correctly. e.g.:

Route::multilingual('/test/route', function () {
    return 'test';
});

Prefixes in wrong order when Route::prefix groups

When using route groups that have a prefix defined will have the prefixes set in the wrong order.

Route::prefix('backend')->group(function () {
    Route::multilingual('/users', 'UsersController@index')->name('backend.users.index');
});
Expected Output Actual Output
en/backend/users backend/en/users

How to deal with Route::resource()?

What's the best way to deal with Resource Controllers?

Since there is no Route::multilingualResource() at the moment, I've solved it like this.

Before:

Route::resource('companies', \App\Http\Controllers\CompanyController::class)

After:

Route::multilingual('companies', [\App\Http\Controllers\CompanyController::class, 'index'])->name('companies.index');
Route::multilingual('companies/create', [\App\Http\Controllers\CompanyController::class, 'create'])->name('companies.create');
Route::multilingual('companies/{company}', [\App\Http\Controllers\CompanyController::class, 'show'])->name('companies.show');
Route::multilingual('companies/{company}/edit', [\App\Http\Controllers\CompanyController::class, 'edit'])->name('companies.edit');

Route::resource('companies', \App\Http\Controllers\CompanyController::class)->only([
    'store', 'update', 'destroy'
]);

Is there a better way to solve this?

Customize 404 and 500 error pages

I try to customize error pages for the 404 and 500 error using Laravel 8.x , but i don't know how to handel these errors with multilingual-routes.

I have 2 baldes in /resources/views/errors/404.blade.php and /resources/views/errors/500.blade.php

I edited /app/Exceptions/Handler.php:

Captura de pantalla 2021-03-19 a las 13 39 59

But when i type a no existing url (http://localhost/sdfsdfsdfsd) i keep seeing the standard error message and not my customized error page:

Captura de pantalla 2021-03-19 a las 13 31 57

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.