
- 基于GPT和ZFS的FreeBSD安装 | ...
- 搭建基于VIM的Python IDE | ...
- python的logging库 | ...
- [小工具]生辰八字计算online(Ver.4) | ...
- 带OAuth的twip安装手记 | ...

今天进入狗屎皮重构的第四天。有件事要纪念一下:从今天晚间开始,我的虚拟主机上站点:BSpMq.com以及rsywx.net无法正常访问,必须翻墙。我实在不能明白的是,这样一个纯粹是打P扯谈的站点,一个以藏书、温和时事评论的站点怎么会被封?GFW真的是不可理喻了!
进入妓术专题。
今天进入狗屎皮重构的第四天。我主要解决了分页的问题。
Symfony进行分页也非常简单,因为它内置了sfPagination这个类,我们只要传递一些参数,并在模板中加入一些代码就可以了。
在我的开发中,第一个要解决的分页界面是“类别”中的文章。先放最终效果:
具体实现步骤如下:
首先,修改routing.yml文件中关于显示属于某个类别的文章的路径,加入分页参数:
show_category:
url: /category/:slug/:page
class: sfDoctrineRoute
options:
model: G4pCategory
type: object
param:
module: category
action: show
page: 1为了简便,我给它定义了缺省的页数为1。
然后,修改category/actions/actions.class.php文件中的executeShow函数:
public function executeShow(sfWebRequest $request) { $this->category = $this->getRoute()->getObject(); $this->c_slug=$this->category->getName(); $this->pager=new sfDoctrinePager('G4pArticle', sfConfig::get('app_max_articles_on_category')); $this->pager->setQuery($this->category->getArticlesQuery($this->category->getId())); $this->pager->setPage($request->getParameter('page', 1)); $this->pager->init(); }
这里的关键是最后四行。我创建了一个sfDoctrinePager对象,传递了它的查询SQL,并设置其要显示的页面(从sfWebRequest,也就是从$_GET中传递进来),然后进行初始化。注意,这里的SQL——严格说是一个查询的对象不是直接来自于之前我常用的G4pCategoryTable.class.php文件,而是来自G4pCategory.class.php文件。这两个文件的区别说实话我也不是很清楚。按照我的认为,前者主要是包含一些直接返回记录集的函数,我们可以把这个文件看成是一个虚拟的表;后者是一些类方法,一般不会包含直接返回记录集的方法,并可以对类的操作如save,get某个字段的方法进行改写。
getArticlesQuery函数具体定义如下:
public function getArticlesQuery($id) { $q=Doctrine::getTable('G4pArticle')->createQuery('a') ->leftJoin('a.G4pCategory') ->where('a.G4pCategory.id=?', array($id)) ->orderBy('a.published_at desc, id'); return $q; }
它和我之前定义的一些方法还是比较类似的,唯一的区别是我直接返回一个Query对象,而不是返回记录集(通过$q->execute()得到)。这是因为具体要得到哪些记录必须由pager来确定,而pager是根据当前页面和每页显示的帖子数量来构建对应的SQL语句的。
另外,请注意这个SQL的构成方法。Article表和Category表显然是一对多的关系(“一”在category表这边),所以我用left join来连接category表,我不需要指定on字段,因为这个是由Symfony根据表关系自动生成的。而在where子句中,我用了带参数的SQL构造,这样也可以有效的防止一些恶意的SQL注入攻击。
最后,我们修改category模块的showSuccess.php函数(它其实就是一个模板文件),引入对应的记录集并加以操作,显示必要的导航等等。全部代码如下。为了方便阅读,我直接加了一些注释,如果你要直接使用代码,请将我的注释去除或者以正确的方式插入:
<?php $articles=$pager->getResults() //获得当前的记录集 ?> <div class="pick"> <div class="titlepic"><span class="sectionhead">文章分类:</span><span class="slug"><?php echo $c_slug; ?></span> <span class="more"><?php echo link_to('...所有文章', 'list_article') ?> </span> </div> <br/> <div class="article"> <ul> <?php foreach ($articles as $a): $acount=Doctrine_Core::getTable('g4pcomment')->getCommentCount($a->id)->c; ?> <li><?php echo link_to($a->title, 'show_article', $a) ?> <div class="writer">作者:<?php echo link_to($a->author, 'show_author', $a) ?> | <?php echo $a->published_at ?> | <a href="<?php echo url_for('show_article', $a)?>#comment"><?php echo $acount ?>评</a> </div> </li> <?php endforeach; ?> </ul> <hr/> <?php if($pager->haveToPaginate()): //判断是否需要分页,如果需要,那么显示导航条 ?> <a href="<?php echo url_for('show_category',$category) ?>/1"><img src="/images/first.png" title="第一页" alt="第一页" /></a> <a href="<?php echo url_for('show_category',$category) ?>/<?php echo $pager->getPreviousPage() ?>"><img src="/images/previous.png" title="上一页" alt="上一页" /></a> <?php foreach ($pager->getLinks() as $page): ?> <?php if($page==$pager->getPage()): ?> <span class="currentpage"><?php echo $page ?></span> <?php else: ?> <a href="<?php echo url_for('show_category', $category) ?>/<?php echo $page ?>"><?php echo $page ?></a> <?php endif ?> <?php endforeach ?> <a href="<?php echo url_for('show_category',$category) ?>/<?php echo $pager->getNextPage() ?>"><img src="/images/next.png" title="下一页" alt="下一页" /></a> <a href="<?php echo url_for('show_category',$category) ?>/<?php echo $pager->getLastPage() ?>"><img src="/images/last.png" title="末页" alt="末页" /></a> <?php endif ?> <br/><strong>本类别中共有<?php echo count($pager) ?>篇文章。</strong> <?php if($pager->haveToPaginate()): ?> 当前为第<?php echo $pager->getPage()?>页,共<?php echo $pager->getLastPage() ?>页。 <?php endif ?> </div> </div>
就这么简单直接。
=====
作为第4天,今天的工作其实还可以延续,因为我可以用相同的、很少的工作量完成其它几个页面的显示。不过这个就让我稍微偷偷懒,用个实际中的几天来完成吧。
本文收录于[go4pro.org]






评论列表
(单击此处切换显示/隐藏评论)