根据需求分析,我们需要三个不同的 Portlet:“用户菜单” Portlet、“标签云” Portlet 和“最新评论” Portlet。我们将通过扩展 Yii 提供的 CPortlet 小部件来开发这些 Portlet。
在本节中,我们将开发我们的第一个具体 Portlet - 用户菜单 Portlet,它显示一个仅供已验证用户使用的菜单项列表。菜单包含四个项目
UserMenu
类 ¶我们创建 UserMenu
类来表示用户菜单 Portlet 的逻辑部分。该类保存在文件 /wwwroot/blog/protected/components/UserMenu.php
中,其内容如下
Yii::import('zii.widgets.CPortlet');
class UserMenu extends CPortlet
{
public function init()
{
$this->title=CHtml::encode(Yii::app()->user->name);
parent::init();
}
protected function renderContent()
{
$this->render('userMenu');
}
}
UserMenu
类继承自 zii
库中的 CPortlet
类。它重写了 CPortlet
的 init()
方法和 renderContent()
方法。前者将 Portlet 标题设置为当前用户的名称;后者通过渲染名为 userMenu
的视图来生成 Portlet 的主体内容。
提示:请注意,我们必须在第一次引用它之前通过调用
Yii::import()
来显式包含CPortlet
类。这是因为CPortlet
是zii
项目的一部分 - Yii 的官方扩展库。出于性能考虑,该项目中的类不会被列为核心类。因此,我们必须在第一次使用它之前导入它。
userMenu
视图 ¶接下来,我们创建 userMenu
视图,该视图保存在文件 /wwwroot/blog/protected/components/views/userMenu.php
中
<ul> <li> echo CHtml::link('Create New Post',array('post/create')); </li> <li> echo CHtml::link('Manage Posts',array('post/admin')); </li> <li> echo CHtml::link('Approve Comments',array('comment/index')) . ' (' . Comment::model()->pendingCommentCount . ')'; </li> <li> echo CHtml::link('Logout',array('site/logout')); </li> </ul>
信息:默认情况下,小部件的视图文件应放置在包含小部件类文件的目录的
views
子目录下。文件名必须与视图名称相同。
UserMenu
Portlet ¶现在是时候使用我们新完成的 UserMenu
Portlet 了。我们将布局视图文件 /wwwroot/blog/protected/views/layouts/column2.php
修改如下
...... <div id="sidebar"> if(!Yii::app()->user->isGuest) $this->widget('UserMenu'); </div> ......
在上面,我们调用 widget()
方法来生成和执行 UserMenu
类的实例。由于 Portlet 应该只显示给已验证用户,因此我们仅在当前用户的 isGuest
属性为 false(表示用户已验证)时调用 widget()
。
UserMenu
Portlet ¶让我们测试一下我们到目前为止所做的事情。
http://www.example.com/blog/index.php
。验证页面侧边栏部分中是否没有任何内容显示。登录
超链接并填写登录表单以登录。如果成功,请验证 UserMenu
Portlet 是否出现在侧边栏中,以及 Portlet 的标题是否为用户名。UserMenu
Portlet 中的“注销”超链接。验证注销操作是否成功以及 UserMenu
Portlet 是否消失。我们创建的是一个高度可重用的 Portlet。我们可以轻松地在其他项目中重复使用它,几乎不需要任何修改。此外,此 Portlet 的设计严格遵循逻辑和表示应分离的理念。虽然我们之前没有提到这一点,但这种做法在典型的 Yii 应用程序中几乎无处不在。
发现拼写错误或您认为此页面需要改进?
在 GitHub 上编辑它 !
什么是 pendingCommentCount?
您需要在 Comment 模型中添加一个额外的函数才能使 Portlet 工作。
pendingCommentCount,更好的方法
关于 Chris83 实现的方法
这是实现 getPendingCommentCount() 方法的更好的方法
public function getPendingCommentCount() { return $this->count('status=:status', array(':status'=>self::STATUS_PENDING)); }
该方法位于 Comment 模型中,因此我们应该使用 $this 而不是 Comment::,我们还应该使用定义的常量来标识评论状态。
使用 CDbCriteria 来实现计数是过度的,而且没有必要,可能会浪费 CPU 周期。
如果您想让代码尽可能简洁而不晦涩,这里有一个更简洁、更短的方法
public function getPendingCommentCount() { return $this->count('status='.self::STATUS_PENDING); }
将 getPendingCommentCount() 放置在哪里?
所描述的 getPendingCommentCount() 方法需要在 Comment 模型文件中。它位于 /protected/models/comment.php 下。
请 注册 或 登录 才能评论。