| 1 |
lars |
1 |
<com:TContent ID="Main">
|
|
|
2 |
|
|
|
3 |
<h1>Creating <tt>ListPost</tt> Page</h1>
|
|
|
4 |
|
|
|
5 |
<p>
|
|
|
6 |
The <tt>ListPost</tt> page shows the latest blog posts in a list. If there are too many posts, they will be displayed in several pages.
|
|
|
7 |
</p>
|
|
|
8 |
|
|
|
9 |
<p>
|
|
|
10 |
Before we proceed with the implementation, we would like to point our homepage to the upcoming <tt>ListPage</tt> page, because we want the users to see latest posts when they hit the website. To do so, we modify the application configuration <tt>protected/application.xml</tt> as follows,
|
|
|
11 |
</p>
|
|
|
12 |
|
|
|
13 |
<com:TTextHighlighter CssClass="source" Language="xml">
|
|
|
14 |
......
|
|
|
15 |
<services>
|
|
|
16 |
<service id="page" class="TPageService" DefaultPage="posts.ListPost">
|
|
|
17 |
<pages MasterClass="Application.layouts.MainLayout" />
|
|
|
18 |
</service>
|
|
|
19 |
</services>
|
|
|
20 |
</com:TTextHighlighter>
|
|
|
21 |
|
|
|
22 |
<p>
|
|
|
23 |
We now create the template and class files for the <tt>ListPost</tt> page: <tt>protected/pages/posts/ListPost.page</tt> and <tt>protected/pages/posts/ListPost.php</tt>.
|
|
|
24 |
</p>
|
|
|
25 |
|
|
|
26 |
<h2>Creating Page Template</h2>
|
|
|
27 |
<p>
|
|
|
28 |
Based on the functionality requirement of the <tt>ListPost</tt> page, we will use two controls in the page template:
|
|
|
29 |
</p>
|
|
|
30 |
<ul>
|
|
|
31 |
<li><a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Repeater">TRepeater</a>: this control is mainly used to display a list of data items. The presentation of the each data item can be specified via an inline template or an external template control (the approach we will use here).</li>
|
|
|
32 |
<li><a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Pager">TPager</a>: this control is used to paginate a list of data items. It interacts with end-users to determine which page of data to be displayed in a <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.List">list control</a> (e.g. <tt>TListBox</tt>) or <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Data">data control</a> (e.g. <tt>TRepeater</tt>).</li>
|
|
|
33 |
</ul>
|
|
|
34 |
|
|
|
35 |
<p>
|
|
|
36 |
Below is the content in the page template:
|
|
|
37 |
</p>
|
|
|
38 |
|
|
|
39 |
<com:TTextHighlighter CssClass="source" Language="prado">
|
|
|
40 |
<%@ Title="My Blog" %>
|
|
|
41 |
|
|
|
42 |
<com:TContent ID="Main">
|
|
|
43 |
|
|
|
44 |
<com:TRepeater ID="Repeater"
|
|
|
45 |
ItemRenderer="Application.pages.posts.PostRenderer"
|
|
|
46 |
AllowPaging="true"
|
|
|
47 |
AllowCustomPaging="true"
|
|
|
48 |
PageSize="5"
|
|
|
49 |
/>
|
|
|
50 |
|
|
|
51 |
<com:TPager ControlToPaginate="Repeater" OnPageIndexChanged="pageChanged" />
|
|
|
52 |
|
|
|
53 |
</com:TContent>
|
|
|
54 |
</com:TTextHighlighter>
|
|
|
55 |
|
|
|
56 |
<p>
|
|
|
57 |
In the repeater, we specify that the repeated content is to be displayed using the item renderer <tt>PostRenderer</tt> which we will create soon after. In order for PRADO to find this class, we give the complete namespace path <tt>Application.pages.posts.PostRenderer</tt>, meaning the class file is <tt>protected/pages/posts/PostRenderer.php</tt>.
|
|
|
58 |
</p>
|
|
|
59 |
|
|
|
60 |
<p>
|
|
|
61 |
We also set a few other properties of repeater to enable paging. And we set <tt>ControlToPaginate</tt> property of the pager so that it knows whose repeated content should be paginated.
|
|
|
62 |
</p>
|
|
|
63 |
|
|
|
64 |
|
|
|
65 |
<h2>Creating Page Class</h2>
|
|
|
66 |
|
|
|
67 |
<p>
|
|
|
68 |
From the above page template, we see that we need to write a page class that implements the event handler: <tt>pageChanged()</tt> (attached to the pager's <tt>OnPageIndexChanged</tt> event). We also need to populate post data into the repeater according to the current paging setting. The following is the complete source code of the page class:
|
|
|
69 |
</p>
|
|
|
70 |
|
|
|
71 |
<com:TTextHighlighter CssClass="source" Language="php">
|
|
|
72 |
class ListPost extends TPage
|
|
|
73 |
{
|
|
|
74 |
/**
|
|
|
75 |
* Initializes the repeater.
|
|
|
76 |
* This method is invoked by the framework when initializing the page
|
|
|
77 |
* @param mixed event parameter
|
|
|
78 |
*/
|
|
|
79 |
public function onInit($param)
|
|
|
80 |
{
|
|
|
81 |
parent::onInit($param);
|
|
|
82 |
if(!$this->IsPostBack) // if the page is requested the first time
|
|
|
83 |
{
|
|
|
84 |
// get the total number of posts available
|
|
|
85 |
$this->Repeater->VirtualItemCount=PostRecord::finder()->count();
|
|
|
86 |
// populates post data into the repeater
|
|
|
87 |
$this->populateData();
|
|
|
88 |
}
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
/**
|
|
|
92 |
* Event handler to the OnPageIndexChanged event of the pager.
|
|
|
93 |
* This method is invoked when the user clicks on a page button
|
|
|
94 |
* and thus changes the page of posts to display.
|
|
|
95 |
*/
|
|
|
96 |
public function pageChanged($sender,$param)
|
|
|
97 |
{
|
|
|
98 |
// change the current page index to the new one
|
|
|
99 |
$this->Repeater->CurrentPageIndex=$param->NewPageIndex;
|
|
|
100 |
// re-populate data into the repeater
|
|
|
101 |
$this->populateData();
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
/**
|
|
|
105 |
* Determines which page of posts to be displayed and
|
|
|
106 |
* populates the repeater with the fetched data.
|
|
|
107 |
*/
|
|
|
108 |
protected function populateData()
|
|
|
109 |
{
|
|
|
110 |
$offset=$this->Repeater->CurrentPageIndex*$this->Repeater->PageSize;
|
|
|
111 |
$limit=$this->Repeater->PageSize;
|
|
|
112 |
if($offset+$limit>$this->Repeater->VirtualItemCount)
|
|
|
113 |
$limit=$this->Repeater->VirtualItemCount-$offset;
|
|
|
114 |
$this->Repeater->DataSource=$this->getPosts($offset,$limit);
|
|
|
115 |
$this->Repeater->dataBind();
|
|
|
116 |
}
|
|
|
117 |
|
|
|
118 |
/**
|
|
|
119 |
* Fetches posts from database with offset and limit.
|
|
|
120 |
*/
|
|
|
121 |
protected function getPosts($offset, $limit)
|
|
|
122 |
{
|
|
|
123 |
// Construts a query criteria
|
|
|
124 |
$criteria=new TActiveRecordCriteria;
|
|
|
125 |
$criteria->OrdersBy['create_time']='desc';
|
|
|
126 |
$criteria->Limit=$limit;
|
|
|
127 |
$criteria->Offset=$offset;
|
|
|
128 |
// query for the posts with the above criteria and with author information
|
|
|
129 |
return PostRecord::finder()->withAuthor()->findAll($criteria);
|
|
|
130 |
}
|
|
|
131 |
}
|
|
|
132 |
</com:TTextHighlighter>
|
|
|
133 |
|
|
|
134 |
<h2>Creating <tt>PostRenderer</tt></h2>
|
|
|
135 |
|
|
|
136 |
<p>
|
|
|
137 |
We still need to create the item renderer class <tt>PostRenderer</tt>. It defines how each post should be displayed in the repeater. We create it as a template control which allows to specify the post presentation using our flexible template syntax. The template and the class files are saved as <tt>PostRenderer.tpl</tt> and <tt>PostRenderer.php</tt> files under the <tt>protected/pages/posts</tt> directory, respectively.
|
|
|
138 |
</p>
|
|
|
139 |
|
|
|
140 |
<h3>Creating Renderer Template</h3>
|
|
|
141 |
<p>
|
|
|
142 |
The renderer template specifies the presentation of various fields in a post, including title, author name, post time and content. We link the post title to the <tt>ReadPost</tt> which shows more details of the selected post.
|
|
|
143 |
</p>
|
|
|
144 |
<p>
|
|
|
145 |
The expression <tt>$this->Data</tt> refers to the data item passed to the repeater. In our case, it is a <tt>PostRecord</tt> object. Notice how we retrieve the author name of a post by <tt>$this->Data->author->username</tt>.
|
|
|
146 |
</p>
|
|
|
147 |
|
|
|
148 |
<com:TTextHighlighter CssClass="source" Language="prado">
|
|
|
149 |
<div class="post-box">
|
|
|
150 |
<h3>
|
|
|
151 |
<com:THyperLink Text="<%# $this->Data->title %>"
|
|
|
152 |
NavigateUrl="<%# $this->Service->constructUrl('posts.ReadPost',array('id'=>$this->Data->post_id)) %>" />
|
|
|
153 |
</h3>
|
|
|
154 |
|
|
|
155 |
<p>
|
|
|
156 |
Author:
|
|
|
157 |
<com:TLiteral Text="<%# $this->Data->author->username %>" /><br/>
|
|
|
158 |
Time:
|
|
|
159 |
<com:TLiteral Text="<%# date('m/d/Y h:m:sa', $this->Data->create_time) %>" />
|
|
|
160 |
</p>
|
|
|
161 |
|
|
|
162 |
<p>
|
|
|
163 |
<com:TLiteral Text="<%# $this->Data->content %>" />
|
|
|
164 |
</p>
|
|
|
165 |
</div>
|
|
|
166 |
</com:TTextHighlighter>
|
|
|
167 |
|
|
|
168 |
<h3>Creating Renderer Class</h3>
|
|
|
169 |
<p>
|
|
|
170 |
The renderer class is very simple. It extends from <tt>TRepeaterItemRenderer</tt> and contains no other code.
|
|
|
171 |
</p>
|
|
|
172 |
<com:TTextHighlighter CssClass="source" Language="php">
|
|
|
173 |
class PostRenderer extends TRepeaterItemRenderer
|
|
|
174 |
{
|
|
|
175 |
}
|
|
|
176 |
</com:TTextHighlighter>
|
|
|
177 |
|
|
|
178 |
<h2>Testing</h2>
|
|
|
179 |
<p>
|
|
|
180 |
To test the <tt>ListPost</tt> page, visit the URL <tt>http://hostname/blog/index.php</tt> (remember we have set <tt>ListPost</tt> as our new homepage). We shall expect to see the following result. Since we only have one post at the moment, the pager will not show up. Later when we finish <tt>NewPost</tt>, we can add more posts and come back to test the paging again.
|
|
|
181 |
</p>
|
|
|
182 |
|
|
|
183 |
<img src="<%~ output.gif %>" class="output" />
|
|
|
184 |
|
|
|
185 |
</com:TContent>
|