> Discuz开发手册 > 模板变量/循环/判断/嵌套
模板制作中必须知道的变量、循环、判断、文件嵌套
作者:cr180 / 最后更新:2016-11-21
模板的基础概念
模板是对程序原有的界面、框架进行各种改进,作者根据自己的创作与功能收集,让程序前台以一种全新的形态进行展示!模板的制作触及程序功能的二次增强与用户体验
制作模板时需要有一定的HTML基础、css样式基础、简单的模板语法基础。这些都可以通过修改默认模板过程中学会
当学会风格制作后,就可以试着制作一款自己需要的模板了。
特点:拥有独立的一套模板目录、涉及大量模板文件的自定义修改,有一些模板会有繁琐的安装过程。
一套优秀的模板需要站点管理人员根据自己使用的模板特性进行专门的数据推送与数据展现方式。
无论模板制作多么优秀,管理人员推送到模板中的数据如果不足以吸引眼球,那也是失败的!
本文中针对模板制作中重要的环节进行讲解,以下内容同样适用与其他开源程序如PHPwind、php168、Ecshop等等,大家在看以下内容时要学会举一反三,多试验、多动手、多备份!
DiscuzX2.5新增php格式模板文件载入支持

从 Discuz! X2.5 开始,模板文件支持 PHP 扩展名的格式,主要功能是防止模板被别的论坛盗取!
例如:template/default/common/header.htm
可创建为:template/default/common/header.php,模板文件为php后,代码书写方式不改变依然和以前一样采用HTML

php后缀的模板文件需在模板文件开头添加一行代码:

如:

  1. <?php exit;?>

或者:

  1. <?php echo '你不能看此模板的内容';exit;?>

PHP 的模板文件的模板数据内容将从文件的第二行开始解析。PHP 和 HTM 模板文件同时存在时,会优先解析 PHP 模板文件(该模式只能用与X2.5及以上版本!)

模板的变量名:

DiscuzX中有两种变量
一种我们称为G变量:$_G[xxx]
G变量是程序的全局变量,为了让程序更加高效,减少不必要的数据获取,所以程序特将经常需要用到的变量统一到G变量下,如用户登录信息、后台设置信息、服务器环境信息、客户端CooKies、数据缓存等都存放在G变量里面,在制作模板的时候作者只需要将G变量打印出来即可获得需要的信息是否在G变量里面。

另一种自定义变量:$xxx
自定义变量是以$开头首位为字母或下划线的自定义代码,如:$data、$thread、$post、$forumlist、$threadlist等等!
自定义变量是作者可以自己在程序里面自定义的,或程序自身已经定义了的。

PS:我们在制作模板的时候是将程序已有的数据进行另外一种展现方式,所以不用去自定义变量。


变量数据在模板中的输出方式:
程序从数据库或缓存文件中将数据进行读取,转换成数组数据并载入模板进行输出!所以我们在模板中调用并输出列表数据时必须写循环代码,将数组数据逐条循环显示出来!

自定义变量数据的循环代码书写格式:

  1. <!--{loop $data $key $value}-->
  2.      <li>$key $value</li>
  3. <!--{/loop}-->
这段代码就是一段典型的循环代码,意思是将自定义变量$data进行循环,并将每次循环的数据传递给$value,$key是数组键值(序号),<!--{loop $data $key $value}--><!--{/loop}-->之间书写html代码。我们只需要记住这个简单却重要的意思!

打开template/default/forum/viewthread.htm

查找以下代码:

  1. <!--{eval $postcount = 0;}-->
  2.     <!--{loop $postlist $post}-->
  3.         <!--{if $post['invisible'] != -5}-->
  4.             <!--{if $rushreply && $_G['gp_checkrush'] && $post['rewardfloor'] != 1}-->
  5.                 <!--{eval continue;}-->
  6.             <!--{/if}-->
  7.             <div id="post_$post[pid]">
  8.                 <!--{subtemplate forum/viewthread_node}-->
  9.             </div>
  10.             <!--{eval $postcount++;}-->
  11.         <!--{/if}-->
  12.     <!--{/loop}-->

这段代码就是帖子页的循环代码,通过上面的【 自定义变量数据的循环代码书写格式】我们应该可以大致了解到这个循环代码的意思!$postlist变量中存放了当前访问帖子的主题信息、回复楼层信息,通过循环,将每个楼层的数据传递给$post变量。
循环的HTML代码存放在template/default/forumviewthread_node.htm
打开这个文件后可以看见里面的很多变量名都是$post,例如:$post['authorid'] = 作者UID、$post['username']=作者用户名等等,通过$post[xxx]不同的字段信息输出相应的数据,这些字段信息都在数据库-数据表pre_forum_post存放着。


经常发现很多童鞋将$post[xxx]变量放到其他模板文件中去用,结果刷新出来的结果什么都没有!
原因是: 每个模板文件都有一个对应的程序文件,所以自定义变量不能在不同的页面中使用,只限于定义了变量的模板文件中使用。例如帖子列表页的帖子数据是不能在论坛首页或其他页面输出的!


模板制作中最重要的条件判断(if else):



在循环语句中,我们经常要对不同的数据进行其他的展现方式,这时就需要用到条件判断!条件判断语法有很多中方式,如:大于、等于、小于、不等于、变量是否存在等!if else速记方法:if=如果 else=那么,条件判断涉及逻辑问题,所以需要很强的逻辑思维。下面的例子你第一次看的时候可能会感觉很好笑,请静下心仔细看!

从简单到复杂讲解例子:

$xxx变量是否存在:

  1. <!--{if $xxx}-->.....<!--{/if}-->
  2. PS:如果$xxx变量存在,则执行中间的代码

$xxx变量是否大于1:

  1. <!--{if $xxx >1}-->.....<!--{/if}-->
  2. PS:如果$xxx变量大于1,则执行中间的代码

$xxx变量是否小于1:

  1. <!--{if $xxx <1}-->.....<!--{/if}-->
  2. PS:如果$xxx变量小于1,则执行中间的代码

$xxx变量是否不等于1:

  1. <!--{if $xxx !=1}-->.....<!--{/if}-->
  2. PS:如果$xxx变量不等于1,则执行中间的代码

复杂一点(如果那么):

  1. <!--{if $xxx ==1}-->a<!--{else}-->b<!--{/if}-->
  2. PS:如果$xxx变量等于1,则执行a代码,那么如果$xxx不等于1则执行b代码

再复杂点(如果那么如果)

  1. <!--{if $xxx ==1}-->a<!--{elseif $xxx ==2}-->b<!--{elseif $xxx ==3}-->c<!--{/if}-->
  2. PS:如果$xxx变量等于1,则执行a代码,
  3. 那么如果$xxx不等于1等于2则执行b代码,
  4. 那么如果$xxx不等于1也不等于2是等于3,则执行c代码。有点晕了吗?

再再复杂一点(ifelse两个条件判断)

  1. <!--{if $xxx ==1 || $xxx ==3}-->a<!--{elseif $xxx ==2}-->b<!--{/if}-->
  2. PS:如果$xxx变量等于1或者$xxx等于3,则执行a代码,
  3. 那么如果$xxx不等于1也不等于3,等于2则执行b代码,

两个变量判断

  1. <!--{if $xxx ==1 || $ooo ==1}-->a<!--{elseif $xxx && !$ooo}-->b<!--{/if}-->
  2. PS:如果$xxx变量等于1或者$ooo等于1,则执行a代码,
  3. 那么如果$xxx不等于1,$ooo也不等于1,$xxx变量存在并且$ooo变量不存在则执行b代码


读懂了ifelse例子后,上面viewthread.htm那段代码中的<!--{if $post['invisible'] != -5}-->.....<!--{/if}-->我们根据刚才的ifelse注解,现在可以理解他的意思:判断循环输出时,如果$post['invisible'] 不等于-5则执行载入的HTML代码

模板文件中的插件钩子(插件嵌入点):


插件钩子代码例子:

  1. <!--{hook/xxx_xxx}-->
查看模板插件钩子注解图示例
插件钩子的作用在于能让插件在指定的一些位置输出有关代码!
在DZ7.x-DX1.5中插件钩子并不显得很重要,但是随着插件应用的不断普及,插件创作者的不断加入,插件钩子在模板中的地位尤其显得格外重要,如果缺少了程序必须的插件钩子,可能会造成自带系统插件功能受到影响!
所以我们在制作模板的时候一定要参考默认模板中的插件钩子位置进行合理的安排!
除非你觉得某个插件钩子在自己的模板中并不需要,否则请保留插件钩子代码!

DiscuzX的模板文件N次嵌套:


我们在模板文件template/default/forum/viewthread.htm中可以找到:<!--{subtemplate forum/viewthread_node}-->,
这个代码的意思是在这个代码的位置载入另外一个模板文件:template/default/forum/viewthread_node.htm,
当我们打开这个文件后发现还有一段载入代码:<!--{subtemplate forum/viewthread_node_body}-->
这就是DiscuzX的模板文件N次嵌套!

我们首先要清楚的理解各个模板文件是做什么用的,就知道这些嵌套的意思:
template/default/forum/viewthread.htm 帖子内容页主模板,这个模板文件是帖子内容页处理程序加载的
template/default/forum/viewthread_node.htm 帖子内容页楼层模板文件,这个模板文件循环一次就是一个楼层
template/default/forum/viewthread_node_body.htm 帖子内容页,帖子内容模板,这个模板文件是专门用于处理帖子内容的

这种嵌套方式是便于以后的代码修改,比如我只想修改帖子内容的代码,就只需要编辑viewthread_node_body.htm,而不用把另外两个文件都编辑。


通过以上的讲解,大家也就可以对变量、循环、判断、文件嵌套有了一个初步的认识,事在人为,凡事多动手多备份少依赖,就能很快的进入模板制作行列,明明只需要改下代码刷新一下的简单问题,却要花一天的时间等别人帮你解决,如何才能高效?只有通过不断试验,不断累计错误,这样才能得到提升!