2011-01-06 34 views
7

Minify是否有與Zend Framework集成的良好實現?我正在尋找例子。任何良好的Zend Framework + Minify實現?

我很想擁有一個覆蓋$ this-> headLink()並且吐出正確縮小的url /內容的插件。

編輯:

看來大多數的例子,我覺得不在一個形式或方式全面優化。我正在尋找一個滿足以下要求的解決方案:

將多個鏈接和腳本標記減少爲一個請求(一個用於鏈接,一個用於腳本) 最近我見過的是一個請求路徑,它傳遞一個逗號-delimited串/分鐘/就像這樣:

<script src="/min?f=file1.js,file2,js,file3.js" type="text/javascript"></script> 

爲什麼不是東西,將所有腳本到上飛盤一個文件,然後將其緩存,這樣你是不是做在每次請求的縮小?

<script src="/js/app.js?someRandomStringHere" type="text/javascript"></script> 

的結合方面應該維持秩序(參照預先考慮,追加等)

雖然我不關心發送正確的這麼多,因爲我強迫gzip壓縮,ETag的Expires頭,和Expires頭在服務器端,擁有該選項會對其他用戶有所幫助。

最後,有一個生成縮小資源的構建腳本不是必須的 - 只要它很容易做到,並且每次構建後都不需要更改代碼。

+0

我現在正在處理這個問題,贊成這個,並會讓你張貼 – 2011-01-07 08:58:38

+0

@jakenoble這裏有什麼進展? – doremi 2011-01-20 19:22:19

+0

現在可以發表回覆 – 2011-01-20 21:49:33

回答

0

嗯,對不起,我沒有例子,但我可以幫你解釋如何,

我簡單的工作流程是這樣的:

1-作爲您的自定義庫中的視圖助手 文件夾,創建可擴展的my_minify::minify() 靜態函數的類,你可以創建一個視圖助手即會覆蓋headLink()minfy

2-功能作爲一個插件: 你可能會創建插件,運行postdispatch來縮小整個視圖,更多explanation

2

我正在嘗試現在做同樣的事情。我正在研究基於Zend Framework的NC州立大學的OT框架。這是作爲視圖助手實現的。它有一個很好的類通過縮減大小來縮小在谷歌代碼的所有headscripts和headlinks:

http://ot.ncsu.edu/2010/03/03/getting-started-with-ot-framework/

Headscripts:

<?php 

/** 
* Minifies the javascript files added via the minifyHeadScript helper using 
* minify (http://code.google.com/p/minify/) 
* 
*/ 
class Ot_View_Helper_MinifyHeadScript extends Zend_View_Helper_HeadScript 
{ 

    protected $_regKey = 'Ot_View_Helper_MinifyHeadScript'; 

    public function minifyHeadScript($mode = Zend_View_Helper_HeadScript::FILE, $spec = null, $placement = 'APPEND', array $attrs = array(), $type = 'text/javascript') 
    { 
     return parent::headScript($mode, $spec, $placement, $attrs, $type); 
    } 

    public function toString() 
    { 
     $items = array(); 
     $scripts = array(); 
     $baseUrl = $this->getBaseUrl(); 

     // we can only support files 
     foreach ($this as $item) { 
      if (isset($item->attributes['src']) && !empty($item->attributes['src'])) { 
       $scripts[] = str_replace($baseUrl, '', $item->attributes['src']); 
      } 
     } 

     //remove the slash at the beginning if there is one 
     if (substr($baseUrl, 0, 1) == '/') { 
      $baseUrl = substr($baseUrl, 1); 
     } 

     $item = new stdClass(); 
     $item->type = 'text/javascript'; 
     $item->attributes['src'] = $this->getMinUrl() . '?b=' . $baseUrl . '&f=' . implode(',', $scripts); 
     $scriptTag = $this->itemToString($item, '', '', ''); 

     return $scriptTag; 
    } 

    public function getMinUrl() { 
     return $this->getBaseUrl() . '/min/'; 
    } 

    public function getBaseUrl(){ 
     return Zend_Controller_Front::getInstance()->getBaseUrl(); 
    } 
} 

這裏是headlinks代碼:

<?php 

/** 
* Minifies the stylesheets added via the minifyHeadLink helper using 
* minify (http://code.google.com/p/minify/) 
* 
*/ 
class Ot_View_Helper_MinifyHeadLink extends Zend_View_Helper_HeadLink 
{ 

    protected $_regKey = 'Ot_View_Helper_MinifyHeadLink'; 

    public function minifyHeadLink(array $attributes = null, $placement = Zend_View_Helper_Placeholder_Container_Abstract::APPEND) 
    { 
     return parent::headlink($attributes, $placement); 
    } 

    public function toString() 
     { 
     $items = array(); 
     $stylesheets = array(); 
     $baseUrl = $this->getBaseUrl(); 

     foreach ($this as $item) { 
      if ($item->type == 'text/css' && $item->conditionalStylesheet === false) { 
       $stylesheets[$item->media][] = str_replace($baseUrl, '', $item->href); 
      } else { 
       $items[] = $this->itemToString($item); 
      } 
     } 

     //remove the slash at the beginning if there is one 
     if (substr($baseUrl, 0, 1) == '/') { 
      $baseUrl = substr($baseUrl, 1); 
     } 

     foreach ($stylesheets as $media=>$styles) { 
      $item = new stdClass(); 
      $item->rel = 'stylesheet'; 
      $item->type = 'text/css'; 
      $item->href = $this->getMinUrl() . '?b=' . $baseUrl . '&f=' . implode(',', $styles); 
      $item->media = $media; 
      $item->conditionalStylesheet = false; 
      $items[] = $this->itemToString($item); 
     } 

     $link = implode($this->_escape($this->getSeparator()), $items); 

     return $link; 
    } 

    public function getMinUrl() { 
     return $this->getBaseUrl() . '/min/'; 
    } 

    public function getBaseUrl(){ 
     return Zend_Controller_Front::getInstance()->getBaseUrl(); 
    } 
} 
3

這就是我使用的類,隨後顯示了用例。我趕緊評論它,它的一些可能需要改變,以配合您的路徑或define()PUBLICPATH

class View_Helper_Minify extends Zend_View_Helper_Abstract 
{ 
    public function minify($files, $ext, $folderName) 
    { 
     // The folder of the files your about to minify 
     // PUBLICPATH should be the path to your public ZF folder 
     $folder = PUBLICPATH . $folderName . "/"; 

     // Set update needed flag to false 
     $update_needed = false; 

     // This is the file ext of the cached files 
     $cacheFileExt = "." . $ext; 

     // The list of files sent is exploded into an array 
     $filesExploded = explode(',', $files); 

     // The full cached file path is an md5 of the files string 
     $cacheFilePath = $folder . md5($files) . $cacheFileExt; 

     // The filename of the cached file 
     $cacheFileName = preg_replace("#[^a-zA-Z0-9\.]#", "", end(explode("/", $cacheFilePath))); 

     // Obtains the modified time of the cache file 
     $cacheFileDate = is_file($cacheFilePath) ? filemtime($cacheFilePath) : 0; 

     // Create new array for storing the list of valid files 
     $fileList = array(); 

     // For each file 
     foreach($filesExploded as $f) 
     { 
      // determine full path of the full and append extension 
      $f = $folder . $f . '.' . $ext; 

      // If the determined path is a file 
      if(is_file($f)) 
      { 
       // If the file's modified time is after the cached file's modified time 
       // Then an update of the cached file is needed 
       if(filemtime($f) > $cacheFileDate) 
        $update_needed = true; 

       // File is valid add to list 
       $fileList[] = $f; 
      } 
     } 

     // If the cache folder's modified time is after the cached file's modified time 
     // Then an update is needed 
     if(filemtime($folder) > $cacheFileDate) 
      $update_needed = true; 

     // If an update is needed then optmise the valid files 
     if($update_needed) 
      $this->optmiseFiles($fileList, $cacheFilePath, $ext); 

     // Finally check if the cached file path is valid and return the absolute URL 
     // for te cached file 
     if(is_file($cacheFilePath)) 
      return "/" . $folderName . "/" . $cacheFileName; 

     // Throw Exception 
     throw new Exception("No minified file cached");    
    } 

    private function optimise($code, $ext) 
    { 
     // Do not optmise JS files 
     // I had problems getting JS files optmised and still function 
     if($ext == "js") 
      return $code; 

     // Remove comments from CSS 
     while(($i = strpos($code, '/*')) !== false) 
     { 
      $i2 = strpos($code, '*/',$i); 

      if($i2 === false) 
       break; 

      $code = substr($code, 0, $i).substr($code, $i2 + 2); 
     } 

     // Remove other elements from CSS 
     $code = str_replace('/*','',$code); 
     $code = str_replace("\n",' ',$code); 
     $code = str_replace("\r",' ',$code); 
     $code = str_replace("\t",' ',$code); 
     $code = @ereg_replace('[ ]+',' ',$code); 
     $code = str_replace(': ',':', $code); 
     $code = str_replace('; ',';', $code); 
     $code = str_replace(', ',',', $code); 
     $code = str_replace(' :',':', $code); 
     $code = str_replace(' ;',';', $code); 
     $code = str_replace(' ,',',', $code); 

     // Return optimised code 
     return $code; 
    } 

    // Optmise the list of files 
    private function optmiseFiles($fileList, $cacheFilePath, $ext) 
    { 
     // Empty String to start with 
     $code = ''; 

     // Check files list in case just one file was passed 
     if(is_array($fileList)) 
     { 
      // Foreach of the valid files optmise the code if the file is valid 
      foreach($fileList as $f) 
       $code .= is_file($f) ? $this->optimise(implode('', file($f)), $ext) : ''; 
     } 
     // Else if a valid file is passed optmise the code 
     else 
      $code = is_file($fileList) ? $this->optimise(implode('', file($fileList)), $ext) : ''; 

     // Open the cache file 
     $f = @fopen($cacheFilePath, 'w'); 

     // If open successful 
     if(is_resource($f)) 
     { 
      // Write code to the cache file 
      fwrite($f, $code); 

      // close cache file 
      fclose($f); 
     } 
    } 
} 

你會使用這樣的幫手在您看來

// Define an array of files, note you do not define the ext of those files 
// The ext is defined as a param for the helper as this effects the optmisation 
$files = array("jquery-ui-1.8.7.custom", 
      "jquery.pnotify.default", 
      "jquery.pnotify.default.icons", 
      "tipTip", 
      "prettyPhoto", 
      "custom"); 

// Get the absolute URL of the files which are imploded also pass the directory 'css' and ext 'css' 
$cssString = $this->minify(implode("," , $files), "css", "css"); 

// use baseURL() to output the full URL of the cached file and use it as normal with headLink() 
echo $this->headLink() 
->appendStylesheet($this->baseUrl($cssString)); 

這裏是一個javascript版本

$files = array("jquery-1.4.4.min", 
      "jquery.pnotify.min", 
      "jquery.tipTip.minified", 
      "jquery.countdown.min", 
      "jquery.prettyPhoto", 
      "jquery.typewatch", 
      "default.functions"); 

$jsString = $this->minify(implode("," , $files), "js", "scripts"); 

echo $this->headScript()->appendFile($this->baseUrl($jsString)); 
2

我跑過同樣的問題,最後編寫了兩個drop-in助手來爲我管理它。你可以在http://blog.hines57.com/2011/03/13/zendframework-minify/看到它們 - 再次感謝。其中之一的快速概覽:

* * ** PREREQUISITES ** 
* This file expects that you have installed minify in ../ZendFramworkProject/Public/min 
* and that it is working. If your location has changed, modify 
* $this->$_minifyLocation to your current location. 
* 
* ** INSTALLATION ** 
* Simply drop this file into your ../ZendFramworkProject/application/views/helpers 
* directory. 
* 
* ** USAGE ** 
* In your Layout or View scripts, you can simply call minifyHeadLink 
* in the same way that you used to call headLink. Here is an example: 
* 
    echo $this->minifyHeadLink('/favicon.ico')    // Whatever was already loaded from Controller. 
    ->prependStylesheet('http://example.com/js/sample.css')// 6th 
    ->prependStylesheet('/js/jqModal.css')     // 5th 
    ->prependStylesheet('/js/jquery.alerts.css')   // 4th 
    ->prependStylesheet('/templates/main.css')    // 3rd 
    ->prependStylesheet('/css/project.css.php')   // 2nd 
    ->prependStylesheet('/css/jquery.autocomplete.css') // 1st 
    ->appendStylesheet('/css/ie6.css','screen','lt IE 7'); // APPEND to make it Last 
* 
* 
* This can be interesting because you will notice that 2nd is a php file, and we 
* have a reference to a favicon link in there as well as a reference to a css file on 
* another website. Because minify can't do anything with that php file (runtime configured 
* css file) nor with CSS on other websites, and order is important,you would notice that 
* the output in your browser will looks something like: 
* 
    <link href="/min/?f=/css/jquery.autocomplete.css" media="screen" rel="stylesheet" type="text/css" /> 
    <link href="/css/project.css.php" media="screen" rel="stylesheet" type="text/css" /> 
    <link href="/min/?f=/templates/main.css,/js/jquery.alerts.css,/js/jqModal.css" media="screen" 
       rel="stylesheet" type="text/css" /> 
    <link href="http://example.com/js/sample.css" media="screen" rel="stylesheet" type="text/css" /> 
    <link href="/favicon.ico" rel="shortcut icon" /> 
    <!--[if lt IE 7]> <link href="/css/ie6.css" media="screen" rel="stylesheet" type="text/css" /><![endif]-->