は開始コメントが必要ない は終了コメントが必要ない それ以外は開始コメント、終了コメントが必要 書式1 '@replace@'はコメントが外される。キャッシュには残らない 全てのテンプレート内に記述できる 書式2 @eve_contents@ '@eve'内では、内部のテンプレートが@child@のように置換されない。(テンプレートは削除のみ) $eveTemplateReplaceが'true'の場合'@eve'内の最初のテンプレートだけが'@eve@'に置換される 書式3 書式4 'parent'内の'parent--child'は'@child@'に置換される 書式5 'parent'内の全ての'parent--children--child'は(最初の'parent--children--child'が)1つの'@children@'に置換される 【注意】 テンプレート名の[--]はchild、childrenの判別使用される テンプレート名の先頭文字[@]はeveの判別使用される テンプレート名の[header]、[footer]は特別な扱い 【置換形式】 置換は配列で指定 Array(key => value) Array("置換対象文字" => "置換文字"); 【下位互換】 var3.系 => ○ ver2.系 => ◯ ver1系 => × ver0系 => × 【歴史】 3.6 replaceに対応(下位互換) 3.5 eveに対応、複数行のコメント削除、内部処理の全面的改良(下位互換) 3.0 childrenに対応、エンコーディング(下位互換) 2系 childに対応。書式変更に伴い下位互換なし 1系 忘れた。確かオブジェクト指向へ移行 0系 忘れた。確かparentのみ ************************************************************/ class template{ ########## 初期設定 ########## # イブテンプレート内のテンプレートを置換文字で置き換えるか private $eveTemplateReplace = false; # 不要なコメントの削除 true:削除する false:削除しない private $commentDelete = true; ########## プロパティ ########## # キャッシュソース private $source = ""; # テンプレートキャッシュ private $cache = Array(); # 内部エンコード private $internalEncoding = "UTF-8"; # テンプレートエンコーディング private $templateEncoding = "UTF-8"; ########## メソッド ########## # コンストラクター // @param string $file_name // @param string [$encodeTo] default:"" // @param string [$encodeFrom] default:"" public function __construct($file_name, $encodeTo = "", $encodeFrom = ""){ $this->internalEncoding = (empty($encodeTo) === true) ? $this->internalEncoding : $encodeTo; $encodeFrom = (empty($encodeFrom) === true) ? $this->templateEncoding : $encodeFrom; if(is_file($file_name) === true){ $contents = file_get_contents($file_name); $this->source = ($encodeTo = "UTF-8" && $encodeFrom = "UTF-8") ? $contents : mb_convert_encoding($contents, $encodeTo, $encodeFrom); //template parse $this->cache = $this->templateParser($this->source); $templateNames = array_keys($this->cache); //stack array $eveTemplateNames = Array(); $childTemplateNames = Array(); $childrenTemplateNames = Array(); foreach($templateNames as $templateName){ //child and children pattern matching $child_ext = substr_count($templateName, "--"); if($child_ext === 1){ $childTemplateNames[] = $templateName; }elseif($child_ext === 2){ $childrenTemplateNames[] = $templateName; } //eve templates pattern matching if(strpos($templateName, "@") === 0){ $eveTemplateNames[] = $templateName; } } if(count($eveTemplateNames) > 0){ $this->templateEveParser($eveTemplateNames); } if(count($childTemplateNames) > 0){ $this->templateChildParser($childTemplateNames); } if(count($childrenTemplateNames) > 0){ $this->templateChildrenParser($childrenTemplateNames); } if($this->commentDelete === true){ $this->templateCommentDelete(); } } } ##テンプレート出力 // @param string $temp_name // @param array [$replace] key を value で置換する // @return string public function extract($temp_name, $replace = Array()){ if(isset($this->cache[$temp_name])){ if(count($replace) > 0){ return str_replace(array_keys($replace), array_values($replace), $this->cache[$temp_name]); }else{ return $this->cache[$temp_name]; } }else{ return ""; } } ## テンプレートソースの取得 // @return string public function getSource(){ return $this->source; } ## テンプレートキャッシュの取得 // @return string public function getCache(){ return $this->cache; } ## メインノード処理 // @param array $template_source // @return void private function templateParser($template_source){ //replacement template $template_source = preg_replace("/\<\!--\[@([^@]+)@\]--\>/s", "@$1@", $template_source); if(preg_match_all('/\<\!--\[([^\]]+)\]--\>/', $template_source, $item) > 0){ //raw templates $raw_templates = array_unique($item[1]); //return templates $return_templates = Array(); foreach($raw_templates as $temp_name){ //header and footer are especial name. switch($temp_name){ case "header": $pattern = "/(.*)\<\!--\[" . $temp_name . "\]--\>/s"; break; case "footer": $pattern = "/[\s]*\<\!--\[" . $temp_name . "\]--\>(.*)/s"; break; default: $pattern = "/[\s]*\<\!--\[" . $temp_name . "\]--\>(.*)\<\!--\[". $temp_name . "\]--\>/s"; break; } //main pattern matching if(preg_match($pattern, $template_source, $matches) === 1){ $return_templates[$temp_name] = $matches[1]; } } return $return_templates; } } ## イブノード処理 // @param array $eveTemplateNames // @return void private function templateEveParser($eveTemplateNames){ foreach($eveTemplateNames as $eveTemplateName){ $eveInnerTemplateNames = array_keys( $this->templateParser($this->cache[$eveTemplateName]) ); $eveInnerTemplateCount = 0; foreach($eveInnerTemplateNames as $eveInnerTemplateName){ $pattern = "/\<\!--\[" . $eveInnerTemplateName . "\]--\>.*\<\!--\[". $eveInnerTemplateName . "\]--\>/s"; $replacement = ($eveInnerTemplateCount === 0 && $this->eveTemplateReplace === true) ? $eveTemplateName . "@" : ""; $this->cache[$eveTemplateName] = preg_replace($pattern, $replacement, $this->cache[$eveTemplateName]); $eveInnerTemplateCount++; } } } ## childノード処理 // @param array $childTemplateNames // @return void private function templateChildParser($childTemplateNames){ foreach($childTemplateNames as $childTemplateName){ list($parent, $child) = explode("--", $childTemplateName); if(isset($this->cache[$parent])){ $pattern = "/\<\!--\[" . $childTemplateName . "\]--\>.*\<\!--\[". $childTemplateName . "\]--\>/s"; $replacement = "@" . $child . "@"; $this->cache[$parent] = preg_replace($pattern, $replacement, $this->cache[$parent]); } } } ## childrenノード処理 // @param array $childrenTemplateNames // @return void private function templateChildrenParser($childrenTemplateNames){ $stack = Array(); foreach($childrenTemplateNames as $childrenTemplateName){ list($parent, $children, $child) = explode("--", $childrenTemplateName); $group = $parent . "--" . $children; $pattern = "/\<\!--\[" . $childrenTemplateName . "\]--\>.*\<\!--\[". $childrenTemplateName . "\]--\>/s"; if(in_array($group, $stack) === true){ $replacement = ""; }else{ $stack[] = $group; $replacement = "@" . $children . "@"; } if(isset($this->cache[$parent])){ $this->cache[$parent] = preg_replace($pattern, $replacement, $this->cache[$parent]); } } } ## コメントの削除 // @return void private function templateCommentDelete(){ foreach($this->cache as $name => &$template){ while(true){ $start = mb_strpos($template, "", 0, $this->internalEncoding) + 3; if($start !== false && $end !== false){ $template = str_replace(mb_substr($template, $start, $end - $start, $this->internalEncoding), "", $template); }else{ break 1; } } } unset($template); } } ?>