Содержание
Настройка автоматической минификации CSS на Джумле
Оптимизация CSS состоит из трех этапов:
- установка и настройка инструментов
- объединение CSS в
css/style-big.css
, последующее сжатие стилей вcss/style.css
- замена всех стилей объединенным файлом стилей
Установка и настройка инструментов
Установка компоновщика
Makefile
- положить в каталог на уровень выше дерева веб-документов. В примерах ниже дерево веб-документов - в каталоге www
.
- Makefile
# # Настройка путей. Makefile необходимо положить выше дерева web-документов, # либо подправить следующие относительные пути # ### Настройки # web-документы WEB_ROOT=www # каталог для сохранения объединенной и минифицированной версии CSS_OUT=$(WEB_ROOT)/media # каталог для сохранения промежуточных вариантов CSS SRC_ROOT=src/css # файл с перечислением всех CSS файлов, участвующих в объединении CSS_SRC=src/css.txt # файл с перечислением всех JS файлов, участвующих в минификации JS_SRC=src/js.txt ### Подготовка данных CSS_SRC_FILES=$(shell cat $(CSS_SRC)) CSS_FILE_DEST=$(addsuffix .less, $(addprefix $(SRC_ROOT)/, $(CSS_SRC_FILES))) JS_SRC_FILES=$(shell cat $(JS_SRC)) JS_FILE_DEST=$(addsuffix .mjs, $(JS_SRC_FILES)) ### Подготовка файла CSS: удаление знака BOM, замена относительных путей на абсолютные define abs_build cat $1 | sed '1s/^\xef\xbb\xbf//' | ./relabs.php --webroot='$4' --abspath='$3' --color > $2 endef ### Цели и зависимости .PHONY: all all: css js css: $(CSS_OUT)/style.css $(CSS_OUT)/style.css: $(CSS_FILE_DEST) # Объединение файлов @echo @echo $(CSS_FILE_DEST) @echo $(shell cat $(CSS_FILE_DEST) > $(CSS_OUT)/style-big.css) # Минификация (1 вариант) с помощью csso https://github.com/css/csso # csso -i $(CSS_OUT)/style-big.css -o $(CSS_OUT)/style.css # Минификация (2 вариант) с помощью yuicompressor http://yui.github.io/yuicompressor/ # java -jar yuicompressor.jar -o $(CSS_OUT)/style.css $(CSS_OUT)/style-big.css # Минификация Он-лайн (3 вариант) с помощью https://code.google.com/p/reducisaurus/ # wget -O $(CSS_OUT)/reducisaurus-style.css http://reducisaurus.appspot.com/css?url=http://ruszvuk.ru/css/style-big.css $(CSS_FILE_DEST): $(CSS_SRC_FILES) $(SRC_ROOT)/$(WEB_ROOT)/%.css.less: $(WEB_ROOT)/%.css @mkdir -p $(@D) $(call abs_build,$<,$@,$(*D),$(WEB_ROOT)) js: $(JS_FILE_DEST) $(WEB_ROOT)/%.js.mjs: $(WEB_ROOT)/%.js java -jar yuicompressor.jar $< -o $@
Необходимо создать каталоги: www/css
, src/css
, в файле src/css.txt
прописать используемые CSS-файлы (относительные пути):
- src/src1.txt
www/components/com_virtuemart/assets/css/vmsite-ltr.css ... www/templates/yourtheme/css/style.css
Если на сайте используются внешние CSS, например http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css, их необходимо скачать и сохранить в отдельный каталог, например в www/css/external/
, заменив в них ссылки на изображения - либо на свои скачанные, либо прописать обращение к внешнему сайту. Затем вписать файл в src/src1.txt
.
Для преобразование относительных путей в абсолютные - скрипт relabs.php
:
работает, если веб-сайт не находится в подкаталоге домена, т.е. если сайт расположен по адресу site.ru/blog/
, возможно, что потребуется доработка
- relabs.php
#!/usr/bin/env php <?php // Этот скрипт служит для исправления относительных путей в CSS на абсолютные с целью объединения в один файл if (php_sapi_name() != 'cli') die('Run it in cli mode!'); class Replacer { private $isAllRight = true; static $parms = array(); public function run() { chdir(__DIR__); $this->getParms(); $this->replace(); die($this->isAllRight ? 0 : 1); } private $text; private function replace() { $this->text = file_get_contents("php://stdin"); // replace @import "style.css"; $this->text = preg_replace_callback('~(@import.*?;)~sui', array('self', '_replaceImport'), $this->text); // rel to abs $this->text = preg_replace_callback('~url\s*\(\s*(.*?)\s*\)~sui', array('self', '_replace'), $this->text); echo $this->text; } public static function _replaceImport($m) { self::error(sprintf('Warning: file contains @import: %s', $m[0])); return ''; } public static function _replace($m) { $uri = trim(trim($m[1],'"\'')); // inline-image if(preg_match('~^data:image~', $uri)) { return self::_wrap($m[1]); } // external image if(preg_match('~^(\/|https?:\/\/)~', $uri)) return self::_wrap($uri); $uri = '/'.self::$parms['abspath'].'/'.ltrim($uri, '/'); self::checkFileExists($uri); return self::_wrap($uri); } public static function _wrap($uri) { return 'url('.self::_prepare($uri).')'; } public static function _prepare($uri) { $uri = preg_replace('~\/[^/]+\/\.\.\/~', '/', $uri); return $uri; } private static function checkFileExists($uri) { $file = self::$parms['webroot'] . parse_url($uri, PHP_URL_PATH); if(!file_exists($file)) self::error("Warning: file $file not exists!"); } private function getParms() { self::$parms = getopt('', array('webroot:', 'abspath:', 'color')); if(!isset(self::$parms['webroot'], self::$parms['abspath'])) { $this->man(); die(1); }; } private function man() { $this->error("Use: relabs.php --webroot=WEB_ROOT --abspath=ABS_PATH --color"); } public function error($msg) { if(isset(self::$parms['color'])) { $msg = self::getColoredString($msg, 'red', null); } fwrite(STDERR, $msg . PHP_EOL); } private static $fgColors = array( 'black' => '0;30', 'dark_gray' => '1;30', 'blue' => '0;34', 'light_blue' => '1;34', 'green' => '0;32', 'light_green' => '1;32', 'cyan' => '0;36', 'light_cyan' => '1;36', 'red' => '0;31', 'light_red' => '1;31', 'purple' => '0;35', 'light_purple' => '1;35', 'brown' => '0;33', 'yellow' => '1;33', 'light_gray' => '0;37', 'white' => '1;37'); private static $bgColors = array('black' => '40', 'red' => '41', 'green' => '42', 'yellow' => '43', 'blue' => '44', 'magenta' => '45', 'cyan' => '46', 'light_gray' => '47'); private static function getColoredString($string, $foreground_color = null, $background_color = null) { $colored_string = ""; if (isset(self::$fgColors[$foreground_color])) { $colored_string .= "\033[" . self::$fgColors[$foreground_color] . "m"; } if (isset(self::$bgColors[$background_color])) { $colored_string .= "\033[" . self::$bgColors[$background_color] . "m"; } $colored_string .= $string . "\033[0m"; return $colored_string; } } $r = new Replacer(); $r->run();
Скрипту необходимо выставить права на выполнение:
chmod +x relabs.php
Установка инструментов минификации
Этот пункт не обязателен, возможно использовать объединенный файл css/style-big.css
, прописав его в шаблоне. Либо после каждой сборки объединенного файла сжимать его каким-либо способом вручную, например так.
Следует установить одну из программ, в зависимости от способа:
- Структурная минификация: csso
- C помощью yuicompressor
- Он-лайн инструментом Reducisaurus
- Любой другой, прописав его в Makefile, зависимость
$(CSS_OUT)/style.css: $(CSS_FILE_DEST)
Для выбора способа необходимо исправить соответствующую строку в Makefile
Объединение и сжатие CSS
В Makefile прописаны необходимые команды для объединения и сжатия. Необходимо запустить make на выполнение из консоли:
make
В дальнейшем, при изменении исходных CSS стилей, этой одной командой запускается весь процесс пересборки. Принудительное выполнение:
make -B
В некоторых случаях, связанных с использованием на Windows-платформе, требуется принудительное выполнение всех правил.
Возможные ошибки
Warning: file www/templates/yourtheme/images/picture.jpg not exists!
Это - предупреждение о том, что указанный в CSS файл физически отсутствует.
make: csso: Команда не найдена
Не был установлен минификатор.
make: *** Нет правила для сборки цели `www/...', требуемой для `src/css/www/...'. Останов.
Не настроены пути в Makefile, неправильные пути в src/src1.txt
.
Замена стилей объединенным файлом CSS
Есть два способа:
- добавить плагин, удаляющие «прежние» стили (простой)
- внести изменения в шаблоны (трудоемкий)
Внесение изменений в шаблоны
Джумла автоматически добавляем стили в шаблон. Любое расширение, обращаясь к API движка, способно добавить свой набор стилей. В нашем случае следует исключить стили, попавшие в собранный выше финальный CSS файл.
Есть два способа: кардинальный - удалить блок:
<jdoc:include type="head" />
и прописать все вручную (JS, CSS, etc), либо выборочно отключить учтенные в сборке CSS файлы - этот способ и рассмотрим.
В файл templates/your-theme/index.php
необходимо добавить следующее (перед доктайпом):
- templates/your-theme/index.php
$excludeCss = array( '/components/com_virtuemart/assets/css/vmsite-ltr.css', // перечислить все отключаемые стили '/templates/your-theme/css/default.css', // возможно указать только часть URL, так как проверка идет регуляркой ); $excludeCssRules = array(); foreach($excludeCss as $f) { $excludeCssRules[] = preg_quote($f); } $excludeCssRules = implode('|', $excludeCssRules); foreach($this->_styleSheets as $k => $v) { if(preg_match('~('.$excludeCssRules.')$~', $k)) unset($this->_styleSheets[$k]); }
Узнать какие стили подключаются возможно, открыв исходный код HTML-страницы. Либо так:
die(var_dump($this->_styleSheets));
После секции <jdoc:include type=«head» />
надо подключить наш собранный CSS:
<link rel="stylesheet" href="/css/style.css" type="text/css" />
В идеале - на этом все. Однако некоторые расширения добавляют стили «после», либо «грязными хаками», поэтому выпилить их возможно либо специальным (каким?) плагином, работающим по сформированной странице, либо доработав исходный код самих расширений. Об этом - далее.
Доработка кода «упрямых» компонентов
От отдельных CSS файлов описанным выше способ не избавиться. Часть - цепляет стили уже после, часть - использует хаки. Против всех работает метод грубой силы - изменение исходного кода. Проблему обновлений и хаков решает систему контроля версий. В примерах - конечный вариант. Суть - закомментировать добавление стилей.
Virtuemart
- administrator/components/com_virtuemart/helpers/config.php
// vmJsApi::css('facebox'); ... // vmJsApi::css ( $cssFile ) ;
YTools
- modules/mod_sj_vm_extraslider_res/mod_sj_vm_extraslider_res.php
// YTools::stylesheet('vmextraslider.css'); // YTools::stylesheet('css3.css');
BIT Vituemart Product Badges
- plugins/system/bit_vm_product_badges/bit_vm_product_badges.php
// $css_link = "<link rel=\"stylesheet\" href=\"$plugin_short_path"."css/bitvmbadges.css\" type=\"text/css\" />"; ... $body = preg_replace ("/<\/head>/", "\n".$css_link."\n".$js_link."\n".$js_call."\n</head>", $body);
Другие расширения
- modules/mod_market_reviews/tmpl/default.php
// $document->addStyleSheet('/modules/mod_market_reviews/css/default.css');
Что делать после установки новых расширений, добавляющих CSS
Выше мы отключили отдельные CSS файлы (из шаблона, а также с помощью комментариев), поэтому новые расширения изначально будут работать, но добавят дополнительные CSS стили.
Следует добавить в src/src1.txt
эти файлы, а также подправить $excludeCss
из index.php
темы, либо подправить код самих расширений. После этого запустить компиляцию:
make