在Drupal中设置分页的区块视图时需要分外小心!

在近期的一个drupal项目中,我们遇到一个十分奇怪的问题:搜索结果页面的总记录数和总页数永远是一个错误的固定数字。这个极具迷惑性的假象让我们朝着各种错误的方向去寻找问题的答案,并且迟迟没有进展,然而等我们找到真正的问题原因时,结果可以说是让人大跌眼镜。

我们先是禁用了所有自定义开发的部分:把主题切换回drupal默认的前端主题Bartik,同时禁用所有自主开发的模块,然后再一点点重装回去,测试的结果是问题出在主题部分。

但接下来更让人迷惑了,一是我们的主题中只是对默认的搜索结果做了一些非常细小的覆写,不足以引发问题;二是当换成其他主题,比如Zen的时候,也出现同样问题。所以前面的问题出在主题部分的论断又被推翻了。

接下来我们又从异常的数据、关键字索引、缓存等方面去找问题。这一切都无功而返以后,我们还是回到代码部分,循着函数的执行路径逐个往回找,最后发现总记录数在某个区块渲染以后被更改了,而这个区块正好是Views模块生成的一个带分页的视图。

我恍然大悟,一定是Views的Pager ID问题!这个问题我以前曾经遇到过,而且还提醒过自己日后注意,没想到这次还是疏忽了。

没错,就是下图中的这个地方:

这个细小的设置,常常被很多人忽略,因为在绝大多数情况下,保持默认设置是没有问题的。但是记住,一旦页面上有多个分页器(这种情况通常是在把Views生成的一个带分页的视图作为区块嵌入页面的时候出现的),这个设置就变得至关重要。因为同一个页面上的各个分页器必须有各不相同的ID,而这个ID就是通过此处的选项来进行设置。

那么这个Pager ID到底是个什么东西呢?在解决我们项目问题的同时,我也顺便深入看了一下drupal的部分核心代码,对Pager ID也有了一些更深的认识。

原来在Drupal中,我们看到的任何分页器都是基于四个全局数组变量生成的,它们是:

global $pager_page_array;    // 存储当前页码
global $pager_total;    // 存储总页数
global $pager_total_items;    // 存储总记录数
global $pager_limits;    // 存储每页的记录数

由于每个变量都是数组,drupal就可以用不同的数组下标来区分多个分页器。这个下标,或者叫索引,就是上面所说的Pager ID。

一般来说,需要显示分页器的模块基本上都是Entity及其派生模块。Entity模块会通过递增Pager ID来自动区分多个分页器,这样多个分页器出现在同一个页面上时就会各自相安无事。

但是Views模块在生成分页器时Pager ID默认是0,这样如果页面上有超过一个分页器,它就会覆盖那个Pager ID为0的分页器。这就是我们项目中遇到的情况——搜索结果页面的分页器被Views生成的区块分页器覆盖掉了。这种情况下,就需要手动设置Pager ID。Pager ID设置为多少是合适的呢?其实只要能互相区分就可以了,一般来说,设置成较大的数字总是比较保险的。