Also available in these languages:
English日本語polskiРусский简体中文

Displaying Posts

In our blog application, a post may be displayed among a list of posts or by itself. The former is implemented as the index operation while the latter the view operation. In this section, we customize both operations to fulfill our initial requirements.

Customizing view Operation

The view operation is implemented by the actionView() method in PostController. Its display is generated by the view view with the view file /wwwroot/blog/protected/views/post/view.php.

Below is the relevant code implementing the view operation in PostController:

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;
}

Our change mainly lies in the loadModel() method. In this method, we query the Post table according to the id GET parameter. If the post is not found or if it is not published or archived (when the user is a guest), we will throw a 404 HTTP error. Otherwise the post object is returned to actionView() which in turn passes the post object to the view script for further display.

Tip: Yii captures HTTP exceptions (instances of CHttpException) and displays them in either predefined templates or customized error views. The skeleton application generated by yiic already contains a customized error view in /wwwroot/blog/protected/views/site/error.php. We can modify this file if we want to further customize the error display.

The change in the view script is mainly about ajdusting the formatting and styles of the post display. We will not go into details here. Interested readers may refer to /wwwroot/blog/protected/views/post/view.php.

Customizing index Operation

Like the view operation, we customize the index operation in two places: the actionIndex() method in PostController and the view file /wwwroot/blog/protected/views/post/index.php. We mainly need to add the support for displaying a list of posts that are associated with a specified tag.

Below is the modified actionIndex() method in PostController:

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,
    ));
}

In the above, we first create a query criteria for retrieving post list. The criteria states that only published posts should be returned and they should be sorted according to their update time in descending order. Because when displaying a post in the list, we want to show how many comments the post has received, in the criteria we also specify to bring back commentCount, which if you remember, is a relation declared in Post::relations().

In case when a user wants to see posts with a specific tag, we would add a search condition to the criteria to look for the specified tag.

Using the query criteria, we create a data provider, which mainly serves for three purposes. First, it does pagination of the data when too many results may be returned. Here we customize the pagination by setting the page size to be 5. Second, it does sorting according to the user request. And finally, it feeds the paginated and sorted data to widgets or view code for presentation.

After we finish with actionIndex(), we modify the index view as follows. Our change is mainly about adding the h1 header when the user specifies to display posts with a tag.

<?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}",
)); ?>

Note that in the above, we use CListView to display the post list. This widget requires a partial view to display the detail of each individual post. Here we specify the partial view to be _view, which means the file /wwwroot/blog/protected/views/post/_view.php. In this view script, we can acccess the post instance being displayed via a local variable named $data.

$Id: post.display.txt 2121 2010-05-10 01:31:30Z qiang.xue $
If you find any typos or errors in the tutorial, please create a Yii ticket to report it. If it is a translation error, please create a Yiidoc ticket, instead. Thank you.

Total 9 comments:

#122
actionList and pagination
by OriginalCopy at 3:52pm on March 18, 2009.

To add pagination to actionList(), you need to set pageSize:

$pages=new CPagination($postCount);
$pages->pageSize = self::PAGE_SIZE;
$pages->applyLimit($criteria);

#158
modifying the view
by thomas.mery at 3:32am on March 31, 2009.

Hi,

should this tutorial mention that we actually need to modify the post/list view to accommodate for the change in the list of post variable from $postList to $posts?

thank you

thomas

#190
sort column
by dennys at 4:53pm on April 11, 2009.

The order is a partial SQL command (i.e. order='createTime DESC'). Could I order by the relation table?

For example, SELECT * FROM post p, user u WHERE p.authorId = u.id ORDER BY u.username

#367
PLEASE FIX THIS!
by alexweber at 6:34am on June 9, 2009.

there are 2 fixes posted here by OriginalCopy and thomas.mery and not implementing them actually breaks the application.

thanks,

Alex

#542
Changing CSS
by williamgwapo at 8:44am on August 4, 2009.

Hi how can i change the CSS of the form. Is it changeable or not? Because the the blog in the tutorial is not the same like the blog in the demo.

#574
Changing CSS
by sebi at 8:16pm on August 12, 2009.

Css should not be a part of the tutorial, if you want to change the Css of your blog application and change the .css files in www/docroot/blog/css

#1045
I get this Error:
by as_lh at 1:43am on January 25, 2010.

include(CActiveDataProvider.php) function.include: failed to open stream: No such file or directory

#0 /.../yii/framework/YiiBase.php(338): autoload() #1 unknown(0): autoload() #2 /.../yiitest/protected/controllers/SiteController.php(41): spl_autoload_call() #3 /.../yii/framework/web/actions/CInlineAction.php(32): PostController->actionUser() #4 /.../yii/framework/web/CController.php(300): CInlineAction->run() #5 /.../yii/framework/web/CController.php(278): SiteController->runAction() #6 /.../yii/framework/web/CController.php(257): SiteController->runActionWithFilters() #7 /.../yii/framework/web/CWebApplication.php(310): SiteController->run() #8 /.../yii/framework/web/CWebApplication.php(120): CWebApplication->runController() #9 /.../yii/framework/base/CApplication.php(135): CWebApplication->processRequest() #10 /.../yiitest/index.php(11): CWebApplication->run()

#1163
think...think...think...lol
by webscriptz at 2:46pm on February 24, 2010.

CActiveDataProvider seems rather complicated, i don't know but i think i'll stick with the old fashion way to display data, the kind i'm used to, still CI.

it's a bit overwhelming and a bit too obscure.

#1350
Parameters
by Incubusaurus at 4:47am on April 5, 2010.

In the Customizing index Operation section, the application parameter postsPerPage is referenced.

For this to work, the following file needs to be created:

/wwwroot/yii/demos/blog/protected/config/params.php

A copy of this file can be found in the blog demo sample code.

The main web application configuration file then needs updating, so that it loads its parameters from params.php:

/wwwroot/yii/demos/blog/protected/config/main.php

Change this:

'params'=>array(
    // this is used in contact page
    'adminEmail'=>'webmaster@example.com',
),

To this:

'params'=>require(dirname(__FILE__).'/params.php'),

Your Comment:

You may enter comment using Markdown syntax.

Please login with your forum account.
Note: you must have at least ONE forum post with your account.