Creating ReadPost Page
The ReadPost page shows the detailed content of a blog post. For authorized users, it also shows link buttons that would allow them to edit or delete the post.
We create two files protected/pages/posts/ReadPost.page and protected/pages/posts/ReadPost.php to save the page template and page class, respectively.
Creating Page Template
The ReadPost page template is very similar to the PostRenderer template, both presenting the content of a post. The difference is that ReadPost needs to display two link buttons when the current user is authorized to edit or delete the post.
<com:TLiteral Text="<%= $this->Post->title %>" />
<com:TControl Visible="<%= $this->canEdit() %>">
<a href="<%= $this->Service->constructUrl('posts.EditPost',array('id'=>$this->Post->post_id))%>">Edit</a> |
<com:TLiteral Text="<%= $this->Post->author->username %>" /><br/>
<com:TLiteral Text="<%= date('m/d/Y h:m:sa', $this->Post->create_time) %>" />
<com:TLiteral Text="<%= $this->Post->content %>" />
Many PHP expressions are used in the above template. The expression $this->Post refers to a property defined in the ReadPost page class. It represents the PostRecord object corresponding to the post currently being viewed.
Although we use expressions widely in templates, we do not overuse them. A major guideline in determining whether we should use an expression in a template is that the expression should be a property or a simple presentational transformation of the property. By following this guideline, we ensure content and presentation are well separated without losing sufficient flexibility.
All PRADO controls have a very useful property named Attributes which can accept arbitrary name-value pairs. Most PRADO controls will render the name-value pairs in Attributes literally in the corresponding HTML tag. For example, in the Delete link button above, we define an onclick which is rendered as the onclick attribute in the resulting <a> tag.
Creating Page Class
From the above page template, we see that we need to write a page class that implements the event handler: deletePost() (attached to the Delete button's OnClick event). We also need to retrieve the post data specified by the post ID passed via the id GET parameter.
class ReadPost extends TPage
* Fetches the post data.
* This method is invoked by the framework when initializing the page
* @param mixed event parameter
public function onInit($param)
// post id is passed via the 'id' GET parameter
// retrieves PostRecord with author information filled in
if($this->_post===null) // if post id is invalid
throw new THttpException(500,'Unable to find the specified post.');
// set the page title as the post title
* @return PostRecord the PostRecord currently being viewed
public function getPost()
* Deletes the post currently being viewed
* This method is invoked when the user clicks on the "Delete" button
public function deletePost($sender,$param)
// only the author or the administrator can delete a post
throw new THttpException('You are not allowed to perform this action.');
// delete it from DB
// redirect the browser to the homepage
* @return boolean whether the current user can edit/delete the post being viewed
public function canEdit()
// only the author or the administrator can edit/delete a post
return $this->User->Name===$this->Post->author_id || $this->User->IsAdmin;
To test the ReadPost page, visit the URL http://hostname/blog/index.php and click on the title of the only post. Our browser will display the following result with the URL http://hostname/blog/index.php?page=ReadPost&id=1. Note, if we do not login, the two link buttons will be invisible.