出于SEO目的,我希望为电子商务商店扁平化我的路线。
我想创建以下路线:
Route::get('/{country}', ['uses' => 'Store'ProductController@browseCountry']);
Route::get('/{category}, ['uses' => 'Store'ProductController@browseCategory']')
country
和category
必须是动态的。
我想知道是否可能出现以下情况? 以及实现的最佳方式。
// Route 1
Route::get('/{country}', ['uses' => 'Store'ProductController@browseCountry'])
->where('country', ProductCountry::select('slug')->get());
// Route 2
Route::get('/{category}', ['uses' => 'Store'ProductController@browseCategory'])
->where('category', ProductCategory::select('slug')->get());
示例路由:
/great-britain should be routed via Route 1
/china should be routed via Route 1
/widgets should fail route 1, but be routed via Route 2 because
widgets are not in the product_country table but are in
the product_category table
我知道我可以对可能的国家/地区的路线进行硬编码:
Route::get('/{country}', ['uses' => 'Store'ProductController@browse'])
->where('country', 'great-britain|china|japan|south-africa');
然而,这是笨拙和乏味的。我想从数据库中获取国家列表。
我会这样做,我选择国家模型,因为需要缓存的模型更少+:将列表("名称")更改为国家/地区名称列
Route::get('/{country}', ['uses' => 'Store'ProductController@browseCountry'])
->where('country', implode('|',ProductCountry::select('slug')->lists('name')));
它的作用是选择所有国家/地区名称并像这样将它们作为数组返回
('usa','england','thailand')
并使用带有"|"的内爆作为胶水返回以下内容:
usa|england|thailand
所以你的最终路线是这样的:
Route::get('/{country}', ['uses' => 'Store'ProductController@browseCountry'])
->where('country', 'usa|england|thailand');
好的,在查看更新后的问题后,您需要在各自的模型中创建一个方法,将所有可用的 slug 与 | 字符连接起来,因此您可以调用类似以下内容:
Route::get('/{country}', ['uses' => 'Store'ProductController@browseCountry'])
->where('country', ProductCountry::getSlugs());
这几乎会像您的示例一样返回"英国|中国|日本|南非",除非您不必编写它。
但是,我强烈建议您为路线提供更多的东西,/country/{country} 或/category/{category},否则会令人困惑,并且 URI 结构通常是这种方式,以便用户可以准确地看到他们在哪里。
您需要路由过滤器来实现这一点。
将以下代码放入filters.php
或route.php
文件中
Route::filter('country', function()
{
$country = Country::where('slug', Route::input('country'))->first();
if( ! $country) {
dd("We do not support this country");
// Redirect::route('home');
}
});
最后是你的路线:
Route::get('country/{country}', array('before' => 'country', 'uses' => 'Store'ProductController@browseCountry'));