Creating NewPost Page

The NewPost page is provided to authenticated users for creating new blog posts. It needs to display a form that collects the information about the new post, including the post title and the post body content.

Because NewPost can only be accessed by authenticated users, we add a page configuration file config.xml under the directory protected/pages/posts. The configuration specifies that authenticated users can access NewPost and EditPost which is to be introduced in the next section. All other users only have access to ListPost and ReadPost.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <authorization>
    <allow pages="NewPost,EditPost" users="@" />
    <allow pages="ListPost,ReadPost" />
    <deny users="*" />
  </authorization>
</configuration>
Tip: It's always a good idea to start with a deny="*" catch all rule at the bottom and then step by step grant access to pages with additional rules.

As the number of our pages expands, we would like to modify MainLayout so that in the footer of our blog pages there are links to various pages, including the homepage, the NewUser page (visible to the administrator only), and the upcoming NewPost page (visible to authenticated users only).

<div id="footer">
<com:THyperLink Text="Home"
	NavigateUrl="<%= $this->Service->DefaultPageUrl %>" />

<com:THyperLink Text="New Post"
	NavigateUrl="<%= $this->Service->constructUrl('posts.NewPost') %>"
	Visible="<%= !$this->User->IsGuest %>" />

<com:THyperLink Text="New User"
	NavigateUrl="<%= $this->Service->constructUrl('users.NewUser') %>"
	Visible="<%= $this->User->IsAdmin %>" />
...other links...
</div>

We now create two files protected/pages/posts/NewPost.page and protected/pages/posts/NewPost.php to save the page template and page class, respectively.

Creating Page Template

The NewPost page template contains a TTextBox to collect the post title and a THtmlArea to collect the post content. The latter is a WYSIWYG HTML editor. To ensure the user input is valid, we associate validators with these input controls.

<%@ Title="My Blog - New Post" %>

<com:TContent ID="Main">

<h1>Create New Post</h1>

<span>Title:</span>
<com:TRequiredFieldValidator
	ControlToValidate="TitleEdit"
	ErrorMessage="Please provide a title."
	Display="Dynamic" />
<br/>
<com:TTextBox ID="TitleEdit" Columns="50" />

<br/>
<span>Content:</span>
<com:TRequiredFieldValidator
	ControlToValidate="ContentEdit"
	ErrorMessage="Please provide content."
	Display="Dynamic" />
<br/>
<com:THtmlArea ID="ContentEdit" />

<br/>
<com:TButton Text="Create" OnClick="createButtonClicked" />

</com:TContent>

Creating Page Class

From the above page template, we see that we mainly need to write a page class that implements the event handler: createButtonClicked() (attached to the Create button's OnClick event).

class NewPost extends TPage
{
	/**
	 * Creates a new post if all inputs are valid.
	 * This method responds to the OnClick event of the "create" button.
	 * @param mixed event sender
	 * @param mixed event parameter
	 */
	public function createButtonClicked($sender,$param)
	{
		if($this->IsValid)  // when all validations succeed
		{
			// populates a PostRecord object with user inputs
			$postRecord=new PostRecord;
			// using SafeText instead of Text avoids Cross Site Scripting attack
			$postRecord->title=$this->TitleEdit->SafeText;
			$postRecord->content=$this->ContentEdit->SafeText;
			$postRecord->author_id=$this->User->Name;
			$postRecord->create_time=time();
			$postRecord->status=0;

			// saves to the database via Active Record mechanism
			$postRecord->save();

			// redirects the browser to the newly created post page
			$url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id));
			$this->Response->redirect($url);
		}
	}
}

Testing

To test the NewPost page, login first and click on the New Post link button in the footer of the homepage. Our browser will display the following result with the URL http://hostname/blog/index.php?page=NewPost.

Info: When you visit the NewPost page for the first time, you may notice that it takes several seconds for the page to be displayed. This is because PRADO needs to unpack and publish the javascript code and images for the THtmlArea control used in the page. This is done once and for all.
Tip: To test the pagination feature that we developed for the ListPost page, we can create five or more posts and see what happens to the homepage. The pager in ListPost displays five posts each page.