Skip to content

Instantly share code, notes, and snippets.

@mgng
Created December 10, 2008 08:52
Show Gist options
  • Save mgng/34283 to your computer and use it in GitHub Desktop.
Save mgng/34283 to your computer and use it in GitHub Desktop.
template
<?php
/* Template.php
【前準備】
・Template.php と同階層に template, cache, compile ディレクトリを作成(適切に権限与えとく必要あり)
・以下の内容で template/test.tpl を作成
--------------------
aaaの内容は{aaa}
bbbの内容は{bbb}
--------------------
【簡単な使い方】
require_once 'Template.php';
$data = array('aaa'=>'あああ', 'bbb'=>'いいい');
$file = 'test.tpl';
$tpl = new Template();
$tpl->assign($data);
$tpl->display($file);
*/
class Template
{
const VERSION = '0.1';
private $_templateDir = './template/';
private $_compileDir = './compile/';
private $_cacheDir = './cache/';
private $_data = array();
private $_cached = false;
private $_cacheLifetime = 60;
private $_filemtime = null;
private $_nowTimestamp = null;
private $_buf = null;
private $_cache = null;
private $_lderim = '{';
private $_rderim = '}';
private $_forceCompile = false;
private $_strict = false;
protected function _reservationVars(){
$ld = $this->_lderim;
$rd = $this->_rderim;
return array(
$ld.'#ld#'.$rd => $ld,
$ld.'#rd#'.$rd => $rd
);
}
protected function _reservationFuncs(){
return array(
'h' => 'htmlspecialchars(#VAR#, ENT_QUOTES)',
'nl2br' => 'nl2br(#VAR#)',
'trim' => 'trim(#VAR#)',
'lower' => 'strtolower(#VAR#)',
'upper' => 'strtoupper(#VAR#)',
'count' => 'count(#VAR#)',
'strlen' => 'strlen(#VAR#)',
'mb_strlen' => 'mb_strlen(#VAR#)',
'print_r' => 'print_r(#VAR#, true)'
);
}
protected function _parseSrc($src) {
preg_match_all('/'.preg_quote($this->_lderim).'[\w\.|]+'.preg_quote($this->_rderim).'/', $src, $ms);
if (count($ms[0]) === 0) {
return $src;
}
$src_comp = $src;
foreach($ms[0] as $m) {
$src_comp = str_replace($m, '<?php echo '.$this->_parseMatch($m).'; ?>'.PHP_EOL, $src_comp);
}
$reserveVars = $this->_reservationVars();
$src_comp = str_replace(array_keys($reserveVars), array_values($reserveVars), $src_comp);
$assignData = '<?php $_tpl_data = $this->_data; ?>';
return $assignData . $src_comp;
}
protected function _parseMatch($match) {
$buf = str_replace(array($this->_lderim, $this->_rderim, '.'), array('', '', '\'][\''), $match);
$buf = array_diff(explode('|', trim($buf)), array(''));
$strict = ($this->_strict === true) ? '' : '@';
$rf = $this->_reservationFuncs();
$var = $strict . '$_tpl_data[\'' . array_shift($buf) . '\']';
while(count($buf) > 0) {
$func = array_shift($buf);
if (array_key_exists($func, $rf)) {
$var = str_replace('#VAR#', $var, $rf[$func]);
}
}
return $var;
}
protected function _normalizeDir($dir) {
return (mb_substr($dir, -1, 1) === '/')? $dir : $dir.'/';
}
protected function _getTplFileName($tpl) {
return $this->_templateDir . $tpl;
}
protected function _getCompileFileName($tpl) {
return $this->_compileDir . basename($tpl) . '_' . md5($tpl) . '.php';
}
protected function _getCacheFileName($tpl) {
return $this->_cacheDir . basename($tpl) . '_' . md5($tpl) . '.cache';
}
protected function _writeFile($filePath, $src, $timestamp = null) {
if ( file_put_contents($filePath, $src) === false ) {
return false;
}
$timestamp = ($timestamp === null) ? $this->_nowTimestamp : $timestamp;
return touch($filePath, $timestamp);
}
protected function _getOb($filePath) {
ob_start();
require_once $filePath;
$ob = ob_get_contents();
ob_end_clean();
return $ob;
}
protected function _createCache($tplFile, $buf) {
if ($this->_cached === true) {
$timestamp = $this->_nowTimestamp + $this->_cacheLifetime;
return $this->_writeFile($this->_getCacheFileName($tplFile), $buf, $timestamp);
}
return true;
}
public function __construct() {
$this->_nowTimestamp = mktime();
return true;
}
public function __destruct() {
return true;
}
public function setTemplateDir($dir) {
$this->_templateDir = $this->_normalizeDir($dir);
return $this;
}
public function setCompileDir($dir) {
$this->_compileDir = $this->_normalizeDir($dir);
return $this;
}
public function setCacheDir($dir) {
$this->_cacheDir = $this->_normalizeDir($dir);
return $this;
}
public function setCache($bool) {
$this->_cached = $bool;
return $this;
}
public function setCacheLifetime($lifetime) {
$this->_cacheLifetime = $lifetime;
return $this;
}
public function assign($data = array()) {
$this->_data = $data;
return $this;
}
public function display($tplFile, $echo = true) {
$filePath = $this->_getTplFileName($tplFile);
$src = @file_get_contents($filePath);
if ( $src === false) {
throw new Exception("{$filePath} is not found!");
}
$this->_filemtime = filemtime($filePath);
$compFileName = $this->_getCompileFileName($filePath);
if ( $this->_forceCompile === false && file_exists($compFileName) && $this->_filemtime === filemtime($compFileName) ) {
$this->_buf = $this->_getOb($compFileName);
$this->_createCache($tplFile, $this->_buf);
echo $this->_buf;
return $this;
}
$s = $this->_parseSrc($src);
if( $this->_writeFile($compFileName, $s, $this->_filemtime) === false ) {
throw new Exception("{$compFileName} create error!");
}
$this->_buf = $this->_getOb($compFileName);
$this->_createCache($tplFile, $this->_buf);
if ($echo === true) {
echo $this->_buf;
}
return $this;
}
public function isCached($tplFile) {
$cacheFileName = $this->_getCacheFileName($tplFile);
return (file_exists($cacheFileName) && filemtime($cacheFileName) > $this->_nowTimestamp );
}
public function displayCache($tplFile, $echo = true) {
$this->_cache = $this->_getOb($this->_getCacheFileName($tplFile));
if ($echo === true) {
echo $this->_cache;
}
return $this;
}
public function getBuffer() {
return $this->_buf;
}
public function getCache() {
return $this->_cache;
}
public function forceCompile($bool) {
$this->_forceCompile = $bool;
return $this;
}
public function setStrict($bool) {
$this->_strict = $bool;
return $this;
}
public function getVersion() {
return self::VERSION;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment