本节中我们将开发第一个portlet——用户菜单portlet,对已经通过验证的登录用户显示一个菜单列表。包含以下四个菜单:
- 发布评论:到未发布评论列表的超链接
- 添加文章:到添加文章的超链接
- 管理文章:到文章管理页面的超链接
- 注销:注销当前用户的链接按钮
创建UserMenu类
我们创建UserMenu类来描绘用户菜单的逻辑部分。保存在blog/protected/components/UserMenu.php中,主要有以下内容
- <?php
- class UserMenu extends Portlet
- {
- public function init()
- {
- $this->title=CHtml::encode(Yii::app()->user->name);
- parent::init();
- }
- protected function renderContent()
- {
- $this->render('userMenu');
- }
- }
用户菜单的类UserMenu扩展自我们先前建立的Portlet类。重写了其中的init()和renderContent() 两个方法。前者用当前用户的名字设置了标题。后者通过输出一个userMenu的视图文件来完成portlet内容的展示。
建立用户菜单的视图
下一步,我们建立了用户菜单的视图文件,保存在blog/protected/components/views/userMenu.php文件中。
- <ul>
- <li><?php echo CHtml::link('Approve Comments', array('comment/list'))
- . ' (' . Comment::model()->pendingCommentCount . ')'; ?></li>
- <li><?php echo CHtml::link('Create New Post',array('post/create')); ?></li>
- <li><?php echo CHtml::link('Manage Posts',array('post/admin')); ?></li>
- <li><?php echo CHtml::linkButton('Logout',array(
- 'submit'=>'',
- 'params'=>array('command'=>'logout'),
- )); ?></li>
- </ul>
在视图文件中我们调用CHtml::link来建立需要的超链接。调用 CHtml::linkButton来产生一个链接按钮用户注销。当点击的时候,他会从当前页面提交一个form,包含变量submit和params
为了对注销做出响应,我们需要如下修改UserMenu的init()方法
- public function init()
- {
- if(isset($_POST['command']) && $_POST['command']==='logout')
- {
- Yii::app()->user->logout();
- $this->controller->redirect(Yii::app()->homeUrl);
- }
- $this->title=CHtml::encode(Yii::app()->user->name);
- parent::init();
- }
在init() 方法中,我们检查是否有一个名为command的POST变量,其值为值是logout。如果有则注销当前用户,跳转到应用的主页。注意跳转redirect()方法会终止当前程序的执行。
使用用户菜单模块
现在让我们是使用我们新做的用户菜单。我们如下修改显示文件blog/protected/views/layouts/main.php
- ......
- <div id="sidebar">
- <?php $this->widget('UserMenu',array('visible'=>!Yii::app()->user->isGuest)); ?>
- </div>
在上面的代码中,我们调用widget()方法来产生一个UserMenu实例并执行。因为仅对登陆的用户显示,所以我们用当前用户的isGuest属性来触发它的visible属性。
现在测试我们的应用
- 打开一个浏览器,输入网址,检查侧边栏是否没有内容显示。
- 点击登陆的链接登陆系统。成功后,检查侧边栏是不现实了菜单列表。并且用户名作为标题。
- 点击用户菜单的注销超链接。检查注销操作是否成功执行,侧边栏内容是否不在显示。
总结
我们建立了一个可重复使用性很高portlet。我们很容易的用它建立另一个应用而不要修改代码,或者只是很少的修改。而且portlet的设计符合把程序逻辑和页面视图想分离的原理。在上一节中我们并没有指出这一点。这样的实现在典型的Yii应用中随处可见