-1

I have read the question on using SluggableBehavior in Yii2

and in my trial case I can generate url like article/1/First-Article using the rule in urlManager

'article/<id:\d+>/<slug>' => 'article/view',

and using

\yii\helpers\Url::to(['article/view', 'id'=>$model->id, 'slug'=>$model->slug])

to create url.

In my real case, I use ['article/view', 'hash'=> $model->hash, 'slug'=>$model->slug] to generate url. My rule is

'article/<hash:[\d-\w]+>/<slug>'=>'article/view'

My url is like article/1e482d69129d760e9494b2c6e86eba2b/First-Article.

I want to only show url like article/First-Article, i.e. not showing the hash code in the url. Is there a way to achieve this? Thanks a lot!

J S
  • 21
  • 4

1 Answers1

-1

According to Yii docs, if your specify SluggableBehavior's attribute property with an array of model attributes, it will implode (concatenate) them in order to generate uniqueness for the slug. In your case, this implementation perfectly satisfies your desired slug concatenated composition (e.g. First-Article-1);

Internally SluggableBehavior will perform it's generateSlug method to generate unique slug from your attributes composition defined in attribute property.

Since generateSlug uses - delimiter by default, it perfectly fits your requirements in order to generate desired url slug.

Take a look into this:

public function behaviors() 
{   
     return [
         [
             'class' => SluggableBehavior::className(),
             'attribute' => ['slug', 'id'],
             ...
         ]
     ];
}

EDIT:

This is your URL Rule: 'article/<slug>' => 'article/view'

and

Generating appropriate link: Url::to(['article', 'slug' => $model->slug . '-' . $model->id])

G.Spirov
  • 198
  • 9
  • Thank you G.Spirov. But the problem I am encountering is that I cannot generate a url without id in it. I can only generate article/1/First-Article, but not article/First-Article. Do you have idea how to realize this? – J S Apr 25 '20 at 13:59
  • Thank you. But I have difficulty to try you code. I shall rewrite my question to make it clearer. – J S Apr 25 '20 at 14:17
  • What makes it difficult? Can I help you with? – G.Spirov Apr 25 '20 at 14:21
  • Yes. Can you please read the revised question? Thanks a lot :) – J S Apr 25 '20 at 14:24
  • I'm afraid that you cannot achieve this because as you pointed earlier you may have 1 or more models with same title and basically you should guarantee uniqueness between different articles. That's why `attribute` property of `SlugableBehavior` is able to be defined as string or array, in order to apply uniqueness with composition between **multiple** model attributes. – G.Spirov Apr 25 '20 at 14:29
  • I agree. But currently my plan is to generate unique slug by myself as there are only a few articles. Or maybe use 'ensureUnique'=> true in behaviors(). If uniqueness is not a problem, is it possible to remove hash code? – J S Apr 25 '20 at 14:37
  • The urls like `article/create`, `article/update` or `article/delete` will also match URL rule `'article/' => 'article/view'`. If that rule is defined first there will be no way to reach those actions. You need to put rules for these actions before the view rule and you should make sure that generated slugs will never match the other action names. – Michal Hynčica Apr 25 '20 at 17:21
  • I see. Thanks a lot, Michal Hynčica. I will refine the rules once I have done with hash code in the url. – J S Apr 26 '20 at 02:11