multiple prefix with the same route group

牧云@^-^@ 提交于 2019-12-12 07:44:45

问题


im writing a fairly simple website for a school ... this website has news , articles , video clips ... etc

the way it works is in the home page we present visitor with some lessons like

>math 
>geography 
>chemistry 

user selects 1 on these and website contents changes based on the user selection

for example if user selects math he will see news , article , videos about math and so on ... right now this is what im doing (pleas ignore syntax errors)

Route::group(['prefix'=>'math'], function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
});

Route::group(['prefix'=>'geography'], function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
});

Route::group(['prefix'=>'chemistry'], function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
});

basically repeating all links for each prefix .... but as the links grow it will become more and more unmanageable ... is there any better way to do this ? something like

Route::group(['prefix'=>['chemistry','math' , 'geography' ], function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
});

------------------------- update -------------

i've tried this

$myroutes =  function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
};

Route::group(['prefix' => 'chemistry'], $myroutes);
Route::group(['prefix' => 'math'], $myroutes);
Route::group(['prefix' => 'geography'], $myroutes);

and it works fine , the problem is the last prefix gets attached to all the internal links

for example if i click on math

my links will be

site.com/math/news

but all the links on the loaded page like

<a href="{{route('article_index')"> link to article </a>

look like

site.com/geography/article

basically link get the last mentioned prefix regardless of currently selected one


回答1:


Why not do it this way:

$subjects = [
    'chemistry', 'geography', 'math'
];

foreach ($subjects as $subject) {
    Route::prefix($subject)->group(function () {
        Route::get('news', 'NewsController@index')->name('news_index');
        Route::get('article', 'ArticleController@index')->name('article_index');
    });
}

I know this is an elementary way do to it. Yet you can easily add subjects, it is clear and effortless to understand.




回答2:


I think it's better to do:

Route::get('/news/{group}', 'NewsController@index')->name('news_index')->where('group', 'math|geography|chemistry');

And then just put condition on the controller function whether it is geography/math/chemistry/etc.

Don't you think?




回答3:


You can try following:

$myroutes =  function () {
    Route::get('/news', 'NewsController@index')->name('news_index');
    Route::get('/article', 'ArticleController@index')->name('article_index');
};

Route::group(['prefix' => 'chemistry'], $myroutes);
Route::group(['prefix' => 'math'], $myroutes);
Route::group(['prefix' => 'geography'], $myroutes);

Use as following:

 {!!URL::to('chemistry/news')!!}
 {!!URL::to('geography/news')!!}
 {!!URL::to('math/news')!!}



回答4:


You could try to use the as option within your groups to tell the Router to prepend a string to every route name within that group. To do so try the following:

Route::group(['prefix' => 'chemistry', 'as' => 'chemistry.'], $myroutes);
Route::group(['prefix' => 'math', 'as' => 'math.'], $myroutes);
Route::group(['prefix' => 'geography', 'as' => 'geography.'], $myroutes);

So what you will be able to do should be:

<a href="{{route('chemistry.article_index')}}"> link to article </a>
<a href="{{route('math.article_index')}}"> link to article </a>
<a href="{{route('geography.article_index'}})"> link to article </a>

Hope it helps.




回答5:


There are several good answers here already, it is probably just a matter of personal preference or deeper project specifics which one suits. Here's another option for the pile.

I am not sure why @Shams answer was downvoted, it seems like the cleanest approach to me - but only if the prefixes are constrained so that only valid subjects are accepted. Something like:

// Only 1 place to update if you add subjects
$subjectRegex = 'math|geography|chemistry';

// Only 1 route per 'group'
Route::get('{subject}/news', 'NewsController@index')->name('news_index')->where('subject', $subjectRegex);
Route::get('{subject}/article', 'ArticleController@index')->name('article_index')->where('subject', $subjectRegex);

As a bonus you have $subject available in your Controller methods, which seems like it might be useful, for example you can use it to generate routes within the current subject:

route('article_index', ['subject' => $subject])



回答6:


You can wildcard the route group and specify the preferred prefixes in your RouteServiceProvider

routes.php

Route::group(['prefix'=>'{slug}'],function (){
 Route::get('/news', 'NewsController@index')->name('news_index');
 Route::get('/article', 'ArticleController@index')->name('article_index');
});

RouteServiceProvider boot method

Route::bind('slug',function ($name){
   $prefix = ["math","chemistry","geography"];
    if(!in_array($name,$prefix))
     {
        //handle wrong prefixes
        throw new \Exception("Something went wrong");
     }
 });

use named route

{{route('news_index',['slug'=>'math'])}}




回答7:


Just for Curiosity sake I attempted optional parameter on prefix route grouping in laravel and it worked. Check it out:

Route::group(['prefix' => '{subject?}', 'as'=> 'subject.', where' => ['subject' => 'math|english|geo']],function (){
    Route::get('news', function (){
       return 'This is the news';
    })->name('news');
});

Pretty sure this is the solution you dreamt of.

Well before this would be the correct answer, there might be a little issue. Calling route('subject.news') will give http://example.com/news. To make it happy, you have to pass the optional parameter to route() function i.e. route('subject.news','math'); for example; then you'll have http://example.com/math/news.

PS: This was done on Laravel 5.4.30 PHP 7.1




回答8:


Instead of grouping you can use route parameters

Route::get('/{prefix}/news', 'NewsController@index')->name('news_index');
Route::get('/{prefix}/article', 'ArticleController@index')->name('article_index');


来源:https://stackoverflow.com/questions/45809006/multiple-prefix-with-the-same-route-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!