0x9d8e
@0x9d8e
Велосипедостроитель в терминальной стадии

Как автоматически заменить в разных CSS-файлах любые относительные пути на абсолютные?

Почему и зачем
Есть около двадцати пяти css-файлов в разных каталогах (плагины). Хочу объединить их все в один, но во многих из них есть относительные пути к иконкам и т.п. То есть, допустим в файле /plugin/style.css есть строка background-image: url(img/icon.png); при этом абсолютный путь к иконке /plugin/img/icon.png и если перенести стили в другое место (а объединяя файлы из разных каталогов это неизбежно), то получится, уже, скажем /css/img/icon.png. Свалить все эти ресурсы в одну кучу тоже не вариант из-за конфликтов имён.

Внимание вопрос
Поэтому нужно каким-то образом автоматически парсить на сервере стили и заменять в них любые относительные пути на абсолютные. Из готового попадаются только средства для склейки и минификации файлов, никак с путями не работающие. Думал сам такое дело написать, но это оказалось задачей не на пару часов.
Есть ли готовые средства? Лучше если на php, но не принципиально.

UPD:
Так как готового средства по-видимому нет, по-сути проблема сводится к тому, чтобы программно найти в строке с css-кодом эти самые пути. А это могут быть строки, как в кавычках, так и без, как в url() так и без, как с точками/слешами, так и без. Разве что без пробелов и всё-таки да, с одной точкой, отделяющей расширение фала. Ситуацию несколько облегчает то, что можно почти из любой строки попытаться вычислить абсолютный путь и проверить существует ли такой файл.
  • Вопрос задан
  • 702 просмотра
Решения вопроса 1
0x9d8e
@0x9d8e Автор вопроса
Велосипедостроитель в терминальной стадии
В общем решил это таким образом:
Читаем каждый css-файл, регуляркой @([\.*\/\w+\/]*[\-\w]+\.(?>jpg|gif|png|svg|css|jpeg|woff|eot|ttf))@ (не очень-то ими владею, так что есть в ней проблемы) находим все ссылки на файлы. Для каждого совпадения делаем какие-то правки (для случаев типа ./filename.svg), конкатенируем эту ссылку с путём до css-файла в котором была ссылка и заменяем ей оригинал. После чего просто пишем всё в один большой файл (можно ещё минифицировать и всякое такое).

private static function fixPathes($css_file_name, $file_string) {
    $path = dirname($css_file_name) . '/';
    $mathes = [];
    preg_match_all('@([\.*\/\w+\/]*[\-\w]+\.(?>jpg|gif|png|svg|css|jpeg|woff|eot|ttf))@iS', $file_string, $mathes);
    $fixed = [];
    foreach($mathes[0] as $original_file_name) {

        if(isset($fixed[$original_file_name]))
            continue;

        if(strpos($original_file_name, './') === 0) {
            $file_name = str_replace('./', '', $original_file_name);
        } else {
            $file_name = $original_file_name;
        }

        $file_string = str_replace($original_file_name, '/'.$path.$file_name, $file_string);

        $fixed[$original_file_name] = true;
    }

    return $file_string;
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@mletov
Открыть каждый из 25 файлов, Crl+F->Replace, работы от силы на час
Ответ написан
dmitry_pavlov
@dmitry_pavlov
World-class .NET freelance contractor (remotely)
Не думаю, что это хорошая затея, так как при обновлении версий плагинов - будет проблема обновляться.

Это видели? www.gambit.ph/converting-relative-urls-to-absolute...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы