Table of contents


ec的範本機制感覺和smarty的類似,算是一個簡易的smarty把

每個程式頁面都有如下類似的語句

$cache_id = sprintf('%X', crc32($_SESSION['user_rank'] . '-' . $_CFG['lang']))   

緩存id,現在是通過使用者等級和語言緩存不同頁面(通過這裡應該可以做網店多語種的實現)

if (!$smarty->is_cached('index.dwt', $cache_id))
 
{          判斷頁面是否已經緩存,如果沒有則做變數賦值和範本裡面動態內容提取
 
           assign_template();  
 
           $smarty->assign(變數名,  變數值);
 
            。。。
 
}
 
$smarty->display('index.dwt', $cache_id);    顯示生成的頁面
 
 
 
頁面的範本機制都是通過cls_template.php檔實現,下面通過display函數開始進入分析,裡面只有關鍵地方的解釋,其他的可以自己去看代碼
 
    function display($filename, $cache_id = '')
 
    {
 
        。。。
 
        $out = $this->fetch($filename, $cache_id);    //這裡是處理範本的關鍵函數
 
        if (strpos($out, $this->_echash) !== false)     //頁面動態內容的顯示,如投票,購物車之類的,看了下面的就知道了
 
        {
 
            $k = explode($this->_echash, $out);
 
            foreach ($k AS $key => $val)
 
            {
 
                if (($key % 2) == 1)
 
                {
 
                    $k[$key] = $this->insert_mod($val);   //取到動態內容並賦值
 
                }
 
            }
 
            $out = implode('', $k);
 
        }
 
        。。。
 
    }
 
 
 
 
 
    function fetch($filename, $cache_id = '')
 
    {
 
       。。。
 
        if (strncmp($filename,'str:', 4) == 0)  此處處理字串範本,如郵件範本
 
        {
 
            。。。
 
        }
 
        else
 
        {
 
           。。。
 
            if ($this->direct_output)      
 
            {
 
               。。。
 
            }
 
            else
 
            {
 
                if ($cache_id && $this->caching)     //如果已經緩存就直接取緩存資料
 
                {
 
                    $out = $this->template_out;
 
                }
 
                else
 
                {
 
                       $out = $this->make_compiled($filename);     //編譯範本函數,關鍵函數
 
                    if ($cache_id)        //如果緩存id不為空則寫快取檔案
 
                    {
 
                               。。。一些緩存資料,如緩存有效期之類的
 
                    }
 
                }
 
            }
 
        }
 
      。。。
 
    }
 
 
 
 
 
 
 
    function make_compiled($filename)
 
    {
 
      。。。。這裡省略一部分都是判斷檔是否有效,是否過期,是否強制編譯之類的
 
        if ($this->force_compile || $filestat['mtime'] > $expires)
 
        {
 
            $this->_current_file = $filename;
 
            $source = $this->fetch_str(file_get_contents($filename));             //關鍵地方,讀取範本檔,處理範本字串
 
            if (file_put_contents($name, $source, LOCK_EX) === false)      //寫入編譯以後的檔
 
            {
 
                trigger_error('can\'t write:' . $name);
 
            }
 
            $source = $this->_eval($source);
 
        }
 
        return $source;
 
    }
 
 
 
 
 
 
 
    function fetch_str($source)
 
    {
 
        if (!defined('ECS_ADMIN'))
 
        {
 
            $source = $this->smarty_prefilter_preCompile($source);      //預處理函數,此函數代碼檔中有詳細解釋就不囉嗦了
 
        }
 
        return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);    //匹配處理{}每個標籤
 
    }