这里会过头再看一下tag是如何取得模板内容的。由此也分析一下 常用的一些函数。
比如调用
tag('view_template',$templateFile);
tag函数头几行 就调用了C函数
// 系统标签扩展
$extends = C('extends.' . $tag);
// 应用标签扩展
$tags = C('tags.' . $tag);
先来看下C函数。作者的解释是获取配置值。优先设置这个值。
function C($name=null, $value=null) {
/*
创建了一个静态的_config.因为是static的,所以会一直存在。
*/
static $_config = array();
// 无参数时获取所有 没有参数的时候返回所有的配置 应该是一个数组
if (empty($name)) return $_config;
// 优先执行设置获取或赋值 是字符串 进入下面的函数
if (is_string($name)) {
/*
看名字里面是不是有点分隔符。如果没有的话。就是通过两个参数 name value设置
*/
if (!strpos($name, '.')) {
$name = strtolower($name);
if (is_null($value)){
return isset($_config[$name]) ? $_config[$name] : null;
}
$_config[$name] = $value;
return;
}
/*
如果有点的话。那么是二维数组。通过 点前面是一级 点后面是二级
比如 extends.template
那么就是操作 _config['extends']['template']
*/
// 二维数组设置和获取支持
$name = explode('.', $name);
$name[0] = strtolower($name[0]);
if (is_null($value))
return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
$_config[$name[0]][$name[1]] = $value;
return;
}
// 批量设置
/*
如果传入的name是数组的话。那么就批量设置,和以前的一起合并。
*/
if (is_array($name)){
return $_config = array_merge($_config, array_change_key_case($name));
}
return null; // 避免非法参数
}
回到 tags 里面
分别获取了extends和tags标签以后。
如果tags不为空。 判断如果extends也不为NULL,那么合并成一个tags
( _overlay 这里暂时不解析 )
如果tags为NULL extends不是NULL 。那么把extends赋值给tags。
如果两个都为NULL。没啥好说的返回false
然后对于tags里面的内容 循环执行B函数
foreach ($tags as $key=>$name) {
if(!is_int($key)) { // 指定行为类的完整路径 用于模式扩展
$name = $key;
}
B($name, $params);
}
前面通过view_template找到了tags
应该是 0 LocationTemplate
B就是behavior执行这个行为。所以这里就是执行LocationTemplate的行为。
调用LocationTemplateBehavior .就是 LocationTemplateBehavior.class.php 并且运行它的run方法
function B($name, &$params=NULL) {
$class = $name.'Behavior';
G('behaviorStart');
$behavior = new $class();
$behavior->run($params);
if(APP_DEBUG) { // 记录行为的执行日志
G('behaviorEnd');
Log::record('Run '.$name.' Behavior [ RunTime:'.G('behaviorStart','behaviorEnd',6).'s ]',Log::INFO);
}
}
接着去LocationTemplateBehavior 里面看看run方法
public function run(&$templateFile){
// 自动定位模板文件
if(!file_exists_case($templateFile))
$templateFile = $this->parseTemplateFile($templateFile);
}
由于此时$templateFile还是NULL。所以会执行 parseTemplateFile方法
private function parseTemplateFile($templateFile) {
if(''==$templateFile) {
// 如果模板文件名为空 按照默认规则定位
//由于我们的名字为NULL。所以按照默认的规则定位模板。找TEMPLATE_NAME
$templateFile = C('TEMPLATE_NAME');
}elseif(false === strpos($templateFile,C('TMPL_TEMPLATE_SUFFIX'))){
// 解析规则为 模板主题:模块:操作 不支持 跨项目和跨分组调用
$path = explode(':',$templateFile);
$action = array_pop($path);
$module = !empty($path)?array_pop($path):MODULE_NAME;
if(!empty($path)) {// 设置模板主题
$path = dirname(THEME_PATH).'/'.array_pop($path).'/';
}else{
$path = THEME_PATH;
}
$depr = defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/';
$templateFile = $path.$module.$depr.$action.C('TMPL_TEMPLATE_SUFFIX');
}
if(!file_exists_case($templateFile))
throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']');
return $templateFile;
}
其实这个 TEMPLATE_NAME App.init里面定义的。
C('TEMPLATE_NAME',THEME_PATH.MODULE_NAME.(defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/').ACTION_NAME.C('TMPL_TEMPLATE_SUFFIX'));
在前面我们打印一下这个,在init里面
mlog("TEMPLATE_NAME ".C(TEMPLATE_NAME));
./App/Tpl/Admin/Default/Public/adminindex.html
这样就找到了这个模板文件