Упаковщик CSS: зачистка css-файла
версия для печатиУпаковщик не в смысле архивации, а в смысле чистки css-файлов от пустых строк и комментариев. Слово "упаковщик" более удобно, чем "чистильщик" или т.п. Файл в итоге получается меньше без потери функциональности, поэтому так "громко" назвал :)
Проблема: на локальной копии сайта я храню файлы стилей с комментариями, а на сервере они должны быть чистыми. Перед первой загрузкой на сервер подчистил все. Теперь у меня две версии - с комментами и без них. При изменении в одной версии приходится повторять изменения в другой. Не удобно, напрягает и все такое :( Надо что-то делать.
Есть такое решение, как php-библиотека Minify. Работает с css/javascript. Размещаем библиотеку в недрах сайта, все подключения стилей/скриптов переводим на нее типа так:
<link href="http://mysite.ru/min/?f=css/style.css" rel="stylesheet" type="text/css" /><script type="text/javascript" src="http://mysite.ru/min/?f=js/script.js"></script>
Теперь на сервер можно все заливать, как есть, а при загрузке страниц браузеру будут отправляться очищенные файлы. Программа минимизирует, объединяет и кэширует CSS-файлы. Вообщем круто наверно :). Отказался я от этой проги потому, что:
- Minify - это большая библиотека php-скриптов. Черт-ее-знает, где там дыры. Перекапывать весь код для самоуспокоения мне не хочется;
- любой сообразительный хаЦкер сможет получить файл без компрессии, т.е. со всеми комментами и т.д. Как? Просто заменит запрос '.../min/?f=css/style.css' на 'http://mysite.ru/css/style.css'. Можно защититься от этого, разместив каталог с js-скриптами и css-файлами в админке.
Суть: в админке страница с формой по загрузке файлов. Выбираю, что грузить и еще некоторые параметры (степень очистки, резервная копия). PHP-скрипт (см. ниже) получает файл, полный комментов, чистит и ложит в нужный каталог, откуда готовый файл подключается в пользовательские шаблоны.
Мой упаковщик. Frontend
В этой статье я приведу скрипт по очистке CSS-файлов. Про скрипт для очистки js-файлов тоже напишу когда-нибудь. Пример файла ("лабораторная крыса"):
div.clear{clear:both;} /*используем пустую div-ку для отмены обтекания. Очень важная div-ка!!*/
/*------Ярлычки, общий вид вкладок----------*/
.tab{background-color: #DDECFF; } /* <----- цвет ярлычка */
.menucontent, .onepost{
border:1px solid #81A8FF;
/* table-layout: fixed; это нельзя делать, иначе придется контролировать ширину ячейки.
При увеличении разряда счетчика ячейку нужно уменьшать. Ширина прям в html установлена.*/
}
div.post_tab{background-color:white;/*#FFF8F2*/ /*#81A8FF*/} /*Ярлычки на одной записи*/
div.hidden{background-color:#FFA500;/*#FFF8F2*/ /*#81A8FF*/}
/*------------------------------------------*/
table.label td{padding:0 5px 2px 0; vertical-align: middle !important;}
Что имеем: пустые строки, обычный комментарий в конце строки (1), многострочный комментарий (7, 8) и вставки комментов прям в описании свойств селектора (10, 11). Более того, я для себя принял такое соглашение: отдельные смысловые блоки отмечаю комментариями, в которых пишу только по-русски и еще использую знак '-' (3, 12).
Если нужно вычищать все комментарии, то код получается совсем простой:
$fn='/home/site/css/style.css'
$text=file_get_contents($fn);
$text=preg_replace('#\/\*.*\*\/#Us','',$text); //Вырезаем комменты, заключенные в "/*...*/"
$text=preg_replace("#\s+[\n|\r|\r\n]+#","\n",$text); //Заменяем все пробелы в конце строки и любые окончания строк на Linux-окончание строки.
file_put_contents($fn,$text);
Результат применения к подопытному файлу выглядит так:
div.clear{clear:both;}
.tab{background-color: #DDECFF; }
.menucontent, .onepost{
border:1px solid #81A8FF;
}
div.post_tab{background-color:white; }
div.hidden{background-color:#FFA500; }
table.label td{padding:0 5px 2px 0; vertical-align: middle !important;}
На этом можно было бы закончить статью. Остается только прикрутить скрипт к обрабочику формы, эта часть работы остается за вами. Важно понимать, что загрузка файлов по HTTP сильно уступает FTP, но в моем случае файлики не большие, так-что вполне хватает метода POST. Еще один вероятный минус (на деле у меня так не было): представьте, пока вы методами POST/GET заливаете обновки на сервер, кому-то формируется ответ в браузер. Я думаю, у пользователя есть вероятность получения битого css/js-файла. Но поскольку это не критично к работе сайта, я иду на такой риск.
В качестве post scriptum приведу код функции, которая аккуратно вычищает все комментарии кроме "смысловой разметки" (см. пример выше, строки 3, 12):
//Умный css-упаковщик. Оставляет однострочные комменты при условии,
//что в строке только русские буквы и "-" (разметка блока).
$fn='/home/site/css/style.css'
$text=file_get_contents($fn);
$text=preg_replace("#\r\n|\r#","\n",$text);
$arr=explode("\n",$text);
$flgMulti=false;//Поднимаем флаг, когда попадется многострочный комментарий.
//Сбрасываем, когда такой коммент заканчивается.
foreach($arr as $str)
{
//Текущая строка - часть многострочного коммента
if($flgMulti)
{ if(preg_match("#\*\/#U",$str)) //если в строке есть закрывающие коммент символы..
{ $str=preg_replace("#.*\*\/#U",'',$str,1);//..вырезаем конец комментария. Только первое совпадение. Эт правильно, иначе может быть вырезано лишнее ;)
$flgMulti=false; } //Cбрасываем флаг.
else continue; }
//Если в строке не [только русский текст или "-" (разметка блока)], то чистим строку..
if (!$flgMulti && !preg_match('#^\/\*[а-яА-Я\s-,\.]+\*\/$#U',$str))
{ $str=preg_replace('#\/\*.*\*\/#U','',$str);//Вырезаем комменты, заключенные в "/*...*/"
$str=rtrim($str); } //Убираем пробелы в конце строки
//Если нашли начало многострочного коммента (есть открывающие символы, но нет закрывающих),..
if (preg_match("#\/\*#",$str) && !preg_match("#\*\/#",$str))
{ $str=preg_replace("#\/\*.*#",'',$str); //..то вырезаем текущую часть коммента
$flgMulti=true; } //и поднимаем флаг.
if(!$str) continue;
$str=preg_replace('#(\S+)\s+\}#',"\\1}",$str);//Последний штрих - убираем пробелы типа "..10px;[пробелы]}". Они могли остаться после вырезки коммента.
$new[]=$str;
}
$text=implode("\n",$new);
file_put_contents($fn,$text);
Думаю, из комментариев в коде понятно, что к чему. Результат работы такого упаковщика выглядит так:
div.clear{clear:both;}
/*------Ярлычки, общий вид вкладок----------*/
.tab{background-color: #DDECFF;}
.menucontent, .onepost{
border:1px solid #81A8FF;
}
div.post_tab{background-color:white;}
div.hidden{background-color:#FFA500;}
/*---------------------------------
---------*/
table.label td{padding:0 5px 2px 0; vertical-align: middle !important;}
[1oo%, EoF]Похожие материалы: Упаковщик Javascript: зачистка js-файла
Понравилась статья? Расскажите о ней друзьям: