澳门新葡萄京官网首页 2

澳门新葡萄京官网首页深入解析WordPress中加载模板的get

澳门新葡萄京官网首页,最近研究官方主题 Twenty Eleven
,有一些东西网上现成的中文资料不好找,在博客里记载下来,算是分享,也算是备忘,wordpress
3.0 以后就开始便有了get_template_part() 这个函数
,应该是为文章呈现形式提供更为多样化的选择而给出的新功能。

模板引擎其实就是将一个带有自定义标签的字符串,通过相应的规则解析,返回php可以解析的字符串,这其中正则的运用是必不可少的,所以要有一定的正则基础。总体思想,引入按规则写好的模板,传递给标签解析类进行解析,再把解析好的字符串传递给php进行解析渲染输出首先定义了一个_HtmlTag类:

Twenty Eleven 中 实例如下:

class _HtmlTag{ protected $taglist = "if|elseif|else|loop|for|while|=|:=|:e|:html|:"; protected $string; protected $tpldir; function __construct($dir, $tpl) { $this->findReg = "/\{[ ]*($this->findReg)(\s*[\{\}]+\s*)?\}/i"; $this->tpldir = $dir; $this->tpl =$tpl; }}

Twenty Eleven index.php 文件
 行:21

  • 先解析下render方法
  • 在render方法中对传入的字符串$s,进行相应的替换渲染,用到了extends方法,import方法,’‘开头的各种过滤方法,后面会一一进行详解.
<?php if ( have_posts() ) : ?>
 <?php twentyeleven_content_nav( 'nav-above' ); ?>
 <?php /* Start the Loop 在循环中使用以调用不同类型的文章 */ ?>
 <?php while ( have_posts() ) : the_post(); ?>
 <?php get_template_part( 'content', get_post_format() ); ?>
 <?php endwhile; ?>
............................
<?php endif; ?>

描述:
加载一个制定的模板到另一个模板里面(不同于包含header,sidebar,footer).
使得一个主题使用子模板来实现代码段重用变得简单

function render { $s = str_replace(['<--{', '}-->'], ['{','}'], $s); if (strpos($s, "{extends") !== false) { $s = $this->_extends; } $s = preg_replace('/[\n\r]+/s', "\n", $s); $s = preg_replace('/\r+/s', "", $s); $s = preg_replace('/\t+/s', "\t", $s); $this->string = str_replace(["\{", "\}"], ["\HKH1", "\HKH2"], $s); preg_match_all("/\{[ ]*(\s*[^\{\}]+\s*)?\}/i", $s, $d); foreach($d[0] as $k => $v) { call_user_func_array(array($this, "_import"), array($v, $d[1][$k], $d[2][$k])); } static $m = array("=" => "_defaultEcho", ":=" =>" _xssEcho", ":e" => "_htmlencodeEcho", ":" => "_echo", ":html" => "_htmldecodeEcho"); preg_match_all($this->findReg, $this->string, $d); foreach ($d[0] as $k => $v) { if (isset($m[$d[1][$k]])) { $medth = $m[$d[1][$k]]; } else { $medth = '_' . $d[1][$k]; } call_user_func_array(array($this, $medth), array($v, $d[1][$k], $d[2][$k])); }}

用于在模板中包含指定的模板文件,只需用指定参数slug和name就可以包含文件{slug}-{name}.php,最重要的功能是如果没有这个文件就包含没有{name}的.php文件文件

  • _extends方法
  • 使用 个方法是为了判断是否有继承相应的模板文件,在子文件中用{extends
    模板名},一般只要填写文件名,如index,系统会自动去构造完整的文件路径,一般在上一级目录,这个在realTpl()方法时会有详解

使用方法:

<?php get_template_part( $slug, $name ) ?>
function _extends { preg_match("/\{\s*extends\s+([^\{\}]+?)\s*\}/i", $tpl, $d); list($search, $arg) = $d; if (stripos($arg, ".") !==0 ) { $arg = '../' . $arg; } $file = $this->tpl->me->realTpl($arg . ".htm"); $basetpl = file_get_contents; preg_match_all("/\{block\s+([^\{\}]+?)\s*\}\{\/block\}/s", $tpl, $ds); foreach($ds[1] as $n => $name) { $basetpl = preg_replace("/\{block\s+name={$name}\s*\}/", $ds[2][$n], $basetpl); } $basetpl = preg_replace("/\{block\s+name=.+?\}/", ' ', $basetpl); return $basetpl;}

参数:

  • _import 方法
  • _import 方法是用来对{import
    文件名}标签进行解析,默认也是上层目录,会把该文件的内容解析到当前标签位置,同时支持使用:函数名|参数1,
    参数2,…的方式进行字符串的回调.这中的display方法后面会有详解
  • $slug (必须) 通用的模板名

  • $name (可选) 指定的模板名

示例:

function _import ($search, $tag, $arg) { $arg = trim; if (stripos($arg, ".") !== 0) { $arg = '../' . $arg; } $file = $this->tpl->me->realTpl($arg . ".htm"); if (file_exists { $this->string = str_replace($search, file_get_contents, $this->string); return; } else { if (stripos($file, "$") !== false) { $this->string = str_replace($search, '<? include $this->tpl->display("' . $arg . '"); ?>', $this->string); return; } if (stripos($arg, '|') !== false) { list($func, $tmp) = explode("|", trim; $kw = explode(', ', $tmp); } else { $func = trim; $kw = array(); } if (function_exists { $tpl_str = call_user_func_array($func, $kw); $this->string = str_replace($search, $tpl_str, $this->string); return; } else { $this->string = str_replace($search, $arg, $this->string); return; } system_error($this->tpldir . trim . ".htm不存在"); }}

使用 loop.php 在子主题里面

  • 现在来看一个标签函数_loop,将标签{loop $data $k $v}或{loop $data
    $v}替换,实现模板循环,其中的parseAttr方法接下来将详解

假设主题文件夹wp-content/themes下父主题是twentyten子主题twentytenchild,那么下面的代码:

<?php get_template_part( 'loop', 'index' ); ?>
function _loop($search, $tag, $arg) { list($attr, $arg) = $this->parseAttr; $d = preg_split("/\s+/", trim; if  == 3) { $data = $d[0]; $k = $d[1]; $v = $d[2]; $s = "<? \n if(!empty {\n \t foreach(" . $data . " as {$k} => {$v}){"; } elseif  == 2) { $data = $d[0]; $v = $d[1]; $s = "<? \n if(!empty{\n \t foreach(". $datsa . " as {$v}) {"; } if (isset($attr['counter'])) { $s = "\n \t\t<? if (!isset({$attr['counter']})) { {$attr['counter']} = 0;} ?> \n \t\t" . $s . "\n \t\t{$attr['counter']}++; \n ?>; } else { $s .= "?>"; } $this->string = str_replace($search, $s, $this->string); $this->string = str_replace("{/loop}", "<? \t}\n}?>", $this->string);}

php 的require()函数将按下面优先级包含文件

– parseAttr方法

该方法用来解析标签
的参数,返回的第一个参数是值形式字符串,第二个是键值数组,如{loop $data
$k $v}返回$data $k $v 组成 的字符串和一个空数组,{if $k =
$v}则返回空字符串和和数组[$k => $v];

function parseAttr { $reg = '/([a-zA-Z0-9_])+\s*=\s*([a-zA-Z0-9_\$]+)/i'; $arg = preg_replace($reg, '', $s); preg_match_all($reg, $s, $d); $arr = array(); foreach($d[1] as $key => $value) { $arr[trim] = trim($d[2][$key]); } return array($arr, $arg);}
  • _if 方法
  • 将{if}{/if}标签解析成原生 的php,简单明了,不多解释

function _if ($search, $tag, $arg) { $replace[0] = "<? if{?>"; $replace[1] = "<? }?>"; $this->string = str_replace(array($search, "{/$tag}"), $replace, $this->string);}
  • _else方法将{else}解析成原生的php

function _else($search, $tag, $arg) { $this->string = str_replace("{else}", "\n" . '<? } else {?>', $this->string);}
  • _elseif方法将{elseif}解析成原生的php

function _elseif($search, $tag, $arg) { $this->string = str_replace($search, "<? }elseif{?>", $this->string);}
  • _for 方法

function _for($search, $tag, $arg) { $s = trim(trim(preg_replace('/\s+/', ' ; ', $arg)), ';'); $this->string = str_replace($search, "<? for{?>", $this->string); $this->string = str_replace("{/for}", "<? \t\n}?>", $this->string);}
  • _while方法

function _while($search, $tag, $arg) { $this->string = str_replace($search , "<? while{ ?>", $this->string); $this->string = str_replace("{/while}", "<? \t\n} ?>", $this->string);}
  • _end方法通过这个方法对其$this->string进行修改可以对变量进行如下标签定义:{$val}{$arr[$key]}{$arr[‘key’]}{:val()}{$arr.key}{$arr.$key}

function _end() { //{$val}标签解析 $this->string = preg_replace('/\{(\$\w+.*)\}/is', "<?=\\1;?>", $this->string); //{:$val()}标签解析 $this->string = preg_replace('/\{\:\s*(\$?\w+.*?)\}/is', "<? =\\1;?>", $this->string); //将$val[arg]解析成$val['arg'] $this->string = preg_replace('/\$([_a-z]+\w*)\[([_a-z]+\w*)\]/is', "$\\1['\\2']", $this->string); //支持点号访问数组。如array['key']可以用array.key访问 $this->string = preg_replace('/\$([_a-z]+\w*)\.(\$[_a-z]+\w*)/is', "$\\1[\\2]", $this->string); $this->string = preg_replace('/\$([_a-z]+\w*)\.([_a-z]+\w*)/is', "$\\1['\\2']", $this->string); $this->string = preg_replace(array("/<?/", "/<?phps*=/"), array("<?php ", "<?php echo "), $this->string);}
  • _result方法,做最后处理,返回字符串,_end方法在上面已经解释过了

function result() { $this->_end(); $this->_baseParse($this->stirng); return str_replace(array("\HKH1", "\HKH2"), array("\{", "\}"), $this->string);}
  • _htmlencodeEcho方法
  • 可以用此种形式对变量进行htmlspecialchars式的过滤spspecialchars函数后面会有介绍{:e
    $val}

function _htmlencodeEcho($search, $tag, $arg) { if (stripos($arg, '$')) { $this->string = str_replace($search, "<? echo sphtmlspecialchars(!empty?$arg:''))?>", $this->string); } else { $this->string = str_replace($search, "<? echo sphtmlspecialchars?>", $this->string); }}
  • _htmldecodeEcho方法

_htmldecodeEcho($search, $tag, $arg) { if (stripos($arg, '$')) { $this->string = str_replace($search, "<? echo htmlspecialchars_decode(!empty?$arg:'')?>", $this->string); } else { $this->string = str_replace($search, "<? echo htmlspecialchars_decode?>", $this->string); }}
  • _defaultEcho方法

function _defaultEcho($search, $tag, $arg) { if (stripos($arg, ',') == false) { $arg . = ", ' ' "; list($v, $default) = explode(",", $arg); $this->string = str_replace($search, "<? echo empty?$default:$v; ?>", $this->string); }}
  • _xssEcho方法

_xssEcho($search, $tag, $arg) { $this->string = str_replace($search, "<? echo xssRemove; ?>", $this->string);}

_echo方法

function _echo($search, $tag, $arg){ $this->string = str_replace($search, "<? echo $arg;?>", $this->string);}
  • _baseParse方法,这个对css和js的引入进行处理

function _baseParse { if (strpos($s, "{loadCss") !== false) { $s = $this->_loadCss; } if (strpos($s, "{loadJs") !== false) { $s = $this->_loadJs; } return $s;}
  • _loadJs方法

function _loadJs { preg_match_all('/{loadJss+([^{}]+?)s*}/i', $tpl, $match); include "jsmin.php"; foreach($match[1] as $k => $js) { $jsstr = ""; $cdn = ""; $if (stripos !== false) { $filename = ""; $md5 = ""; $js_content = ""; foreach(explode as $j) { $filename .= basename($j, '.js') . ','; $md5 .= self::fileMd5; if (stripos($j, '.min.') == false) { $js_content .= JSMin::minify(file_get_contents(WEB_ROOT . $j)); } else { $js_content .= file_get_contents(WEB_ROOT . $j); } $js_content .= ';' } $md5 = md5; $filename = dirname . '/' .trim($filename, ',') . '.js'; self::parseJs($js_content, $filename); $jsstr = "<script src="{$cdn}{$filename}?v={$md5}"></script>"; } else { $md5 = self::fileMd5; if (stripos($js, ".min.") === false) { $js = self::pareJs(JSMin::minify(file_get_contents(WEB_ROOT . $js)), dirname. '/' .basename($js, '.js') . '.min.js'); } $jsstr = "<script src="{$cdn}{$js}?v={$mdt}"></script>"; } $tpl = str_replace($match[0][$k], $jsstr, $tpl); } return $tpl;}

_loadCss方法

function _loadCss { preg_match_all('/{loadCsss+s*}/i' , $tpl , $match); $cdn = ""; foreach($match[1] as $k => $css) { $cssstr = ""; if (stripos($css, ',') !== false) { $filename = ""; $md5 = ""; $css_content = ""; foreach($explode(',', $css) as $css) { $filename .= basename($css, '.css') . ','; $md5 = self::fileMd5; $css_content .= file_get_contents(WEB_ROOT .$css); } $md5 = md5; $filename = dirname . '/' .trim($filename, ',') . '.css'; self::parseCss($css_content, $filename); $cssstr = "<link rel="stylesheet" href="{$cdn}{$filename}?v={md5}">"; } else { $md5 = self::fileMd5; if (stripos($css, ".min.") == false) { $css = self::parseCss(file_get_contents(WEB_ROOT . $css), dirname . '/' .basename($css, '.css') . '.min.css'); } $cssstr .= "<link rel="stylesheet" href="{$cdn}{$css}?v={$md5}">"; } $tpl = str_replace($match[0][$k], $cssstr, $tpl); } return $tpl;}
  • 上面两个函数都用到了各自的parseCss,和parseJs,让我们来看下

static function parseCss($css_content, $filename) { $css_content = preg_replace("/[rnt]/", '', $css_content); $css_content = preg_replace("/ +/", ' ', $css_content); sp_file_pu_contents(WEB_ROOT . $filename, $css_content); return $filename;}static function parseJs($js, $filename) { sp_file_put_content(WEB_ROOT . $filename, $js); return $filename;}

上面的_html类和他的方法对传入的字符串进行了标签到原生
Php的替换,可以传入相应的模板,也可以在其中自定义自己的过滤方法。

下面我们再来看一个template类:

  1. wp-content/themes/twentytenchild/loop-index.php
  2. wp-content/themes/twentytenchild/loop.php
  3. wp-content/themes/twentyten/loop-index.php
  4. wp-content/themes/twentyten/loop.php

– 定义这个类来对模板进行管理,这里会用到上面的_html类,基本定义如下,接下来会介绍其中的一些方法

class template { private $tpl_cache_dir; public $ext = ".htm"; public $default_tpl_dir = false; public $me; function _construct($tpl_cache_dir, $me) { $this->sets($tpl_cache_dir); $this->me = $me; } function sets($tpl_cache_dir) { $this->tpl_cache_dir = $tpl_cache_dir; if (SP_DEBUG == 1) { spmkdir($this->tpl_cache_dir); } } function default_template { $this->default_tpl_dir = $dir; }}

导航(这个例子很烂,但却是另一种使用思路)
使用通用的nav.php文件给主题添加导航条:

– getString方法

在之前 开启ob_start(),然后获取这之间的ob数据,试用于框架中

function getString() { $s = ob_get_contents(); ob_clean(); return $s;}
  • display方法

function display($tpl, $return = 0, $script = SCRIPT) { $tpl .= $this->ext; $tpl_name = $this->tpl_cache_dir . $script . '_' . str_replace(['/', '\\'], '_', $tpl); if { if (SP_DEBUG == 1 || (SP_DEBUG == 2 && !file_exists($tpl_name))) { $this->compiles($tpl_name, $tpl); } } return $tpl_name;}
  • compiles方法, 在这里使用了sp_file_put_contentsb函数会在后面介绍

function compiles($cache_name, $tpl) { if (!file_exists { if (file_exists($this->default_tpl_dir . $tpl)) { $html = file_get_contents($this->default_tpl_dir . $tpl); } else { spmkdir(dirname, '777'); file_get_contents($tpl, 这个是自动生成模板'); } } else { $html = file_get_contents; } $tag = new _HtmlTag(realpath(dirname . '/../'), $this); $tag->render; $html = preg_replace_callback('//s', array(&$this, "make_magic_func"), $tag->result; $html = preg_replace('/[\n\r]{1,}/s', "\n", $html); @unlink($cache_name); sp_file_put_contents($cache_name, $thml);}
  • make_magic_func方法

function make_magic_func { preg_match_all=\s*?\2/m', $d[2], $dd); $aa = array(); foreach($dd[1] as $i => $k) { $vs = preg_replace('/([^\-]*[<>]{1,1})\s*?\s*/', '\1\'\2\' ', $dd[3][$i]); $vs = preg_replace('/=\s*?\s*/', '=\'\1\'', $dd[3][$i]); if (stripos($d[3][$i], '$') !== false) { $vs = preg_replace('/\$\s*/', '{$\1}', $vs); } }}

注意

  • 两个类的相应方法都
    定义好了,这其中用到的函数sp_file_pu_contents($file, $data)

function sp_file_put_contents($file, $data) { $dir = dirname; if (is_writeable { return file_put_contents($file, $data); } else { throw new writeFail(sprintf("写入文件%s,失败,目录不可写", $file), 503); }}

js压缩类: jsmin.class.php链接:
密码:y5jb将这两个 类定义在一个文件中,使用进进行相应的配置

define("WEB_ROOT", dirname . '/');

使用

  • 文件准备base.htm,main.htm,test.js,test1.js,test.css,test1.css,indx.php,im.htm

  • main.htm:

{import ./im}{block name=head}{block name=body}{block name=foot}
  • base.htm

{extends ./main}{block head}{loadCss test.css,test1.css}{loop $data $k $v}<p>我是头部</p>{/loop}{if $bb == 'aa'}<p>我是if 测试</p>{elseif $bb = 'bb'}<p>我是elesif测试</p>{else}<p>我是eles测试</p>{/if}{for $i=0 $i<10 $i++}<p>我是for循环</p>{/for}{while $con >5}<? $con--;?><p>我是while循环</p>{/while}{/block}{block foot}<p>我是尾部</p>{loadJs test1.js,test.js}{/block}
  • im.htm

我是import进来的
  • index.php

<?phpdefine('WEB_ROOT',dirname . '/');function sp_file_put_contents($file, $data) { $dir = dirname; if (is_writeable { return file_put_contents($file, $data); } else { throw new writeFail(sprintf("写入文件%s,失败,目录不可写", $file), 503); }}class _HtmlTag{ protected $taglist = "if|elseif|else|loop|for|while|=|:=|:e|:html|:"; protected $string; protected $tpldir; public $findReg; function __construct($dir, $tpl) { $this->findReg = "/{[ ]*($this->taglist)(s*[^{}]+s*)?}/i"; $this->tpldir = $dir; $this->tpl =$tpl; } function render { $s = str_replace(['<--{', '}-->'], ['{','}'], $s); if (strpos($s, "{extends") !== false) { $s = $this->_extends; } $s = preg_replace('/[nr]+/s', "n", $s); $s = preg_replace('/r+/s', "", $s); $s = preg_replace('/t+/s', "t", $s); $this->string = str_replace(["{", "}"], ["HKH1", "HKH2"], $s); preg_match_all("/{[ ]*(s*[^{}]+s*)?}/i", $s, $d); foreach($d[0] as $k => $v) { call_user_func_array(array($this, "_import"), array($v, $d[1][$k], $d[2][$k])); } static $m = array("=" => "_defaultEcho", ":=" =>" _xssEcho", ":e" => "_htmlencodeEcho", ":" => "_echo", ":html" => "_htmldecodeEcho"); preg_match_all($this->findReg, $this->string, $d); foreach ($d[0] as $k => $v) { if (isset($m[$d[1][$k]])) { $medth = $m[$d[1][$k]]; } else { $medth = '_' . $d[1][$k]; } call_user_func_array(array($this, $medth), array($v, $d[1][$k], $d[2][$k])); } } function _extends { preg_match("/{s*extendss+([^{}]+?)s*}/i", $tpl, $d); list($search, $arg) = $d; if (stripos($arg, ".") !==0 ) { $arg = '../' . $arg; } //$file = $this->tpl->me->realTpl($arg . ".htm"); $file = $arg . ".htm"; $basetpl = file_get_contents; preg_match_all("/{blocks+([^{}]+?)s*}{/block}/s", $tpl, $ds); foreach($ds[1] as $n => $name) { $basetpl = preg_replace("/{blocks+name={$name}s*}/", $ds[2][$n], $basetpl); } $basetpl = preg_replace("/{blocks+name=.+?}/", ' ', $basetpl); return $basetpl; } function _import ($search, $tag, $arg) { $arg = trim; if (stripos($arg, ".") !== 0) { $arg = '../' . $arg; } //$file = $this->tpl->me->realTpl($arg . ".htm"); $file = $arg . ".htm"; if (file_exists { $this->string = str_replace($search, file_get_contents, $this->string); return; } else { if (stripos($file, "$") !== false) { $this->string = str_replace($search, '<? include $this->tpl->display("' . $arg . '"); ?>', $this->string); return; } if (stripos($arg, '|') !== false) { list($func, $tmp) = explode("|", trim; $kw = explode(', ', $tmp); } else { $func = trim; $kw = array(); } if (function_exists { $tpl_str = call_user_func_array($func, $kw); $this->string = str_replace($search, $tpl_str, $this->string); return; } else { $this->string = str_replace($search, $arg, $this->string); return; } system_error($this->tpldir . trim . ".htm不存在"); } } function mytest(){ return $this->string; } function _baseParse { if (strpos($s, "{loadCss") !== false) { $s = $this->_loadCss; } if (strpos($s, "{loadJs") !== false) { $s = $this->_loadJs; } return $s; } function fileMd5 { if (stripos($f, "http://") !== false) { return md5; } return md5_file(WEB_ROOT . $f); } function _loadCss { preg_match_all('/{loadCsss+s*}/i' , $tpl , $match); $cdn = ""; foreach($match[1] as $k => $css) { $cssstr = ""; if (stripos($css, ',') !== false) { $filename = ""; $md5 = ""; $css_content = ""; foreach(explode(',', $css) as $css) { $filename .= basename($css, '.css') . ','; $md5 = self::fileMd5; $css_content .= file_get_contents(WEB_ROOT .$css); } $md5 = md5; $filename = dirname . '/' . trim($filename, ',') . '.css'; self::parseCss($css_content, $filename); $cssstr = "<link rel="stylesheet" href="{$cdn}{$filename}?v={$md5}">"; } else { $md5 = self::fileMd5; if (stripos($css, ".min.") == false) { $css = self::parseCss(file_get_contents(WEB_ROOT . $css), dirname . '/' .basename($css, '.css') . '.min.css'); } $cssstr .= "<link rel="stylesheet" href="{$cdn}{$css}?v={$md5}">"; } $tpl = str_replace($match[0][$k], $cssstr, $tpl); } return $tpl; } function _loadJs { preg_match_all('/{loadJss+([^{}]+?)s*}/i', $tpl, $match); //var_dump;die; include "jsmin.class.php"; foreach($match[1] as $k => $js) { $jsstr = ""; $cdn = ""; if (stripos !== false) { $filename = ""; $md5 = ""; $js_content = ""; foreach(explode as $j) { $filename .= basename($j, '.js') . ','; $md5 .= self::fileMd5; if (stripos($j, '.min.') === false) { $js_content .= JSMin::minify(file_get_contents(WEB_ROOT . $j)); } else { $js_content .= file_get_contents(WEB_ROOT . $j); } $js_content .= ';'; } $md5 = md5; $filename = dirname . '/' .trim($filename, ',') . '.js'; self::parseJs($js_content, $filename); $jsstr = "<script src="{$cdn}{$filename}?v={$md5}"></script>"; } else { $md5 = self::fileMd5; if (stripos($js, ".min.") === false) { $js = self::pareJs(JSMin::minify(file_get_contents(WEB_ROOT . $js)), dirname. '/' .basename($js, '.js') . '.min.js'); } $jsstr = "<script src="{$cdn}{$js}?v={$mdt}"></script>"; } $tpl = str_replace($match[0][$k], $jsstr, $tpl); } return $tpl; } static function parseCss($css_content, $filenme) { $css_content = preg_replace("/[rnt]/", '', $css_content); $css_content = preg_replace("/ +/", ' ', $css_content); // echo WEB_ROOT . $filenme; sp_file_put_contents(WEB_ROOT . $filenme, $css_content); return $filenme; } static function parseJs($js, $filenme) { sp_file_put_contents(WEB_ROOT . $filenme, $js); return $filenme; } function _loop($search, $tag, $arg) { list($attr, $arg) = $this->parseAttr; $d = preg_split("/s+/", trim; if  == 3) { $data = $d[0]; $k = $d[1]; $v = $d[2]; $s = "<? n if(!empty {n t foreach(" . $data . " as {$k} => {$v}){"; } elseif  == 2) { $data = $d[0]; $v = $d[1]; $s = "<? n if(!empty{n t foreach(". $datsa . " as {$v}) {"; } if (isset($attr['counter'])) { $s = "ntt <? if (!isset({$attr['counter']})) { {$attr['counter']} = 0;} ?> n tt" . $s . "n tt{$attr['counter']}++; n ?>"; } else { $s .= "?>"; } $this->string = str_replace($search, $s, $this->string); $this->string = str_replace("{/loop}", "<? t}n}?>", $this->string); } function parseAttr { $reg = '/([a-zA-Z0-9_])+s*=s*([a-zA-Z0-9_$]+)/i'; $arg = preg_replace($reg, '', $s); preg_match_all($reg, $s, $d); $arr = array(); foreach($d[1] as $key => $value) { $arr[trim] = trim($d[2][$key]); } return array($arr, $arg); } function _if ($search, $tag, $arg) { $replace[0] = "<? if{?>"; $replace[1] = "<? }?>"; $this->string = str_replace(array($search, "{/$tag}"), $replace, $this->string); } function _else($search, $tag, $arg) { $this->string = str_replace("{else}", "n" . '<? } else {?>', $this->string); } function _elseif($search, $tag, $arg) { $this->string = str_replace($search, "<? }elseif{?>", $this->string); } function _for($search, $tag, $arg) { $s = trim(trim(preg_replace('/s+/', ' ; ', $arg)), ';'); $this->string = str_replace($search, "<? for{?>", $this->string); $this->string = str_replace("{/for}", "<? tn}?>", $this->string); } function _while($search, $tag, $arg) { $this->string = str_replace($search , "<? while{ ?>", $this->string); $this->string = str_replace("{/while}", "<? tn} ?>", $this->string); } function _end() { //{$val}标签解析 $this->string = preg_replace('/\{(\$\w+.*)\}/is', "<?=\\1;?>", $this->string); //{:$val()}标签解析 $this->string = preg_replace('/\{\:\s*(\$?\w+.*?)\}/is', "<? =\\1;?>", $this->string); //将$val[arg]解析成$val['arg'] $this->string = preg_replace('/\$([_a-z]+\w*)\[([_a-z]+\w*)\]/is', "$\\1['\\2']", $this->string); //支持点号访问数组。如array['key']可以用array.key访问 $this->string = preg_replace('/\$([_a-z]+\w*)\.(\$[_a-z]+\w*)/is', "$\\1[\\2]", $this->string); $this->string = preg_replace('/\$([_a-z]+\w*)\.([_a-z]+\w*)/is', "$\\1['\\2']", $this->string); $this->sring = preg_replace(array("/<?/", "/<?phps*=/"), array("<?php ", "<?php echo "), $this->string); } function result() { $this->_end(); $this->string = $this->_baseParse($this->string); return str_replace(array("\HKH1", "\HKH2"), array("\{", "\}"), $this->string); }}$data = ['aa','bb','cc'];$bb = 'aa';$con = 11;$tag = new _HtmlTag('./index', '');$str = file_get_contents('base.htm');$tag->render;$html = $tag->result();var_dump;echo '</br>----------------------------</br>';sp_file_put_contents("./index.html", $html);include "index.html";
  • 运行index.php查看结果

    澳门新葡萄京官网首页 1Paste_Image.png澳门新葡萄京官网首页 2Paste_Image.png

我们来总结一下这个类的使用过程,先实例话template类,调用template::display()方法,其中会调用template::compiles()方法,这个方法会实例化_HhtmlTag类,调用_HtmlTag::render方法,在这个方法里,对传入的带字符串进行一个结构的完整化,包括调用_HtmlTag::_extends,_HtmlTag::_import,_HtmlTag::_loop,_HtmlTag::_if,_HtmlTag::elseif,_HtmlTag::else,_HtmlTag::_for,_HtmlTag::while接着调用_HtmlTag::result方法,里面调用_HtmlTag::_end方法对变量进行php原生化和_HtmlTag::_baseParse()引入css和js,最后返回解析好的完整模板字符串。

<?php get_template_part( 'nav' );      // Navigation bar (nav.php) ?>
<?php get_template_part( 'nav', '2' );   // Navigation bar #2 (nav-2.php) ?>
<?php get_template_part( 'nav', 'single' ); // Navigation bar to use in single pages (nav-single.php) ?>

get_template_part() 的钩子详解 因为在官方主题(Twenty Eleven)中 get_template_part()
函数被大量使用,所以就目前来看,该函数应该算是比较热门的一个函数了,之前有写过一篇文章讲述该函数的具体使用方法,在这里也就不便再赘述,本文主要针对该函数的
add_action 中的 hook $tag 值进行探讨,因为,WP hook
中林林总总有那么些函数在$tag 值中比较让人费解。

与普通hook的区别
普通的hook的$tag 是一个固定值,而 get_template_part()
确是一个可变值,好吧先不说,wp这么做给我们实现一个简单功能带来多少麻烦,但如此设置确实给多样化的主题实现带来了不少方便之处。
实现这一原理的源代码如下,截取自 WordPress 源程序。

 function get_template_part( $slug, $name = null ) {
//$tag = "get_template_part_{$slug}" 
//也就是,get_template_part_+你当时设置的$slug值
 do_action( "get_template_part_{$slug}", $slug, $name );
 $templates = array();
 if ( isset($name) )
  $templates[] = "{$slug}-{$name}.php";
  $templates[] = "{$slug}.php";
  locate_template($templates, true, false);
}

实例
像上面那样说,可能也许基本上有点看不明白,好吧给点实例

 

//复习一下get_template_part($slug, $name)的用法,
//如果你在主题里这样
get_template_part( 'index' , 'photo');
//那么 WP 会去找主题根目录下 index-photo.php 文件
 
//那么我们想挂一个函数的话就得像如下
function addFunction ($slug, $name){
echo $slug;
}
add_action("get_template_part_index","addFunction",10,2);

get_template_part() 函数详解备忘

发表评论

电子邮件地址不会被公开。 必填项已用*标注