日志显示

在我们的博客应用中,一篇日志可以显示在一个列表中,也可以单独显示。前者的实现通过 index 操作,而后者是通过 view 操作。 在这一节中,我们将自定义这两个操作来适合我们一开始的需求。

1. 自定义 view 操作

view 操作是通过 PostController 中的 actionView() 方法实现的。它的显示是通过 view 视图文件 /wwwroot/blog/protected/views/post/view.php 生成的。

下面是在 PostController 中实现 view 操作的具体代码:

public function actionView()
{
    $post=$this->loadModel();
    $this->render('view',array(
        'model'=>$post,
    ));
}
 
private $_model;
 
public function loadModel()
{
    if($this->_model===null)
    {
        if(isset($_GET['id']))
        {
            if(Yii::app()->user->isGuest)
                $condition='status='.Post::STATUS_PUBLISHED
                    .' OR status='.Post::STATUS_ARCHIVED;
            else
                $condition='';
            $this->_model=Post::model()->findByPk($_GET['id'], $condition);
        }
        if($this->_model===null)
            throw new CHttpException(404,'The requested page does not exist.');
    }
    return $this->_model;
}

我们的修改主要是在 loadModel() 方法上进行的。在这个方法中,我们通过 id GET参数查询了 Post 表。如果日志未找到或者没有发布,也未存档(当用户为游客(guest)时),我们将抛出一个 404 HTTP 错误。否则,日志对象将返回给 actionView()actionView() 又会把日志对象传递给视图脚本用于显示。

提示: Yii 会捕获 HTTP 异常 (CHttpException 的实例) 并通过预置的模板或自定义的错误视图显示出来。由 yiic 生成的程序骨架已经包含了一个自定义的错误视图 /wwwroot/blog/protected/views/site/error.php。如果想进一步自定义此错误显示,我们可以自己修改此文件。

view 脚本中的修改主要是关于调整日志显示格式和样式的。此处我们不再细讲,读者可以参考 /wwwroot/blog/protected/views/post/view.php.

2. 自定义 index 操作

view 操作类似,我们在两处自定义 index 操作:PostController 中的 actionIndex() 方法和视图文件 /wwwroot/blog/protected/views/post/index.php。我们主要需要添加对显示一个特定Tag下的日志列表的支持;

下面就是在 PostController 中对 `actionIndex() 方法作出的修改:

public function actionIndex()
{
    $criteria=new CDbCriteria(array(
        'condition'=>'status='.Post::STATUS_PUBLISHED,
        'order'=>'update_time DESC',
        'with'=>'commentCount',
    ));
    if(isset($_GET['tag']))
        $criteria->addSearchCondition('tags',$_GET['tag']);
 
    $dataProvider=new CActiveDataProvider('Post', array(
        'pagination'=>array(
            'pageSize'=>5,
        ),
        'criteria'=>$criteria,
    ));
 
    $this->render('index',array(
        'dataProvider'=>$dataProvider,
    ));
}

在上面的代码中,我们首先为检索日志列表创建了一个查询标准(criteria),此标准规定只返回已发布的日志,且应该按其更新时间倒序排列。因为我们打算在显示日志列表的同时显示日志收到的评论数量,因此在这个标准中我们还指定了要带回 commentCount, 如果你还记得,它就是在 Post::relations() 中定义的一个关系。

考虑到当用户想查看某个Tag下的日志列表时的情况,我们还要为指定的Tag添加一个搜索条件到上述标准中。

使用这个查询标准,我们创建了一个数据提供者(data provider)。这主要出于三个目的。第一,它会在查询结果过多时实现数据分页。这里我们定义分页的页面大小为5。 第二,它会按用户的请求对数据排序。最后,它会填充排序并分页后的数据到小部件(widgets)或视图代码用于显示。

完成 actionIndex() 后,我们将 index 视图修改为如下代码。 此修改主要是关于在用户指定显示Tag下的日志时添加一个 h1 标题。

<?php if(!empty($_GET['tag'])): ?>
<h1>Posts Tagged with <i><?php echo CHtml::encode($_GET['tag']); ?></i></h1>
<?php endif; ?>
 
<?php $this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$dataProvider,
    'itemView'=>'_view',
    'template'=>"{items}\n{pager}",
)); ?>

注意上面的代码,我们使用了 CListView 来显示日志列表。这个小物件需要一个局部视图以显示每一篇日志的详情。这里我们制定了局部视图为 _view,也就是文件 /wwwroot/blog/protected/views/post/_view.php. 在这个视图脚本中,我们可以通过一个名为 $data 的本地变量访问显示的日志实例。

$Id: post.display.txt 2121 2010-05-10 01:31:30Z qiang.xue $

Be the first person to leave a comment

Please to leave your comment.