如何自动将 post 的类别添加到 url 之前?

How auto prepend post's category to url?

在 Yii2 中,我有博客文章,每篇文章有 1 个类别。规则是这样的:

'rules' => [
    '<category_slug>/<article_slug>' => 'article/view',
],

控制器:

public function actionView($category_slug, $article_slug)
{
    ...
}

类别存储在 params.php:

<?php
return [
    'categories' => [
        [
            'id' => 1,
            'name' => 'First category',
            'slug' => 'first_category',
        ],
        ...
    ],
];

Url 到文章:

Url::to(['article/view', 'category_slug' => $model->category_slug, 'article_slug' => $model->article_slug])

问题: 是否可以将类别 slug 自动添加到 Url::to?我的意思是,你只需要 Url::toarticle_slug 参数。我想最好的解决方案是以某种方式更改 url 规则,但具体如何更改?

'rules' => [
    '<Yii::$app->MyFunction->GetCategorySlugByArcticleId(..)>/<article_slug>' => 'article/view',
],

这应该很简单。

选项一:扩展 Url-Helper

简单地扩展Url-Helper如下:

class MyUrl extends \yii\helpers\Url
{

    //extending regular `to`-method
    public static function to($url = '', $scheme = false)
    {
        //check if url needs completion and meets preconditions
        if (is_array($url) && strcasecmp($url[0], 'article/view') === 0 && isset($url['article_slug']) && !isset($url['category_slug'])) {
            //add category slug if missing...assuming you have a relation from article to category and category having a property `slug`
            $url['category_slug'] = $article->category->slug;
        }
        
        return parent::to($url, $scheme);
    }

    //...or custom method for your case which is even more convenient
    public static function toArticle($article, $scheme=false)
    {
        //article could be an article model itself or an id
        $articleModel = $article instanceof Article ? $article : Article::findOne($article);
        return parent::to([
            'article/view',
            'article_slug'=>$articleModel->slug,
            'category_slug'=>$articleModel->category->slug,
        ], $scheme);
    }

}

您现在所要做的就是使用 class 而不是常规的 Url-helper!

选项二:在您的文章模型中添加一个方法

只需添加一个方法如下:

class Article extends \yii\db\ActiveRecord
{
    //...

    public function link($scheme=false)
    {
        return Url::to([
            'article/view',
            'article_slug'=>$this->slug,
            'category_slug'=>$this->category->slug,
        ], $scheme);
    }

    //...
}

如果您需要更多信息,请告诉我!