织梦设定模板文件函数LoadTemplate($tmpfile)

admin2023-01-191340

函数名:LoadTemplate($tmpfile)

功能:加载并处理模板后,得到一个处理后的字符串

参数:$tmpfile 模板文件

所在文件:/include/dedetemplets.class.php

无论分页还是在其它地方,一般都要用到这个装载模板的函数/方法,也就是说只要在我们后台能够看到的,只要用到模板引擎的都要用到这个函数,平常我们写php代码或其它代码,虽然,我们看不到这个函数的使用,但是,它其它一直在使用,因为,这是最底层的函数了,对于织梦系统来说,再也没有比模板引擎更底层的了。

作为一般的站长我们可以不知道这个,但是,对于二次开发人员来说,如果不懂的织梦模板引擎也能进行织梦二次开发,但是,建议还是把这个弄明白,这样去开发的时候,更加容易理解,效率更高。

这个函数的代码虽然非常多,但是,它实际上没有对内容做多少处理,这个函数最后返回的是处理后的模板内容字符串,也就是经过LoadTemplate($tmpfile)加载后,得到的是$tmpfile内容的字符串。

函数代码分析:

1、判断模板是否存在,若不存在,直接显示错误并退出,代码如下:

 if(!file_exists($tmpfile))
    {
        echo " Template Not Found! ";
     exit();
}

当我们实例化模板类的时候,就要调用这个对象的方法 LoadTemplate($tmpfile),若模板$tmpfile连存在都不存在,那么,接下来就什么也做不了了,当然就要退出程序了。模板引擎本来就是解析模板的,连要解析的模板都不存在了还解析什么?明白了这一点,我们就会理解为什么一开始就要判断一下这个模板文件存不存在了。

2、有时候我们可能不经意或其它原因,把模板路径里面写上了多个“/”,例如www.xxx.com///dede//templets/index.htm,像这样的我们就要把多个斜杠,修改成一个斜杠,代码如下:

  $tmpfile = preg_replace("/[\\/]{1,}/", "/", $tmpfile);

经过上面的代码处理后,得到的模板文件$tmpfile就是一个正常的模板路径www.dedebase.com/dede/templets/index.htm了。

3、把这个处理好的模板文件,按正斜杠分割成数组,存放到$tmpfiles这个数组里面,代码如下所示:

$tmpfiles = explode('/',$tmpfile);

我们测试一下,分割后的数组如下图所示。

image.png

4、做一个唯一文件名:$tmpfileOnlyName = preg_replace("/(.*)\//", "", $tmpfile),也就是把www.xxx.comdedetempletsindex.htm,作为一个文件名以备后台使用之。

5、把模板文件赋给当然变量 $this->templateFile = $tmpfile;

6、找到模板所在的目录并赋给$this->refDir,代码是:

for($i=0; $i < count($tmpfiles)-1; $i++)
   {
       $this->refDir .= $tmpfiles[$i].'/';
}

统计数组count($tmpfiles)的值,即为4,然后,减少1,则为3,这样通过上面的遍历就可以取出数组$tmpfiles里面除了模板名外的模板路经,即:www.xxx.com/dede/templets/  这什么要做找到模板路径?肯定是为一面使用作准备了。

7、编译后的模板文件肯定要存放起来,所以,要判断一下加载的模板编译后的路径,是不是存在,若$this->cacheDir不是一个目录,则直接使用模板index.htm所在的文件目录即www.xxx.com/dede/templets/作为缓存目录,若存在则使用$this->cacheDir 作为缓存目录,并且在这个缓存目录后面加上一个正斜杠,代码如下所示:

if(!is_dir($this->cacheDir))
        {
            $this->cacheDir = $this->refDir;
        }
        if($this->cacheDir!='')
        {
            $this->cacheDir = $this->cacheDir.'/';
        }

这个缓存目录,构造函数里面已经初始化为 $this->cacheDir=DEDEROOT.$GLOBALS['cfg_tplcache_dir'],也就是织梦系统根目录下面的data/tplcache,这个在织梦后台就可以查找到,如下图所示。

image.png

8、是否定义全局变量_DEBUG_CACHE,若设置了这个变量,则直接把模板路径作为文件缓存路径,事实上,织梦默认的是没有设置这个全局变量,代码是:

        if(isset($GLOBALS['_DEBUG_CACHE']))
        {
            $this->cacheDir = $this->refDir;
        }

关于这个变量我们可以打印一下看看到底有没有设置,如果echo 一下,系统会提示:Notice: Undefined index: _DEBUG_CACHE in D:\wamp\www\test.php,这就说明这个确实没有设置,为什么要设置这个,设置了有什么用?可能是调试错误用的。

8、设置缓存文件和配置文件,代码如下:

$this->cacheFile = $this->cacheDir.preg_replace("/\.(wml|html|htm|php)$/", "_".$this->GetEncodeStr($tmpfile).'.inc', $tmpfileOnlyName);
$this->configFile = $this->cacheDir.preg_replace("/\.(wml|html|htm|php)$/", "_".$this->GetEncodeStr($tmpfile).'_config.inc', $tmpfileOnlyName);

代码看上去很吓人似的,其实,这些代码比较简单,这二个文件都存在到了缓存目录,也就是/data/tplcache/,大家可以看一下个目录里的文件是以.inc和.txt为后缀的文件。以.inc为后缀的文件就是在这里生成的。

9、 不开启缓存、当缓存文件不存在、及模板为更新的文件的时候才载入模板并进行解析代码如下:

        if($this->isCache==FALSE || !file_exists($this->cacheFile)
        || filemtime($this->templateFile) > filemtime($this->cacheFile))
        {
            $t1 = ExecTime(); //debug
            $fp = fopen($this->templateFile,'r');
            $this->sourceString = fread($fp,filesize($this->templateFile));
            fclose($fp);
            $this->ParseTemplate();
            //模板解析时间
            //echo ExecTime() - $t1;
        }

这里我要解释一下,是否启用模板缓存这个也是在我们安装完织梦程序后,在我们的后台有一个地方进行设置是否启用模板缓存,如下图所示。

image.png

默认是开启的,当开启后,载入的模板处理后,就要缓存起来,没有开启则载入的模板就不会有缓存文件,所以,当然,要重新解析一次,也就是载入一次解析一次,从这里我们可以看出,我们一般情况下不要关闭这个缓存。

当模板文件不存在,这个不用多解释,不存在当然,要解析模板了。

当模板为更新的文件,也就是说原来的模板我更新了,例如,原来模板为inde.htm,现在我在这个文件里面的增加了一个标签,这时再载入模板后,生成的缓存文件虽然,原来的存在了,但是,不能用原来的缓存文件了,因为,我增加了一个标签了,这时就要解析。判断方法就是通过filemtime()函数来判断更新模板的时间是不是比缓存文件的时间还要大,若是大于缓存文件,则说明我们已经更改了模板文件。

这三个条件我们都理解了吧。再看里面的代码,设置一个模板的解析时间,这里织梦已经取消了这个了。

打开模板文件fopen($this->templateFile,'r'),然后,把这个模板文件通过函数fead()读取到$this->sourceString变量里面,以备后面的函数$this->ParseTemplate()解析用。

10、上面是解析模板的情况,若上面不成立,则执行下面的代码:

        else
        {
            if(file_exists($this->configFile))
            {
                include($this->configFile);
            }
        }

如果存在config文件,则载入此文件,该文件用于保存 $this->tpCfgs的内容,以供扩展用途

模板中用{tag:config name='' value=''/}来设定该值

以上二句解释是织梦官方给的,但是,默认是不存在这个文件的。

从上面的分析我们就可以看出,其实,这个LoadTemplate($tmpfile)函数就是把处理后的模板内容放到了$this->sourceString里面,最终目的就做这一件事。

万里长征只走出了一步,万事开头难,接下来我就验证这个函数里面的相关的结论。

先验证一下,当我们把模板文件改了后,程序会不会重新生成编译的文件。

在测试文件test.php写上如下测试代码:

<?php
require_once('./include/common.inc.php');
require_once ('./include/dedetemplate.class.php');

$tpl=new DedeTemplate();

$tpl->LoadTemplate('index.htm');

$tpl->display();
?>

其中模反文件index.htm里面的内容如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title><font color="Blue">{dede:field.webname/}</font></title>
</head>
<body class="index">
<font color="Blue">{dede:field.webname/}</font>
<!-- /footer -->
</body>
</html>

这里面有二个标签,此时,data\tplcache缓存目录里并没有任何缓存文件,如下图所示。

image.png

当我们在地址栏目输入localhost/test.php后,在这个缓存目录里就会多出一个文件,如下图所示:

image.png

请注意后面的时间是:2015-7-4 15:53

我们打开这个缓存文件看看里面的内容如下所示。

image.png

已经成功替换成了php代码了。

现在要改一下index.htm模板文件,我把标题里面的{dede:field.webname/}换成{dede:field.title/}如下图所示。

我再在地址栏目里面打开localhost/test.php

然后再看一下缓存目录里面的缓存文件data/tplcache/如下图所示。

image.png

请仔细看名字没有变,但是,后面的时间变了,变成了2015-7-4 16:00

这说明现在的缓存文件内容是我们修改过的内容,打开缓存文件看看:

 

5.png (17.6 KB, 下载次数: 78)

下载附件

2015-7-4 16:04 上传

果然已经变成了<?php echo fields['title'];?>。

实验成功!

网友评论