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.
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
.
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.
if(!empty($_GET['tag'])): <h1>Posts Tagged with <i> echo CHtml::encode($_GET['tag']); </i></h1> endif; $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
.
Found a typo or you think this page needs improvement?
Edit it on github !
Parameters
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'),
actionList and pagination
To add pagination to actionList(), you need to set pageSize:
$pages=new CPagination($postCount); $pages->pageSize = self::PAGE_SIZE; $pages->applyLimit($criteria);
Don't just copy the view.php from the demo
Although they say that the changes in views/Post/view.php have mainly to do with formatting and styles, you can't just copy the view.php over to your install: they reference _comment which you haven't built yet.
For the _comments view, look here...
Signup or Login in order to comment.