1、创建文章详情方法
PostsController控制器中创建文章详情方法
/** * 文章详情 * @param $id * @return string */ public function actionView($id) { $model = new PostsForm(); $data = $model->getViewById($id); return $this->render('view',['data'=>$data]); }
2、实现文章详情内容获取方法
在PostsForm中实现getViewById方法
/** * 文章详情 * @param $id * @throws NotFoundHttpException */ public function getViewById($id) { $res = PostsModel::find()->with('relate.tag')->where(['id'=>$id])->asArray()->one(); if (!$res){ throw new NotFoundHttpException('文章不存在'); } }
3、通过关联关系获取tags标签
//首先获取文章与标签的关联ID public function getRelate() { return $this->hasMany(RelationPostTagsModel::className(),['post_id'=>'id']); }
//然后通过关联关系获取关联标签 public function getTag() { return $this->hasOne(TagsModel::className(),['id'=>'tag_id']); }
这里对第二步中文章详情页内容获取方法中的 with('relate.tag') 解释下,不然有些人可能看不懂getRelate和getTag这两个方法。
文章详情获取标签的第一步,先获取文章和标签的关联关系,所以文章详情获取方法如下
/** * 文章详情 * @param $id * @throws NotFoundHttpException */ public function getViewById($id) { $res = PostsModel::find()->with('relate')->where(['id'=>$id])->asArray()->one(); if (!$res){ throw new NotFoundHttpException('文章不存在'); } }
也就是with方法中只有‘relate’获取关联关系,然后PostsModel中需要有一个获取文章标签关联关系的方法,也就是getRelate方法,所以with中的‘relate’对应的是getRelate方法。因为我们的关联关系表(relation_post_tags)存放的是标签id和标签关联的文章数,并没有标签名。
所以第二步,需要通过关联关系获取到标签名,于是文章详情获取的方法变成了这样
/** * 文章详情 * @param $id * @throws NotFoundHttpException */ public function getViewById($id) { $res = PostsModel::find()->with('relate.tag')->where(['id'=>$id])->asArray()->one(); if (!$res){ throw new NotFoundHttpException('文章不存在'); } }
因为需要通过关联关系获取标签名,所以需要在 RelationPostTagsModel 写一个关联关系方法来获取标签名,也就是getTag方法。这两个get方法后面的名字都要与with中的相对应,只不过with中都小写,但在get中首字母需要大写。
以上就是with('relate.tag')详细解释。当然了,在具体操作的时候可以一个一个参数和方法的写,然后把$res 结果打印出来,看看是否与上面的解释一致。
4、对获取到的标签做格式处理
/** * 文章详情 * @param $id * @throws NotFoundHttpException */ public function getViewById($id) { $res = PostsModel::find()->with('relate.tag')->where(['id'=>$id])->asArray()->one(); if (!$res){ throw new NotFoundHttpException('文章不存在'); } $res['tags']=[]; if(isset($res['relate']) && !empty($res['relate'])){ foreach ($res['relate'] as $list){ $res['tags'][]=$list['tag']['tag_name']; } } unset($res['relate']); return $res; }
5、详情页布局
到这里详情页的数据基本已经获取到了,接下来就要把这些详情数据渲染到页面了,在frontend/views/posts 下新建一个view.php页面 view.php页面的内容
<?php $this->title=$data['title']; $this->params['breadcrumbs'][]=['label'=>'文章','url'=>['posts/index']]; $this->params['breadcrumbs'][]=$this->title; ?> <div class="row"> <div class="col-lg-9"> <div class="page-title"> <h1><?=$data['title']?></h1> <span>作者:<?=$data['user_name']?></span> <span>发布:<?=date('Y-m-d',$data['created_at'])?></span> <span>浏览:0 次</span> </div> <div class="page-content"> <?=$data['content']?> </div> <div class="page-tag"> 标签: <?php foreach ($data['tags'] as $tag):?> <span><a href="#" ><?=$tag?></a></span> <?php endforeach;?> </div> </div> <div class="col-lg-3"> </div> </div>
view页面css样式,把下面的css样式加入frontend/web/statics/css/site.css中
.page-title { border-bottom: 1px solid #eee; margin-bottom: 10px; padding-bottom: 5px; } .page-title h1 { font-size: 18px; margin: 4px 0 10px; } .page-title span { color: #999; font-size: 12px; margin-right: 5px; } .page-content { border-bottom: 1px solid #eee; margin-bottom: 10px; min-height: 400px; }
文章详情效果展示图