bla*_*boy 5 php url seo routing yii2
In my system, users need to have their profile pages. It is requested from me that these pages will be displayed in url like this:
www.example.com/John-Doe
www.example.com/Mary-Smith
Run Code Online (Sandbox Code Playgroud)
如何在yii2中实现这些URL?这些John-Doe和Mary-Smith可以是用户用户名或配置文件名.例如,我在用户表中有一个名为"name"的字段,它将包含名称"John Doe","Mary Smith".注意我需要SEO友好的URL与" - "而不是空格.
像这样的网址:www.example.com/profile/view?id = 1不是一个选项.
www.example.com/John-Doe
www.example.com/Mary-Smith
Run Code Online (Sandbox Code Playgroud)
我认为没有正常的方法来使用这些网址,因为首先ProfileController需要确定控制器(在你的情况下).从这些网址来看,这是不可能的.
您提供的网址存在第二个问题 - 无法保证唯一性.如果有其他名字的用户John Doe会在网站上注册怎么办?
例如,在Stack Overflow的配置文件链接中查找:
http://stackoverflow.com/users/4395794/black-room-boy
Run Code Online (Sandbox Code Playgroud)
它不是http://stackoverflow.com/black-room-boy,甚至不是http://stackoverflow.com/users/black-room-boy.
结合id并且name是更广泛和更健全的方法.他们也可以像这样结合破折号:http://stackoverflow.com/users/4395794-black-room-boy
Yii 2具有内置的行为,它被称为SluggableBehavior.
将它附加到您的模型:
use yii\behaviors\SluggableBehavior;
public function behaviors()
{
return [
[
'class' => SluggableBehavior::className(),
'attribute' => 'name',
// In case of attribute that contains slug has different name
// 'slugAttribute' => 'alias',
],
];
}
Run Code Online (Sandbox Code Playgroud)
对于您的特定网址格式,您还可以指定$value:
'value' => function ($event) {
return str_replace(' ', '-', $this->name);
}
Run Code Online (Sandbox Code Playgroud)
这只是生成自定义slug的一个示例.name保存之前,请根据属性功能和验证/过滤进行更正.
实现唯一URL的另一种方法是将$ ensureUnique属性设置为true.
所以在的情况下,John-Doe存在性John-Doe-1蛞蝓将产生等.
请注意,您还可以通过设置$ uniqueSlugGenerator callable 来指定您自己的唯一生成器.
我个人不喜欢这种方法.
如果您选择类似于Stack Overflow使用的选项,请将其添加到您的网址规则中:
'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view',
Run Code Online (Sandbox Code Playgroud)
在ProfileController:
public function actionView($id, $slug)
{
$model = $this->findModel($id, $slug);
...
}
protected function findModel($id, $slug)
{
if (($model = User::findOne(['id' => $id, 'name' => $slug]) !== null) {
return $model;
} else {
throw new NotFoundHttpException('User was not found.');
}
}
Run Code Online (Sandbox Code Playgroud)
但实际上id足以找到用户.如果您使用正确id但不同的访问权限,Stack Overflow会重定向slug.当您完全跳过名称时,会发生重定向.
例如,http://stackoverflow.com/users/4395794/black-room-bo重定向到原始页面http://stackoverflow.com/users/4395794/black-room-boy以避免对SEO不利的内容重复.
如果你也想使用它,修改findModel()方法如下:
protected function findModel($id)
{
if (($model = User::findOne($id) !== null) {
return $model;
} else {
throw new NotFoundHttpException('User was not found.');
}
}
Run Code Online (Sandbox Code Playgroud)
而actionView()像这样:
public function actionView($id, $slug = null)
{
$model = $this->findModel($id);
if ($slug != $model->slug) {
return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5763 次 |
| 最近记录: |