With below route I expect to catch sitemap.xml
and sitemap-0.xml
. But it only catches sitemap-0.xml
. Can you help me understand why it doesn't work?
Route::get('/sitemap{suffix?}.xml', 'SitemapController@sitemap');
In the controller I then do this: public function sitemap($suffix = null)
Of course I can make an additional route called Route::get('/sitemap.xml', 'FeedsController@sitemap');
but that seems redundant.
CodePudding user response:
It should work if you put a constraint on the route via Regular Expression and make that optional. See the following route example should work:
<?php
Route::get('/sitemap{suffix?}.xml', 'SitemapController@sitemap')
->where('suffix', '-?([0-9] )?');
Why is that?
This is happening because of the Regular Expression. The Laravel route works based on the Symfony route which works based on the Regular Expression. So when you have a route like the one you referred to
'/sitemap{suffix?}.xml'
will be converted to the following one to be matched/working with the application.
"{^/sitemap(?P<suffix>[^/\.] )\.xml$}sDu"
Now take the part that is wrapped with the parenthesis which is called Named Capturing Group.
(?P<suffix>[^/\.] )
If you want to check the skeleton of the named capturing group that would be as the following:
(?P<name>group)
Here the group part of that regular expression says to match anything except a forward slash (/) and a dot (.) before the .xml
. This means it matches sitemap-0.xml
or will match anything in place of -0
in sitemap-0.xml
.
So when you omit -0
from sitemap-0.xml
, the group part (as it is NOT optional) does not have anything to match before .xml
. Thus it does not match sitemap.xml
.
To solve this issue you should put a constraint on the route as I did above which produces the following regular expression:
"{^/sitemap(?P<suffix>-?(?:[0-9] )?)\.xml$}sDu"
Here I tell the route to allow -
and [0-9]
optionally. Thus it matches both.