Create yii2 dynamic pages with the URL: www.example.com/pageName

On my system, users must have their profile pages. I am suggested that these pages display in the url as follows:

www.example.com/John-Doe www.example.com/Mary-Smith 

How to reach these urls in yii2? These John-Doe and Mary-Smith can be user names or user names. For example, I have a field in a user table with the name "name" and it will have the names "John Doe", "Mary Smith". Please note that I need friendly URLs for SEO with "-" instead of spaces.

URLs: www.example.com/profile/view?id=1 are not an option.

+5
source share
1 answer
 www.example.com/John-Doe www.example.com/Mary-Smith 

I think there is no normal way to use these URLs, because you need to define a controller first (in your case, it is ProfileController ). Of these URLs, this cannot be done.

The second problem with the addresses you specify is that uniqueness is not guaranteed. What should I do if another user with the name John Doe is registered on the site?

See an example of your profile link in Stack Overflow:

 http://stackoverflow.com/users/4395794/black-room-boy 

This is not http://stackoverflow.com/black-room-boy and not even http://stackoverflow.com/users/black-room-boy .

Combining id and name is a more common and reliable approach. They can also be combined with a dash as follows: http://stackoverflow.com/users/4395794-black-room-boy

Yii 2 has a built-in behavior for this, it is called SluggableBehavior .

Attach it to your model:

 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', ], ]; } 

For your specific URL format, you can also specify $value :

 'value' => function ($event) { return str_replace(' ', '-', $this->name); } 

This is just an example of creating a custom pool. Correct it according to your name attribute attributes and check / filter before saving.

Another way to achieve a unique URL is to set the $ ensureUnique property to true .

So, in the case of John-Doe existense, John-Doe-1 will generate slug, etc.

Note that you can also specify your own unique generator by setting $ uniqueSlugGenerator .

Personally, I do not like this approach.

If you choose an option similar to the one used by Stack Overflow, add it to your URL rules:

 'profile/<id:\d+>/<slug:[-a-zA-Z]+>' => 'profile/view', 

In 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.'); } } 

But actually id enough to find the user. The stack overflow is redirected if you use the correct id but another slug . Redirecting occurs when you also completely miss the name.

For example, http://stackoverflow.com/users/4395794/black-room-bo redirected to the original page http://stackoverflow.com/users/4395794/black-room-boy to avoid duplication of content that is not desirable for SEO.

If you want to use this as well, change the findModel() method as follows:

 protected function findModel($id) { if (($model = User::findOne($id) !== null) { return $model; } else { throw new NotFoundHttpException('User was not found.'); } } 

And actionView() as follows:

 public function actionView($id, $slug = null) { $model = $this->findModel($id); if ($slug != $model->slug) { return $this->redirect(['profile/view', ['id' => $id, 'slug' => $model->slug]]); } } 
+9
source

Source: https://habr.com/ru/post/1211254/


All Articles