2011-01-06 15 views
7

Czy istnieją dobre implementacje integracji Minify z Zend Framework? Szukam przykładów.Dowolne dobre Zend Framework + Minify implementations?

Chciałbym mieć wtyczkę, która nadpisuje $ this-> headLink() i wypluwa poprawny minified URL/treść.

Edit:

Wydaje Większość przykładów I znaleźć nie są w pełni zoptymalizowane w jednej formie lub mody. Szukam rozwiązania spełniającego następujące wymagania:

Redukuje wiele łączy i znaczników skryptów do jednego żądania (jeden dla łącza i jeden dla skryptów) Najbliższy, jaki widziałem, to ścieżka żądania, która przekazuje przecinek -delimited ciąg/min/tak:

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

Dlaczego nie coś, co łączy wszystkie skrypty w jednym pliku na dysku w locie, a następnie buforuje go tak, że nie robi minifikacji na każde żądanie?

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

Łączenie aspekt powinien utrzymać porządek (w odniesieniu do poprzedź, dołącz itp)

Chociaż nie dbają tak bardzo o wysyłanie prawidłowe wygasa nagłówki, bo zmuszają gzipping, Etags i wygasa nagłówki po stronie serwera, posiadanie tego opcjonalnego byłoby korzystne dla innych użytkowników.

Na koniec, posiadanie skryptu budującego, który generuje zminimalizowane zasoby, nie jest konieczne, o ile jest to łatwe i nie wymaga zmiany kodu po każdym kompilacji.

+0

Pracuję nad tym teraz, fav'd to i będzie pan pisał –

+0

@jakenoble żadnego postępu tutaj? – doremi

+0

Odpowiedz teraz wysłany –

Odpowiedz

0

mmm, przepraszam, nie mam przykłady ale mogę pomóc w wyjaśnieniu, jak,

mój prosty obieg byłby tak:

1- jako widok pomocnika w Twojej bibliotece Folder, należy utworzyć klasę, która rozciąga się statyczną funkcję my_minify::minify() można utworzyć viewhelper które zastępują funkcjonalność zarówno headLink() i minfy klasy

2- jako plugin : możesz utworzyć wtyczkę, która uruchamia postdispatch, aby zminimalizować cały wynikowy widok, więcej explanation

2

Próbuję zrobić to samo teraz. Patrzę na OT Framework Uniwersytetu Stanowego, oparty na Zend Framework. Jest to zaimplementowane jako pomocnik widoku. Ma ładny klasę Minify wszystkie headscripts i headlinks poprzez Minify na Google Code:

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(); 
    } 
} 

A oto kod 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

To jest to, czego używam, pokazana jest klasa, a następnie przypadki użycia.Ja skomentował to szybko, niektóre z nich mogą potrzebować zmieniając dopasować swoje ścieżki lub 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); 
     } 
    } 
} 

by użyć takiego pomocnika w widoku

// 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)); 

A oto javascript wersja

$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)); 
+0

Działa, ale naprawdę mylące? Potrzebuję wyjaśnienia. – Nandakumar

+0

Co wymaga wyjaśnienia - wszystkie są komentowane? –

2

Przebiegłem ten sam problem, a skończyłem na pisaniu dwóch pomocników, którzy mogliby mi pomóc. Możesz je zobaczyć pod numerem http://blog.hines57.com/2011/03/13/zendframework-minify/ - jeszcze raz dziękuję. Krótki opis jednego z nich:

* * ** 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]--> 
+0

W odniesieniu do "Zmniejsza liczbę łączy i znaczników skryptu do jednego żądania (jeden dla łącza i jeden dla skryptów) Najbliższy widziałem jest ścieżka żądania, która przekazuje ciąg rozdzielany przecinkami do/min/like:" - minify faktycznie obsługuje to za Ciebie. Tworzy i buforuje plik na dysku przy pierwszym żądaniu, a wszystkie kolejne żądania tego łańcucha rozdzielanego przecinkami po prostu służą wersji buforowanej, w przeciwieństwie do "ponownego" zmniejszania go przy każdym wywołaniu. – bubba