#php #css #relative-path
#php #css #относительный путь
Вопрос:
Каков наилучший способ перевести css, чтобы он работал по другому пути. Я просмотрел несколько разных библиотек (CrushCSS, minify), и, похоже, они работают только над этой службой вместе со сжатием файлов (чего я не хочу делать).
Мое лучшее регулярное выражение? Если да, то каковы все возможные случаи, которые мне нужно будет обработать?
Например, введите: /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 оставался правильным в новом пути.
Ответ №1:
Я бы сказал, что лучшим способом было бы всегда использовать URL-адреса относительно корня вашего сайта. /example/absolute/path.png всегда будет работать, независимо от того, где вы разместите файл CSS.
Комментарии:
1. Это не вариант, поскольку файлы css уже существуют. Я ищу способ их программного перемещения, сохраняя при этом их действительность.
2. Также в моем случае я не могу использовать абсолютные пути, поскольку база сайта не гарантируется
/
.3. Они всегда будут /something . В вашем собственном домене или поддомене они будут относиться к /, а если вы находитесь в подкаталоге, то они будут /подкаталог.
4. В моем случае сайт доступен для просмотра из двух разных каталогов одновременно (не мое дело). Так что, если я буду использовать
url('/path')
для одного, это приведет к разрыву другой ссылки. Я должен использовать относительный css, чтобы он работал.5. В этом случае, я думаю, у вас есть только два реалистичных варианта. 1) Создайте символические ссылки в местоположении b, которые указывают на файлы в местоположении a, чтобы оба пути к рассматриваемому ресурсу были действительными, или б) замените файл CSS скриптом PHP, который выводит файл 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 amp;amp; $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('@/(?!\.\.?)[^/] /\.\.@', '/', $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] amp;amp; strpos( $url, '//') === FALSE ) {
$url = $change_prefix.$url;
$url = str_replace('/./', '/', $url);
do {
$url = preg_replace('@/(?!\.\.?)[^/] /\.\.@', '/', $url, 1, $changed);
} while( $changed );
}
return "url({$quote}{$url}{$quote})";
},
$content
);
return $content;
}
}
?>