给块标记赋值的织梦函数MakeOneTag()

admin2023-01-191181

函数名:MakeOneTag(&$dtp, &$refObj, $parfield='Y')

参数说明:这个函数里面的三个参数数据类型全是对象,第一个指模板引擎、第二个指的实例化对象,第三个是一个标志对象。一般第三个用默认的。

返回值:字符串

所在文件:文档小助手文件/include/helpers/channelunit.helper.php里面

这个函数定义,虽然没有直接写在模板引擎或类中,但是,这并不等于这个函数不重要,其实,这个函数对于静态模板引擎解析模板起到了至关重要的作用,如果没有这个函数,那么,标签就无法使用,模板也就无法解析,所以,对于研究模板引擎的朋友来说,最好,能把这个函数弄明白,这样理解起来织梦模板是如何被解析的,就容易多了。

不过如果实在不理解,这个完全可以不用管,因为,做织梦二次开发这个完全用不着,除非你也开发个像织梦一样的系统,而且是自己写代码,如果你也想做个织梦这样的系统,是在织梦基础上进行二次开发的话,那么,你完全可以也不用管这个函数,因为,这个我们也不用改,只要按照织梦开发规则去开发,既然,人家织梦都帮我们封装好了,那么,我们完全拿过来用就行了。

不过话又说回来了,如果你多了解一下织梦底层的东西,对于我们做二次开发的朋友,至少可以知道更多的开发思路,也是基于此,我才要把织梦系统里面的函数分析一遍。

总之,这个函数是重要,而且,非常重要,但是,如果没有兴趣的话,完全可以不用理它。因为,它一点也不影响我们对织梦二次开发。

代码分析开始:

第一行代码:声明全局变量$cfg_disable_tags; 这个变量是在织梦后台,系统——>基本参数配置——其它选项里面,这个变量的值就是dede模板引擎禁用的内容,织梦默认的值为php代码,也就是把标签标签{dede:php}{/dede:php}禁用了,也就是说这个变量的值就是一个一个的标记,这些标记都在/include/taglib/里面,如果你填写的是ask,那么,ask标签就会在模板里被禁止使用。

接下来二行是判断这个变量是否设置,若设置则把设置的值赋给$cfg_disable_tags,然后,把设置的值通过英文状态下的逗号分隔开来,放入到数组$disable_tags里面。

第五行:$dtp->setRefObj($refObj);这个有点难理解,就是把参数$refObj这个对象作为当前对象,例如我们实例化视图类arc.partview.class.php后,就把实例化后的partiview对象作为当前对象,因为,在视图类里面调用这个函数了,所以,在这个函数里面我们要这样设置一下,如果在类中实例化模板引擎后,也要执行一下这个代码,这样就告诉当前类,把实例化的对象当作当前对象。

如果实在不理解也没有关系,只要知道实例化后一个模板引擎后,就要写这样一句代码,这是规定。

下面这段代码是:读取自由调用tag列表

$dh = dir(DEDEINC.'/taglib');
    while($filename = $dh->read())
    {
        if(preg_match("/\.lib\./", $filename))
        {
            $alltags[] = str_replace('.lib.php','',$filename);
        }
    }
    $dh->Close();

因为,我们解析模板的时候,就要分析模板里面的标签,看看模板里的标签是不是在/include/taglib/ 文件夹里面,要判断是不是在这个文件夹里面,就首先要把这些标记一个一个取出来,然后,为下面从模板里取出解析后的标记进行对比,然后,找到后就处理这个标记。

上面这段代码,其实,非常简单,就是把标记从taglib文件夹遍历出来,放入到$alltags里面。注意在遍历这个文件夹的时候,用到了dir()这个函,这个函数返回一个对象。这个对象包含三个方法:read() , rewind() 以及 close()。

我们遍历数组用的是for或foreach,while等,如果我们遍历文件就用dir()及其里面的方法,这个函数很少用到,但是,也是一种遍历文件夹的方法。

下面整个foreach是处理模板里面的标签的,在这一大段代码里面又分二大部分,一部分是处理模板里面的短标签{dede:field.title/} 也就是处理标记field的,一部分是处理模板里面的块标签的。

代码:

1.获取标记名:$tagname = $ctag->GetName();

2.获取属性值:$vname = $ctag->GetAtt('name');$vname 相当于栏目表里面的字段。

3. 若以实例化视图类为例子,$refObj是指partview对象,$refObj->Fields指的是栏目表#@__arctyper所有字段和模型表#@__channeltype 表里面的栏目名称,附加表字段和是否生成字段组成的数组,这个是通过视图类里面的实例化栏目类来得到的数组,代码如下所示:

            $this->TypeLink = new TypeLink($typeid);
            if(is_array($this->TypeLink->TypeInfos))
            {
                foreach($this->TypeLink->TypeInfos as $k=>$v)
                {
                    if(preg_match("/[^0-9]/", $k))
                    {
                        $this->Fields[$k] = $v;
                    }
                }
            }

那么$refObj->Fields[$vname]指的就是字段为$vname的值,理解了这个以下代码理解起来就容易多了。

标记是field,然后,name的属性值有可能是二种,一种是数组,一种是变通的字段,这样就要把这二种分开处理。name="array"且已经设置了$refObj->Fields,那么,直接把这个数组分配给这个标记id,代码为:

$dtp->Assign($tagid,$refObj->Fields);

否则,把字段值分配给这个tagid,即:$dtp->Assign($tagid,$refObj->Fields[$vname]),这样类似{dede:field name='title'/}的短标记就解析完了,但是,在织梦系统里还有一种比较特殊的标签就是专题标签,标题标签也是短标记的一种,例如:

{dede:field name='note' noteid='aaa' /}

所以,对于专题模板标记我们也要处理,这个处理起来也比较简单,先判断一下noteid是不是存在,若存在则再判断一下note_aaa这个是否已经设置了,若设置了则把这个专题的内容分配给当前标记。到现在短标记才正式处理结束,我们先来个小结上面是处理的短标签或称短标记,是标记为field的,这里面又因为name值不同,分为数组和普通的,最后一类就是专题,其实,专题是普通的可以归类为普通一类。

下面的代码是处理块标签的,例如:{dede:ask row=6}底层模板{/dede:ask} 像这样的块标签。

因为这些块标签都存在include/taglib/里面,所以,应当先从这个文件夹里面把标记取出来,这个工作我们在上面已经做了,这些标记都放在$alltags 里面。

只要在模板里遇到标签,就要判断一下是不是在这个数组里面,若在这个数组里面,就要解析这个标签,如何解析?那么,使用include/taglib/里面的遍历到的标记文件了,例如在模反里遍历到了ask标记,那么,就要把这个标记文件引入到函数里面,这个是通过

$filename = DEDEINC.'/taglib/'.$tagname.'.lib.php';

这行来实现的,也就是$filename = DEDEINC.'/taglib/ask.lib.php';然后,用include_once($filename)引入。

引入ask.lib.php这个文件后,就要执行这个文件里面的函数,也就是lib_ask()这个函数,这个函数的返回值分配到了当前标签id里面,这个值就是标签的值,调用这个函数是通过$dtp->Assign($tagid,$funcname($ctag,$refObj));来实现的。

从这里我们可以得出,原来织梦在include/taglib/里面的文件是通过这个函数来调用的,也就是说我们模板里面的标签都是通过这个函数来处理的,从这里我们看出这个函数的重要性了吧!

当然,这个函数已经是织梦里面非常底层的代码了,可以说是最底层的,对于我们织梦二次开发人员来说这个开发的可能性为零,因为,我们在做织梦二次开发的时候,一般不去改织梦系统里面底层的代码,若改这个地方可能要改几十个文件,也完全没有必要改,人家都帮我们封装好了,但是,这样来读一下这些代码也没有坏处。

这个函数必须与静态模板引擎里面的处理特殊标记AssignSysTag()函数结合使用,才能把一个模板解析完整,否则,只用这个函数是不可能实现的。

这个函数还有一个特点就是它跟动态模板引擎里面的CompilerOneTag()类似,不过它做的比这编译函数要多,可以说比较综合,它把动态模反引擎里面几个函数做的一起给做了。

使用这个函数文件一般为类文件,因为,在织梦系统里面类是比较底层的模板了,我们二次开发极少改类文件,更不要说这个函数了,所以,这个函数都是类文件在调用,我这里把调用这个函数的类文件分类整理如下:

//除了分类信息、专题外的所以模型共用类
/include/arc.partview.class.php
/include/arc.archives.class.php
/include/arc.listview.class.php

//自由列表类
/include/arc.freelist.class.php

//分类信息类www.dedebase.com
/include/arc.sgpage.class.php
/include/arc.sglistview.class.php

/专题类专用
/include/arc.specview.class.php

//tag列表类
/include/arc.taglist.class.php

//静态模板引擎类
/include/dedetag.class.php

我们仔细对比一下这个些文件,我们发现是不是系统各模型都使用了这个函数?是的,前台里面的系统模板、单表独立模型、专题、自由列表、标签列表都使用了这个函数,也就是说这个函数应用于所有前台文件中,这样说的话不够准确,因为,会员中心那里有的就用了动态模板引擎,例如,会员空间,准确的说法是,使用绝大多数前台模板解析都用了这了这个函数。可见这个函数的应用之广泛,当然,这个要与静态模板引擎一起使用才可以,否则,它什么也做不了。

网友评论