2011-02-15 54 views
2

現狀:PHP模板系統 - 正確的方式來加載默認的JavaScript行爲模板

  1. 一個PHP模板系統,負責建立一個網頁的HTML。
  2. 的Javascript核心功能都是在外部文件
  3. 每個模板都需要一些默認的JavaScript函數以每個/模板基礎

當一個頁面被渲染調用,接下來我需要調用一個一組Javascript函數:即

<script type="text/javascript"> 
    $(document).ready(function{ 
     API.loadThis(); // all these Javascript functions are in an external JS file 
     API.loadThat(); 
     API.buildDateSelector("#idForSelector"); 
     // etc 
    }); 
</script> 

到目前爲止,我已經將它作爲文本添加到每個HTML模板中。但是,如果頁面由多個較小的模板組成(每個模板可能都包含它們自己的初始化Javascript),那麼我會在我的網頁上嵌入多個嵌入式JavaScript。

我的問題是:

  1. 我應該如何恰當地安排一切,讓我可以輕鬆地「註冊」或「觸發」了一些默認的JavaScript來在頁面加載後調用?
  2. 或者是每個模塊(如上所述)的每個塊的附加適當?
+0

此外,如果它不完全清楚我所問的,讓我知道,我可以添加更多的具體信息。謝謝 – 2011-02-15 19:56:14

+0

在我們的產品中我們有類似的東西,我們這樣做,{tpl_name} _js_bottom.tpl在渲染模板時加載(如果存在)。 – ludesign 2011-02-15 19:59:29

回答

1

我會做的事情與@Chris非常相似。不過,我建議一些小的改動:

  1. 一個參數添加到addJS功能指示頁面上的位置。默認情況下,您應該至少支持headfoothead將其置於首位,foot將在關閉</body>之前將其置於正前方)。

    public function addJS($string, $position = 'head') { 
        if (!is_array($this->js[$position])) { 
         $this->js[$position] = array($string); 
        } elseif (!in_array($string, $this->js[$position])) { 
         $this->js[$position][] = $string; 
        } 
    } 
    

    然後,在模板中包括標記來指示的位置:

    {{js_head}} 
    </head> 
    <body> 
        <!--content here--> 
        {{js_foot}} 
    </body> 
    

    然後,渲染時,只是這樣做:

    $js = $this->js; 
    $positions = preg_replace_callback(
        '/{{js_(inline_)?([a-zA-Z0-9]+)}}/', 
        function ($match) use ($js) { 
         if (isset($js[$match[2]])) { 
          $js = implode("\n", $js[$match[2]]); 
          if ($match[1] == 'inline') { 
           return $js; 
          } else { 
           return '<script type="text/javascript">'.$js.'</script>'; 
         } 
         return ''; 
        }, 
        $templateBody 
    ); 
    

    現在,真正的好處是,您的模板可以乾淨利落地定義自己的位置,以便重複使用和常用位:

    $this->addJS('return this.form.submit();', 'submit_form'); 
    $html = ' 
        <input type="text" onblur="{{js_inline_submit_form}}" /> 
        <button name="submit" onclick="{{js_inline_submit_form}}" /> 
    '; 
    

    它可能非常有用,因爲現在你不會在代碼中隨處複製JS調用。此外,它會減少打包<script>標籤中的每個輸出的開銷(因爲它包裝在標籤中的整個位置,而不是每個內容)...

  2. 這將允許您然後採取所有非內聯JS並且在運行時編譯一系列文件以發送給瀏覽器來處理緩存。它增加了能夠保持JS接近你的視圖的好處(爲了可維護性),但仍然服務於緩存的JS,並且不必每次都重新發送它...

    public function buildJSCache($position) { 
        if (!isset($this->js[$position]) || empty($this->js[$position])) { 
         return ''; 
        } 
        $file = implode($this->js[$position]); 
        $name = 'js/'.md5($file) .'.js'; 
        if (!file_exists($name)) { 
         file_put_contents($name, $file); 
        } 
        return $name; 
    } 
    

    然後,在你的模板代碼,只是做:

    $replace = $this->buildJSCache('head'); 
    if ($replace) {   
        $replace = '<script type="text/javascript" src="'.$filename.'"></script>'; 
    } 
    $template = str_replace('{{js_head}}', $replace, $template); 
    

    你得到的可維護性和速度的雙贏用戶(你甚至可以再壓縮它,如果你想)。

注:所有這些代碼是示範而已,如果你在生產中使用它,我會清理並進一步認爲它有點...

這是我的$ = 0.02至少...

0

有很多方法可以做到這一點。我建議你得到一些開源框架,看看他們如何做事,並決定你的偏好。有些技術被認爲是「最佳實踐」,但很多框架的結構歸結爲開發人員的偏好。

我有一個框架,我用於我自己的項目,類似於你所描述的,每個較小的模板被稱爲「組件」。每個組件都可以使用addJS()方法爲自己添加任意數量的javascript,同樣適用於css和html。頂級控制器遍歷給定頁面的內容(就組件而言)。這給了我一個提前加載所有css,javascript和html的機會。然後,我可以按照我認爲合適的順序輸出它們。

所以:

  • 頁面控制器手柄請求
    • inits一個或多個組件
      • 部件load方法填充HTML,JavaScript和CSS類屬性(文件名的陣列,串爲HTML ) 本身
      • 組件有它自己的一組模板,js,css
    • 輸出站點範圍內的模板
      • 包括
    • 遍歷組件頁頭標之內的所有部件的CSS,輸出部件的HTML,佈局東西
    • 輸出部件JS爲頁腳

我有一個components文件夾,其中是每個組件的文件夾新界東北堆填區。在每個組件文件夾內有一個php文件(該組件的處理程序),可選一個或多個css/js文件。這使得一切組織得很好。

+0

不錯。這是我的想法。該頁面有一個JS onload函數/代碼數組,並且在頁面呈現時全部回顯。您也正確地檢查出許多其他模板引擎。我覺得也許我應該在發佈之前在較低級別完成此操作:P – 2011-02-15 20:11:06