在我们blog中,文章可能显示在列表中或者单个显示。前一个由list动作(action)处理,后一个由show动作(action)处理。在本节中我们按照需求修改完善这两个操作
完善显示操作
显示操作由PostController的actionShow()方法处理数据,由视图文件blog/protected/views/post/show.php展示页面。
下面是PostController中的显示操作的相关代码
- public function actionShow()
- {
- $this->render('show',array(
- 'post'=>$this->loadPost(),
- ));
- }
- private $_post;
- protected function loadPost($id=null)
- {
- if($this->_post===null)
- {
- if($id!==null || isset($_GET['id']))
- $this->_post=Post::model()->findbyPk($id!==null ? $id : $_GET['id']);
- if($this->_post===null || Yii::app()->user->isGuest &&
- $this->_post->status!=Post::STATUS_PUBLISHED)
- throw new CHttpException(500,'The requested post does not exist.');
- }
- return $this->_post;
- }
我们的修改主要位于loadPost()方法,该方法中我们用GET中的id参数查询Post表。如果没有记录,或者文章没有发布,将抛出一个 500 HTTP 错误。其他情况下post对象被返回到actionShow()方法中。actionShow()方法将其传递到视图文件进行显示。
Yii 捕获HTTP异常并用预先准备的模板进行显示。这些模板可以在每个应用中进行修改定制。在向导的最后我们将详细的描述相关信息
视图文件的修改主要在于显示的格式和样式。此处不做详细介绍。
完善列表
和显式操作一样,我们将在两个地方进行修改。actionList()方法和对应的视图文件blog/protected/views/post/list.php。我们主要增加了相关tag的文章展示
下面是对PostController中actionList()的修改
- public function actionList()
- {
- $criteria=new CDbCriteria;
- $criteria->condition='status='.Post::STATUS_PUBLISHED;
- $criteria->order='createTime DESC';
- $withOption=array('author');
- if(!emptyempty($_GET['tag']))
- {
- $withOption['tagFilter']['params'][':tag']=$_GET['tag'];
- $postCount=Post::model()->with($withOption)->count($criteria);
- }
- else
- $postCount=Post::model()->count($criteria);
- $pages=new CPagination($postCount);
- $pages->applyLimit($criteria);
- $posts=Post::model()->with($withOption)->findAll($criteria);
- $this->render('list',array(
- 'posts'=>$posts,
- 'pages'=>$pages,
- ));
- }
注意的是Yiic工具产生的代码中最后返回的是postList,上面的代码中返回的是posts。这样一来还需要修改view中的postList为posts,建议继续使用postList。因为官方文档是posts所以上面没做更改
上面的代码中我们首先建立了一个查询规范,来指定只有已经发布的文章才能被显示出来,记录按照建立时间降序排列。计算符合条件的文章的总数以便分页组件正确计算出有多少页需要展示。然后我们从数据库读取信息,发送到视图文件进行显示。
如果GET参数中指定了Tag。则需要用tagFilter按照参数进行查询。加载tagFilter可以确保对指定的tag只产生一个SQL JOIN进行查询,否则,Yii会把语句分成两部分,返回不正确的结果。
$posts和$pages两个变量被发送到视图文件,分别包含了文章和评论的信息。如果记录过多,list视图文件包含的pagination widget可以根据在不同的页自动进行分页显