织梦获取分页导航列表函数GetPageList()
函数:GetPageList($atts,$refObj='',$fields=array())
功能:获取分页导航
所在文件:/include/datalistcp.class.php
这个函数是的功能是实现如下所示的分页导航。
我们登录后台后,在所有分页列表看到的分页都是由这个函数来实现的,这个类似织梦前台文档里列表分页和内容分页样式,当然,跟前台的是有根本的区别的。二者的使用的模板引擎都不一样,这是最重要的区别,正是使用的模板引擎不一样,才有了二者的区别。
本教程对这个函数进行详细分析一下,然后,在另外的一个教程里面对这个导航进行二次开发,升级改造之。因为,我们做底层二次开发的就必须有这样的基本功,做到每个功能都能知其然,更要知其所以然。
分析开始:
1.获得当前网址:$purl = $this->GetCurUrl(),这里的当前网址指的就是分页页面的网当前网址,这个网址获取的是除掉域名和问号后面的参数,例如:www.dedebase.com/dede/content_li ... amp;totalresault=19,那么这个GetCurl()函数获取的是/dede/content_list.php 。
2.定义上一页和下一页公式:
$prepagenum = $this->pageNO-1; $nextpagenum = $this->pageNO+1;
例如总共分页有20页,当前页是10,那么上一页就是10-1=9,下一页就是10+1=11 。
3. 初始化listsize,listitem和总页数$totalpage: 计算机公式ceil($this->totalResult/$this->pageSize)的值就是总页数,这是分页里面的核心。定义$atts['listitem'] = "info,index,end,pre,next,pageno",也就是listitem的默认属性值。
4. 判断$totalpage总共多少页:若总页数小于等于1,并且总记录数$this->totalResult 大于零,说明有一页,那么返回的是:<span>{$lang_total} 1 {$lang_page}/".$this->totalResult.$lang_record_number."</span>,对应的显示内容为:1页/多少条记录。
注意:总记录数$this->totalResult是如何而来的?相信很多人看不出来的,我在写教程前也没有在意也是在做这个教程前,才好好想了一下,原来这个是通过预处理函数PreLoad()得到的。
请听我慢慢道来:当我们在文件content_list.php里面实例化分页类为一个对象,载入模板,此时,就已经调用了模板引擎,把模板文件解析好,并编译好了里面的标签。但是此时,并没有写入缓存文件;在文件content_list.php里面运行到显示代码:$dlist->Display();时,因为这个方法是在分页类对象里面,代码如下所示。
function Display() { $this->PreLoad(); $this->tpl->SetObject($this); $this->tpl->Display(); }
您发现没有这里面调用了预处理函数PreLoad(),这个函数里面有下面几行代码:
$countQuery = preg_replace("#SELECT[ \r\n\t](.*)[ \r\n\t]FROM#is", 'SELECT COUNT(*) AS dd FROM', $this->sourceSql); $row = $this->dsql->GetOne($countQuery); $this->totalResult = isset($row['dd'])? $row['dd'] : 0;
这里面的$this-.sourceSql正是我们在content_list.php里面写的如下sql查询语句:
也就是我们要显示的内容条数,即$this->totalResult = $row['dd']。
当执行完这个PreLoad()函数后,我们得到了总记录数$this->totalResult,但是,此时,缓存文件并没有执行写入操作,因为,还没有调用模板引擎里面的display()函数。
当执行到分页类display()函数里面的这行代码:$this->tpl->Display()
此时,才把缓存文件写入到/data/tplcache/文件夹里面。
在$tpl->Display()里面,执行include $this->cacheFile;这行代码后,才把编译好的缓存文件引入到content_list.php里面,这时,这里面就多了很多代码,其中,包括这段分页代码:
<?php $atts = array(); $atts['tagname'] = 'pagelist'; $atts['listsize'] = '3'; $atts['site'] = 'www.dedebase.com'; echo $this->refObj->GetPageList($atts,$this->refObj,$fields); ?>
此时,程序才执行这里面的函数GetPageList(),也就是分页导航代码。这时,我们在后台才能看到分页效果。
5.若总记录数为零,则返回:共0页/0条记录。
6.定义一般的信息页:$infos = "<span>{$lang_total} {$totalpage} {$lang_page}/{$this->totalResult}{$lang_record_number} </span>";
7.除了总记录数为0 和小于等于1页,总记录数大于0的二种情况,其它情况当总记录数不为零时,把其实内容保存到数组$this->getValues里面,即:$this->getValues['totalresult'] = $this->totalResult;
然后,遍历这个数组$this->getValues,把totalresult当作键,把$this->totalResult当作值,组装到当前网址上面,即$geturl.="$key=$value"."&";
现在网址就多了这个总记录数参数了。
然后,通过代码$purl .= "?".$geturl;在网址前加上问号。下面就开始处理不同页码数的连接了。
8.若页码数不为1,说明当前页肯定有前一页和第一页,否则,就是第一页也就是首页;若当前页码与总页码不相等,且总页数大于1,说明当前页既有上一页也有下一页,否则就是最后一页,也就尾页。这些判断的代码如下所示:
9. 获得在分页导航显示的总的页数:$total_list = $atts['listsize'] * 2 + 1;
这个意思是:当我们在织梦模板里面,加上{dede:pagelist listsize='3' /}的话,那么,在后台我们看到的分页将是显示3*2+1=7个数字,再多出来的页数将不显示。如下图所示。
实际上这个分页共有9个页面,但是,这里只显示7个数字,就上因为,上面标签的设置,最终还是取决于$atts['listsize'] * 2 + 1这个表达式。
10.处理我们在标签里面设置的listsize值,因为,用户不知道能从数据库中查询出多少条记录,用户也不知道到底应当设置多少,所以,有可能的情况是,用户写的标签里面的属性listsize后,显示的页数大于总页数,设置{dede:pagelist listsize='8' /} 此时,分页导航显示的17页,但是,实际查询出来的数据,只有9页;另一种情况就是相反的,也就是我们上面设置的listsize=3的情况,下面的代码就是处理的这二种情况:
if($this->pageNO >= $total_list) { $j = $this->pageNO - $atts['listsize']; $total_list=$this->pageNO + $atts['listsize']; if($total_list > $totalpage) { $total_list = $totalpage; } } else { $j=1; if($total_list > $totalpage) { $total_list = $totalpage; } }
11. 判断当前页是不是就是我点击的这个页,也就是如下图所示点击的是第4页。
若是当前页,则加个html标签<strong>,否则,显示的是一个链接。代码如下所示。
for($j; $j<=$total_list; $j++) { $listdd .= $j==$this->pageNO ? "<strong>$j</strong>\n" : "<a href='".$purl."pageno=$j'>".$j."</a>\n"; }
12.下面这一大段代码就简单了,如下图所示。
这段代码是判断属性数组$atts里面的值,也就是listitem的值有哪些,若匹配到说明,我们在标签里已经设置了这个属性值,若设置了就显示,例如,我在标签里面加上listitem="next form",即{dede:pagelist listsize=3 listitem="next end" /},此时,显示的分页导航如下图所示。
此时,只显示“下一页”和“末页”二项分页导航内容。
如果想做织梦分页导航就得对这个函数进行彻底的研究透,当然,这个分页导航我们自己看一般也不用去改,但是,有的客户会要求改造一下这个分页,确实,织梦官方默认的导航也不太好看。