2011-10-27 2 views
1

다른 경로에서 작동하도록 CSS를 변환하는 가장 좋은 방법은 무엇입니까? 몇 가지 다른 라이브러리 (CrushCSS, minify)를 살펴 봤는데 파일을 압축하는 것과 함께이 서비스를 통해서만 보입니다.다른 폴더로 이동할 때 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

필자가 필요로하는 추상적 인 CSS 변환을 허용하기 위해 Minify에서 일부 코드를 리팩토링하기로 결정했습니다.

<?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을 사용하는 것이 최선의 방법이라고 말하고 싶습니다. /example/absolute/path.png는 CSS 파일을 어디에 두든 상관없이 항상 작동합니다.

+0

css 파일이 이미 있으므로 옵션이 아닙니다. 나는 여전히 프로그램을 계속 유효하게하면서 프로그래밍 방식으로 움직이는 방법을 찾고 있습니다. –

+0

또한 사이트베이스가'/'이 될 수 없기 때문에 제 경우에는 절대 경로를 사용할 수 없습니다. –

+0

그들은 항상/뭔가있을거야. 자신의 도메인 또는 하위 도메인에서 /와 관련이 있으며/하위 디렉토리에 있으면/하위 디렉토리가됩니다. – GordonM

관련 문제