问题
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