user237329
user237329

Reputation: 819

Laravel optional prefix routes with regexp

Is there a way to create routes with prefixes so I can have routes like this

/articles.html -> goes to listing Controller in default language
/en/articles.html -> goes to the same controller
/fr/articles.html -> goes to the same controller

My current problem is that by doing:

Route::group(['prefix' => '/{$lang?}/', function () {});

a route like this: /authors/author-100.html will match the prefix authors, and for sure there is no language called "authors".

I use Laravel 5.5

Upvotes: 11

Views: 11843

Answers (4)

omitobi
omitobi

Reputation: 7334

This should be sufficient using the where Regex match on the optional route parameter:

Route::get('/{lang?}', 'SameController@doMagic')->where('lang', 'en|fr');

You can do the same on Route Group as well, else having all the options as in this answer works.

An update to show the use of prefixes:

Route::group(['prefix' => '{lang?}', 'where' => ['lang' => 'en|fr']],function () {
    Route::get('', 'SameController@doNinja');
});

This should be sufficient even when there is no language and, likewise, when there is one, just maybe this group could come before other routes.

Upvotes: 10

Yezan Rafed
Yezan Rafed

Reputation: 782

Another working solution would be to create an array of langs and loop over it:

$langs = ['en', 'fr', ''];

foreach($langs as $lang) {
  Route::get($lang . "/articles", "SomeController@someMethod");
}

For sure this makes your route file less readable, however you may use php artisan route:list to clearly list your routes.

Upvotes: 2

edruid
edruid

Reputation: 703

There doesn't seem to be any good way to have optional prefixes as the group prefix approach with an "optional" regex marker doesn't work. However it is possible to declare a Closure with all your routes and add that once with the prefix and once without:

$optionalLanguageRoutes = function() {
    // add routes here
}

// Add routes with lang-prefix
Route::group(
    ['prefix' => '/{lang}/', 'where' => ['lang' => 'fr|en']],
    $optionalLanguageRoutes
);

// Add routes without prefix
$optionalLanguageRoutes();

Upvotes: 11

aaron0207
aaron0207

Reputation: 2333

You can use a table to define the accepted languages and then:

Route::group([
    'prefix' => '/{lang?}',
    'where' => ['lang' => 'exists:languages,short_name'],
], function() {

    // Define Routes Here
});

Upvotes: 1

Related Questions