1、第十章:迭代 7:添加 RSS Web Feed在上次的迭代中,我们添加了用户对问题(issue)进行评论的功能及利用 portlet 结构轻松整合列表显示在应用程序中的任何位置。在本次迭代中,我们将利用这一点,实现一个 RSS 数据 feed 的评论列表。此外,我们将使用另一个开源框架 Zend Framework 中现有的可用的 feed 功能。以证明在 Yii 应用中整合第三方工具是多么的容易。迭代计划本次迭代的目标是使用用户生成的评论内容创建一个 RSS feed。我们应该允许用户订阅所有项目(project)及单独项目的评论 feed。幸运的是,我们之前使用挂件功能返回了所有项目最近
2、评论列表或限制为指定的一个项目的数据。所以,我们已经编写了适当的方法来访问所需的数据。这次迭代大部分精力将放在对这些数据以正确 RSS feed 格式进行发布,并添加链接允许订阅的用户访问我们的应用程序。为了实现这些目标,我们将需要完成以下更高级的任务列表: 下载并安装 Zend FrameWork 到 Yii 应用程序中。 在一个控制器类中创建一个新的操作,用来响应 feed 请求并返回 RSS 格式的数据。 改变易于使用的 URL 结构。 添加我们新创建的 feed 到两个项目(project) 的列表页和每个项目的详细页面与往常一样,在作出任何更改之前,一定要先运行单元测试套件来保证预期
3、的工作相符。关于 RSS 内容聚合及 Zend Framework 的背景Web 的内容聚合已经出现很多久了,但最近才比较流行。Web 内容聚合指的是一种发布信息的标准格式,通过这种格式其他网站的读取可以很容易地访问应用程序。许多新文网站一直以这种格式发布它们的内容,从互联网上网络日志(也称博客)提供内容聚合到几乎每一个网站都有这个功能。当然我们的 TrackStar 应用程序也不会例外。RSS 是一个缩写,全称 Readlly Simple Syndication。它是一种 XML 格式文件用来提供一个 Web 内容聚合的标准。还有其他的格式可以使用,但由于绝大多数的网站都使用 RSS,我们
4、将着重介绍这种格式。Zend 是一家”PHP 公司”。其创始人是 PHP 语言的核心贡献者,Zend 致力于创造新产品用来帮助开发人员改善 PHP 应用程序的整个开发生命周期。他们提供的产品和服务会帮助你配置和安装 PHP,以及应用程序的开发,部置,生产管理和维护。其中一款有助于应用程序开的产品是 Zend Framework。该框架可以作为一个整体来提供一个完整的应用程序,比如可以使用同样的方式开发 Trackstar 应用程序,或者使用单独的功能组件库。Yii 的灵活之处是让我们可以使用其他的框架组件。我们将使用 Zend Framework 中的一个组件,它是 Zend_Feed。使用它
5、可以让我们不用写任何低层的代码就能生成一个RSS 格式的 Web feed。关于更多的 Zend_Feed 信息,请访问 http:/ Zend 框架由于我们使用 Zend 框架的帮助完成我们的 RSS 需求,我们首先需要下载和安装它。要获取最新版本,请访问 http:/ Zend 框架的最小版本就中足够了。当你展开下载文件后,你应该看到以下文件及目录结构:SHELL 代码或屏幕回显:INSTALL.txt LICENSE.txt README.txt bin/ library/为了在 Yii 应用程序中使用这个框架,我们需要将一些文件移到我们的应用程序的目录结构中。让我们在 /protect
6、ed 目录下创建一个新的目录叫 vendors 。然后移动 Zend 框架目录下的/library/Zend 目录到新创建的目录下。移动完成了,确保在 TrackStar 应用程序中存在 protected/vendors/Zend/Feed.php 文件。使用 Zend_FeedZend_Feed 是 Zend 框架中的一个小组件,它封这装了创建 Web Feed 背后复杂的过程,提供了简单易于使用的接口,这将有助于我们在很短的时间就可以完成这项功能和测试 RSS 兼容数据。我们所需要做的是通过 Zend_Feed 来格式化我们的评论数据。我们需要一个地方放置我们需要处理的 feed 的请求
7、的位置。我们可以创建一个新的控制器,但是为了简便起见,我们只需要在 CommentController.php 文件中添加一个新的操作来处理请求。现在我们只为此方法添加一些功能,然后我们再讨论整个方法。打开 CommentController.php 文件,并添加如下公有方法:PHP 代码:public function actionFeed()if(isset($_GETpid) $projectId = intval($_GETpid);else $projectId = null;$comments = Comment:model()-findRecentComments(20, $pr
8、ojectId);/convert from an array of comment AR class instances to an name=value array for Zend$entries=array();foreach($comments as $comment)$entries=array(title=$comment-issue-name,link=CHtml:encode($this-createAbsoluteUrl(issue/view,array(id=$comment-issue-id),description= $comment-author-username
9、. says: . $comment-content,lastUpdate=strtotime($comment-create_time),author=$comment-author-username,);/now use the Zend Feed class to generate the Feed/ generate and render RSS feed$feed=Zend_Feed:importArray(array(title= Trackstar Project Comments Feed,link= $this-createUrl(),charset = UTF-8, ent
10、ries = $entries,), rss);$feed-send();这一切都非常简单。首先,我们检查输入请求的 pid 参数是否存在,这里我们所采取的是一个具体的项目ID。记住这里我们希望有选择地让数据的内容限制在一个指定的项目的相关评论。接下来,我们用findRecentComments 的方法获得 20 条最近评论列表,这里如果指定项目 ID,则是具体的项目的评论,否则是所有的项目的评论。你可能还记得,这个方法返回一个 Comment AR 类实例的数组。我们遍历这个数,通过 Zend_Feed组件来返回转换成所需格式的数据。Zend_Feed 期望的是简单的数组,其本身的每个元素是
11、一个包含评论实体的数组。每个实体是以一个简单的 name=value 对的关联数组。为了符合具体的 RSS 格式,我们的每个条目必须至少包含 一个 title(标题) ,link(链接) 和 description(描述)。我们还增加了两个可选的字段 ,一个名为 lastUpdate(最后更新),这是 Zend_Feed 转换为 RSS 格式的发布日期,另一个指定为 author(作者)。有一些额外的辅助方法,让我们可以获取正确的数据格式。首先,我们使用控制器的createAbsoluteUrl()方法,而不仅仅是 createUrl()方法,以创建一个完整的 URL,使用createAbso
12、luteUrl()将产生类似下面的链接:http:/localhost/trackstar/index.php?r=issue/view require_once(Zend/Feed.php); require_once(Zend/Feed/Rss.php);然后,修改 CommentController:accessRules()方法,允许任何用户访问我们新增方法 actionFeed():PHP 代码:public function accessRules()return array(array(allow, / allow all users to perform index and v
13、iew actionsactions=array(index,view, feed),users=array(*),),这就是全部内容。如果我们访问 http:/localhost/trackstar/index.php?r=comment/feed,我们能看到我们努力的结果。不同的浏览器将显示不同的 RSS 结果,你所看到的可能与截图不同。下面的截图是使用 Firefox 浏览器查看 RSS 的结果。创建友好的 URL到目前为止,整个开发过程中,我们使用了 yii 应用程序默认格式的 URL 结构,在第 2 章,我们讨论了这种格式,它采用了查询参数的方式。主要参数r代表路由,是由 contr
14、ollerID/actionID 对组成,其次是 action 方法所需要的一些可选的查询参数。我们新创建的 feed 操作也不例外,但这是一个很长,繁琐且不友好的 URL 结构。有更好的方法吗?嗯,事实上是有的。使用路径格式,我们可以让上面的 URL 看起来更清晰,更明了。消除 URL 中的查询参数字符串,把查询参数放到路径信息中:以我们的评论 feed URL 为例,替换:http:/localhost/trackstar/index.php?r=comment/feed为我们需要的:http:/localhost/trackstar/index.php/comment/feed/更多情况
15、,我们甚至不需要指定入口文件。我们也可以利用 Yii 的路由配置选项删除指定的controllerID/actionID 对。我们的要求将像这样:http:/localhost/trackstar/commentfeed还有,普遍的 feed URL 最后都有一个.xml 扩展名。所以,如果我们可以改成下面的这样那就更好了:http:/localhost/trackstar/commentfeed.xml这样将大大简化了 URL 地址,并且也符合各大搜索引擎的收录格式(通常被称为“ 友好的搜索引擎 URL”)。让我们看看如何使用 Yii 的 URL 管理功能,改变我们的 URL 以符合我们需要
16、的格式。使用 URL 管理器在 Yii 中内置的 URL 管理器是一个应用程序组件,它可以在 protected/config/main.php 文件中配置。让我们打开这个文件,并在组件数组中添加一个新的 URL 管理器组件的声明:PHP 代码:urlManager=array( urlFormat=path,),只要我们使用默认的名字 urlManager,我们不需要指定组件的类名,因为它已经在CWebApplication.php 框架类中预定义为 CUrlManager.php。通过简单的添加配置,整个站点的 URL 结构变成了path格式。例如,以前如果我们想查看一个具体的ID 为 1
17、 的 issue,我们会使用下面的 URL:http:/localhost/trackstar/index.php?r=issue/view它将生成的 URL 仍然包括 index.php: http:/localhost/trackstar/index.php/commentfeed.xml当生成 URL 时为了不使用入口文件,我们需要设置 urlManager 组件的属性。我们再才修改 main.php配置文件,例如:PHP 代码:urlManager=array( urlFormat=path, rules=array(commentfeed=array(site/commentFeed
18、, urlSuffix=.xml, caseSensitive=false),),showScriptName=false,),在 URL 中为了处理指定 project ID 的评论 feed,我们需要添加另外一个规则:PHP 代码:urlManager=array( urlFormat=path,rules=array(/commentfeed=array(site/ commentFeed, urlSuffix=.xml, caseSensitive=false),commentfeed=array(site/commentFeed, urlSuffix=.xml, caseSensit
19、ive=false),), showScriptName=false,),这条规则同样也使用了语法指定模式,URL 的 commentfeed.xml 部分之前指定了一个 project ID。通过这条规则,我们可以限制评论的 feed 指定到一个具体的 project。例如,如果我们只想要 project #2的评论的 feed,URL 格式是:http:/localhost/trackstar/2/commentfeed.xml添加 feed 链接现在我们已经创建了更加友好的 feed 的 URL 结构。我们需要添加用户可订阅 feed 的功能。一种方法是增加以下代码,在页面渲染前添加 R
20、SS feed 链接。让我们对项目列表页和具体的项目详细页进行修改。我们首先开始制作项目列表页。这个页面的操作方法是 ProjectController:actionIndex(),修改此方法为如下代码:PHP 代码:public function actionIndex() $dataProvider=new CActiveDataProvider(Project);Yii:app()-clientScript-registerLinkTag( /这行alternate, /这行application/rss+xml, /这行$this-createUrl(comment/feed); /这
21、行$this-render(index,array( dataProvider=$dataProvider,);上述高亮代码将在再部份渲染以下 HTML:PHP 代码:在许多的浏览器中,地址栏上将自动生成一个 RSS feed 小图标。下面的截图描绘了这个图标像在Firefox3.6 地址栏中的外观:我们将类似的修改添加到具体的项目详细页,这个页面的操作方法是 ProjectController:actionView(),修改此方法为如下代码:PHP 代码:public function actionView() $issueDataProvider=new CActiveDataProvid
22、er(Issue, array(criteria=array(condition=project_id=:projectId, params=array(:projectId=$this-loadModel()-id), ),pagination=array( pageSize=1,),);Yii:app()-clientScript-registerLinkTag( alternate,application/rss+xml,$this-createUrl(comment/feed,array(pid=$this-loadModel()-id);$this-render(view,array
23、( model=$this-loadModel(), issueDataProvider=$issueDataProvider,);除了指定 project ID,几乎与添加到 index 方法中的代码一样。这将使评论的 feed 仅限制在指定项目。现在我们在项目详细页面的地址栏中也显示了 feed 订阅图标,点击图标将允许用户订阅这些评论。小结本次迭代证明在 Yii 框架中融入其他外部框架是多么的容易。我们特地使用了流行的 Zend Fraemwork快速添加网站的 RSS feed 符合我们的应用程序的要求来证明这一点。虽然我们仅指定使用了Zend_Feed,但我们真正展示了是如何将 Zend Framework 的任何组件融入到我们的应用程序中。这进一步扩大了 Yii 的功能,使 Yii 应用程序实现更丰富的功能。我们也了解了使用 Yii 中的 URL 管理功能来改变整个应用程序的 URL 为更加友好的格式。这是提升应用程序外观和感觉的第一步。我们有太多的东西被忽视。在下一次迭代中,我们将重点转向风格,主题。