2011-10-27 27 views
1

什麼是翻譯css的最佳方式,以便它可以在不同的路徑中工作。我查看了一些不同的庫(CrushCSS,minify),他們似乎只在這個服務上壓縮文件(我不想這麼做)。如何在將css url路徑移動到不同文件夾時重新計算css url路徑

是我最好的一個正則表達式嗎?如果是的話,我將需要處理的所有可能的情況是什麼?

例如,輸入:/base/my.css

@import url "../another/file.css" 
#container { 
    background: url('example/relative/path.png'); 
} 
#container2 { 
    background: url('/example/absolute/path.png'); 
} 

預期輸出:/base/example/path/my.css

@import url "../../../another/file.css" 
#container { 
    background: url('../relative/path.png'); 
} 
#container2 { 
    background: url('/example/absolute/path.png'); 
} 

編輯:

我在 「最佳實踐」 不感興趣或方法來避免這種類型的的問題。我只關心如何進行轉換,以便css在新的路徑中保持正確。

回答

2

我決定我會重構一些代碼Minify以允許我需要的抽象CSS轉換。

<?php 

//This class is heavy borrowed from Minify_ImportProcessor 

class CSSImporter 
{ 

    static function changePaths($content, $current_path, $target_path) 
    { 
     $current_path = rtrim($current_path, "/"); 
     $target_path = rtrim($target_path, "/"); 
     $current_path_slugs = explode("/", $current_path); 
     $target_path_slugs = explode("/", $target_path); 
     $smallest_count = min(count($current_path_slugs), count($target_path_slugs)); 
     for($i = 0; $i < $smallest_count && $current_path_slugs[$i] === $target_path_slugs[$i]; $i++); 
     $change_prefix = implode("/", array_merge(array_fill(0, count($target_path_slugs) - $i, ".."), array_slice($current_path_slugs, $i))); 
     if(strlen($change_prefix) > 0) $change_prefix .= "/"; 

     $content = preg_replace_callback(
      '/ 
      @import\\s+ 
      (?:url\\(\\s*)?  # maybe url(
      [\'"]?    # maybe quote 
      (.*?)    # 1 = URI 
      [\'"]?    # maybe end quote 
      (?:\\s*\\))?  # maybe) 
      ([a-zA-Z,\\s]*)? # 2 = media list 
      ;     # end token 
      /x', 
      function($m) use ($change_prefix) { 
       $url = $change_prefix.$m[1]; 
       $url = str_replace('/./', '/', $url); 
       do { 
        $url = preg_replace('@/(?!\\.\\.?)[^/]+/\\.\\[email protected]', '/', $url, 1, $changed); 
       } while($changed); 
       return "@import url('$url'){$m[2]};"; 
      }, 
      $content 
     ); 
     $content = preg_replace_callback(
      '/url\\(\\s*([^\\)\\s]+)\\s*\\)/', 
      function($m) use ($change_prefix) { 
       // $m[1] is either quoted or not 
       $quote = ($m[1][0] === "'" || $m[1][0] === '"') 
        ? $m[1][0] 
        : ''; 
       $url = ($quote === '') 
        ? $m[1] 
        : substr($m[1], 1, strlen($m[1]) - 2); 

       if('/' !== $url[0] && strpos($url, '//') === FALSE) { 
        $url = $change_prefix.$url; 
        $url = str_replace('/./', '/', $url); 
        do { 
         $url = preg_replace('@/(?!\\.\\.?)[^/]+/\\.\\[email protected]', '/', $url, 1, $changed); 
        } while($changed); 
       } 
       return "url({$quote}{$url}{$quote})"; 
      }, 
      $content 
     ); 
     return $content; 
    } 

} 

?> 
2

我想說最好的辦法是始終使用相對於您網站根目錄的URL。無論放置CSS文件的位置如何,/example/absolute/path.png都將始終有效。

+0

這不是一個選項,因爲css文件已經存在。我正在尋找一種以編程方式移動它們,同時保持它們有效的方式。 –

+0

同樣在我的情況下,我不能使用絕對路徑,因爲網站基地不能保證是'/'。 –

+0

他們總是會/某事。在你自己的域名或子域名中,它們將與/相關,如果你在子目錄中,那麼它們將是/子目錄。 – GordonM