帝国CMS和织梦CMS的栏目都支持无限级分类,这也带来了不少问题。去年我实现了一个功能,用来获取当前栏目的最顶级栏目。这相对简单,只需编写一个无限循环查询,逐层查找当前栏目的上级栏目,直到找到顶级栏目为止。今天我们讨论的是一个更复杂的功能:不仅要读取当前栏目的下级栏目,还要读取所有的子栏目,无论这些子栏目有多少层级。这里以帝国CMS和织梦CMS为例来说明。(个人比较推崇帝国CMS,它的标签和PHP混编非常好用,甚至可以在模板中定义PHP函数来使用),先看效果:
这个效果图是以帝国CMS为例的,可以看到我已经将当前栏目的所有子栏目中最终级栏目的ID读了出来。我们可以根据自己的需要调整这个函数。
实现方法是这样的:查看帝国CMS的数据库,其栏目表名为`phome_enewsclass`。所有无限级分类都会存储每个记录的父类信息。我们通过这一点来获取所有子栏目。代码如下:
- function sonclass1($cid, $dbtbpre){
- $sql="SELECT classid, classname, islast FROM {$dbtbpre}enewsclass WHERE bclassid = '$cid'";
- $query=mysql_query($sql);
- $id = '';
- while($c = mysql_fetch_array($query)){
- if('1'==$c['islast']){
- $id .=$c['classid'].',';
- }else{
- $id .=sonclass2($c['classid'],$dbtbpre);
- }
- }
- if($id){
- return $id;
- }else{
- return false;
- }
- }
- function sonclass2($cid, $dbtbpre){
- $sql="SELECT classid, classname, islast FROM {$dbtbpre}enewsclass WHERE bclassid = '$cid'";
- $query=mysql_query($sql);
- $id = '';
- while($c = mysql_fetch_array($query)){
- if('1'==$c['islast']){
- $id .=$c['classid'].',';
- }else{
- $id .=sonclass2($c['classid'],$dbtbpre);
- }
- }
- return $id;
- }
将上述代码添加到帝国CMS的函数库文件`e/class/functions.php`中。
我们来看这段代码的意思:调用`sonclass1`函数,传递两个参数,第一个是当前栏目的ID,第二个是数据表的前缀。这些参数都可以直接从前端模板中获取。
接着我们来看看前端模板的写法。
通常我们在列表页使用,以列表模板为例。帝国CMS的封面模板不能发布文章,但可以使用列表页模板,并且模板中可以直接写PHP代码。
我是这样写的:
- <?php
- echo sonclass1($GLOBALS['navclassid'], $dbtbpre);
- ?>;
模板中已经加载了函数库文件,因此可以直接使用这个函数。`$GLOBALS['navclassid']`和`$dbtbpre`分别是获取当前栏目的ID和数据表的前缀。这样就能实现读取所有子栏目中的最终级栏目的ID。根据需要可以进行修改。
有人可能会问既然可以直接写PHP代码,为什么不在模板中定义这个函数?原因在于,如果模板被多次调用,函数就会被多次定义,而我们知道,一个同名函数不能被多次定义。除非这个模板只使用一次,否则需要在函数库中定义。
织梦CMS实现相同功能的方法类似,只需找到其函数库文件并调整函数内的字段即可。