Эволюция Viewer: управление блоками, слияние и минимизация JS/CSS

На SVN работа над LS0.4 кипит, начну понемногу описывать нововведения. Итак, сегодня у нас на очереди модуль Viewer, который постепенно «обрастает» очень вкусными полезностями. В этот модуль добавлено:

1. Управление выводимыми на страницу js,css файлами.

2. Управление выводимыми на страницу блоками через конфигурацию.

Подробнее под катом.

Функционал по управлению js/css файлами состоит в:

1. Возможности задавать через конфигурацию совокупность выводимых файлов «по умолчанию», т.е. если ничего другого для страницы не указано.

Пример дефолтной конфигурации для css:

$config['head']['default']['css'] = array(
	$config['path']['static']['skin']."/css/style.css?v=1",
	$config['path']['static']['skin']."/css/Roar.css",
	$config['path']['static']['skin']."/css/piechart.css",
	$config['path']['static']['skin']."/css/Autocompleter.css",
	$config['path']['static']['skin']."/css/prettify.css",	
	$config['path']['static']['skin']."/css/thickbox.css",
	$config['path']['static']['skin']."/css/ie6.css?v=1"=>array('browser'=>'IE 6'),
	$config['path']['static']['skin']."/css/ie7.css?v=1"=>array('browser'=>'gte IE 7'),	
	$config['path']['static']['skin']."/css/simple_comments.css"=>array('browser'=>'gt IE 6'),	
);


В отличие от моего модуля Loader, здесь решена проблема с IE-хаками. При указании параметра отображения файла
'browser'=>'IE 6'

он будет выведен как
<!--[if IE 6]>.....<![endif]-->


2. Возможность переопределять список js/css по правилам, привязанным к виду URL страницы. При этом можно добавлять новые файлы или удалять из списка дефолтные. Это достаточно полезно, так как далеко не все 18 js-скриптов и 6 css нужны на всех страницах проекта. А если вам нужно подключить новый js для нового модуля, то вы можете не «нагружать» им весь проект — а только те страницы, который реально в этом нуждаются.

Сейчас в конфигурации прописано только одно правило (для примера):

$config['head']['rules']['page'] =array(
	'path'=>$config['path']['root']['web'].'/page/',
	'js' => array(
		'exclude' => array(
			$config['path']['static']['skin']."/js/vote.js",
			$config['path']['static']['skin']."/js/favourites.js",
			$config['path']['static']['skin']."/js/questions.js",		
		)
	),
);

«По просьбам трудящихся» я буду понемногу накапливать список подобных правил в сборке, чтобы движек сразу после установки использовал минимально возможный набор js/css.

3. Добавить js/css файл теперь можно из кода Action`a. Для этого доступны четыре функции Viewer`a: AppendScript(), PrependScript(), AppendStyle(), PrependStyle().

4. Судя по комментариям к записи о Loader`e и личным письмам в мой ящик — это самое долгожданное: возможность сливать js/css файлы в один с одновременным уменьшением их объема.

Для минимизации js скриптов используется библиотека JSMin, для минимизации CSS — CSSTidy (для справки: именно эти библиотеки лежат в основе работы набирающего популярности Web Optimizator`a). Настройка степени сжатия и выполняемых при этом действий осуществляется через основную конфигурацию.

По умолчанию все подключенные файлы сливаются в один .js и один .css (это позволяет уменьшить число GET запросов при загрузке страницы в 12 раз). Отдельно выводятся только IE-хаки, которые подгружаются или нет «по желанию» браузера. Но в конфигурации можно разбивать файлы на блоки, каждый блок будет слит в отдельный файл.

Слитые и сжатые .js, .css кешируются в папке templates/cache/. При этом в css файлах автоматически перезаписываются относительные пути к ресурсам. Поэтому, уважаемые верстальщики, не волнуйтесь — вашей работе этот механизм никак не помешает :) Предусмотрен механизм «сброса» кеша при замене\внесении изменений в js или css файл. Также разработан cron-процесс для периодической «зачистки» cache-директории от старых js/css файлов.

Функционал по управлению блоками:

Теперь в конфигурации вы можете указывать какие блоки в каких action`ах и event`ах выводить.

Пример такой конфигурации (правило для отображения блоков в экшенах Index и Blog):

$config['block']['rule_index_blog'] = array(
	'action'  => array(
			'index' => array('index'), 
                        'blog',
		),
	'blocks'  => array(
			'right' => array('stream','tags','blogs'=>array('params'=>array(),'priority'=>1))
		)
);


Event для конкретного Action можно задавать прямо или регулярным выражением, а можно вообще не задавать — тогда правило сработает для всех Event`ов указанного Action`a.

В приведенном примере:
— 'rule_index_blog' — название правила (осмысленные названия правил дают возможность переопределять их в коде при необходимости);
— 'index', 'blog' — названия экшенов для правила;
— 'index' => array('index') — название/я event`ов action`a Index;
— 'blocks' — массив блоков с указанием параметров добавления.

В добавлении блока теперь участвует дополнительный параметр — priority, который дает возможность управлять порядком вывода блоков.

На этом громкие сенсации во Viewer заканчиваются, комментарии, идеи, баг репорты и краш-тесты приветствуются.

Впереди еще рассказы о новом роутере, новых возможностях конфигурации, о модуле обработки изображений Image, обертке для Cron-процессов, отложенной отправке почты, о закрытых блогах, возможностях кастомизации модулей и сущностей, взаимной дружбе, блекджеке…

Как сказал бы сейчас Малахов: Не переключайте каналы.

68 комментариев

avatar
Скоро админку писать придётся. Конфиг уже крышесносный. :)
Когда ожидать релиз 0.4?
avatar
Когда ожидать релиз 0.4?
возможно в этом году
avatar
Вы будете оказывать услуги по переезду на новую версию?
avatar
Пишите в приватные сообщения, договоримся.
avatar
движек

ДвижОк!

Prepand

«Prepend». I don't know what «prepand» means.


А так изменения очень радуют.
avatar
Ага, добавили новые, очень нужные, фичи. Одно управления блоками чего стоит. Теперь не нужно редактировать десяток файлов.
:)
avatar
Спасибо, исправил.
avatar
>>закрытых блогах

Вот это очень жду.
avatar
Функционал закрытых блогов уже реализован, т.е. можете ставить с SVN и тестировать.
avatar
Поставил 579 ревизию на хостинг потестить. Насчет закрытых блогов было бы неплохо если бы пользователи могли делать заявки на присоединение к закрытым блогам, примерно как ранее в хаке carw'a было реализовано. А то сейчас если нажать кнопку «присоединиться» выскакивает красное окошко, что вступить можно только по приглашению. В идеале было бы круто чтобы в отдельные, заданные создателем блога можно было вступать только по приглашению от создателя, а в другие закрытые по заявкам, т.е. зашел админ блога к себе, посмотрел список желающих присоединиться и одобрил и назначил роли: читатель, модератор, админ. Может это и лишнее, но по заявкам мне кажется удобнее. Продолжаю тестить:)
avatar
Опять какой то пидор-тролль пробежался и поставил минус, прошу высказаться по закрытым блогам народ.
avatar
Оффтопик, но подобную проблему, если ее можно так назвать, прекрасно решает выдача прав на изменение рейтинга только тем, у кого рейтинг не просто положительный, но выше единицы. Разумеется, схема годна только для уже активно функционирующего сайта.
avatar
Ну тогда это уже скорее не закрытые блоги, а временно невидимые :-)

Тут все действительно от подхода сильно зависит.
avatar
Минусуют часто. Особенно старые записи (и топики, и комментарии к ним). Не знаю кому и зачем это нужно, но я уже привык.
avatar
Ребят, а Road Map у вас есть?
avatar
:) Конечно есть, только пока коротенькая: «Скоро выйдет 0.4».
avatar
:-D
avatar
Алексей, было б неплохо еще версию ЛС задавать. Причем, не в индекс.пхп, как сейчас, а тоже в конфиг-файле. И это, конечно, константой.
avatar
Ну, вообще-то, это не конфигурация :) Это констатация факта.
avatar
Хотел было объяснить, зачем и для чего его (это факт) нужно бы констатировать именно в конфиге, но пока объяснял, понял, что в общем-то это не так уж обязательно :)
avatar
:)
avatar
Это просто замечательно. Очень хорошие новости. Наконец-то пошла работа над оптимизацией пользовательской части.
В 0,31 с модулями получается какой-то монстр с горой яваскрипта и css)
avatar
Вообще супер! Буквально, как говорится, мечты сбываются! :-)
  • Carw
  • +2
avatar
Посмотрел закрытые блоги, как раз то, что я собирался допилить буквально… :-)

Но видимо уже мало имеет смысла продолжать развитие моего хака действительно… :-)
avatar
К сожалению, я не видел ни функционал вашего хака, ни его реализацию, поэтому не могу дать толкового совета :)
avatar
Можно демку посмотреть, правда со стороны пользователя, но в целом суть та же самая. Единственно, что я реализовал модель, когда сами пользователи просятся в закрытый блог, а администратор их принимает или выгоняет. Как раз планировал сделать модель приглашения, а точнее белых/черных списков (почти тоже самое).

Опять же из других отличий — я не стал бороться с кешированием всех лент и учетом кому и что показывать (так как по идее пользователь итак находясь в закрытом блоге получает оповещения и знает о происходящем). Надо посмотреть как вы это реализовали. :-)

Но вообще — это замечательно, что такая штука появилась родная. А я уж либо заброшу свое решение, либо разовью во что-то более функциональное :-)
avatar
В ядре с кешем и отображением штука запутанная :) В блок Блоги, например, выводятся закрытые, но со специальной пометкой. В облако тегов и прямой эфир — только происходящее в открытых, независимо от того состоит ли где-то пользователь или нет. Аналогично по записям из избранного, комментариям в избранном.

В отображении записей появляется понятие Accessible блог (Открытые + Те, в которых моя роль выше нулевой). Ньансов, тонкостей и хитростей много. Чего только стоит перевод ранее открытого блога в закрытый :)
avatar
Вы сделали роли в блогах?! Ура!!! Вот я вообще просто счастлив буквально! Осталось теперь разобраться в механизме добавления новых ролей и будет совсем интересно! :-)

У них есть какое-то глобальное определение? Или это всего лишь цифра, которая фигурирует в связи пользователь-блог?
avatar
С точки зрения базы данных — это число (по другому сложно придумать). С точки зрения определения ролей в модулях — это константы класса LsBlog вида BLOG_USER_ROLE_{} (следовательно, доступны глобально).

Создания новых ролей «правильнее» всего (с архитектурной точки зрения) организовывать с помощью подмены LsBlog кастомным, унаследованным от исходного.

Разбирайтесь :)
avatar
ошибочку, наверное, исправить стоит ;-)
avatar
Ошибочку исправлю обязательно! А какую, кстати? Лучше сразу в личку, чтобы не оффтопить :-)
avatar
Прекрасные новости. Как раз хотел начать заняться блогосоциальной сетью в начале 2010 и закончить к 2011. То, что вы делаете действительно очень ценно.
  • z0r
  • 0
avatar
да, ценно. но вот как будет осуществляться обновление с 0.3 на 0.4?
avatar
а что вас смущает?
avatar
Админка планируется ко всему этому богатству настроек?
avatar
будем надеяться
avatar
очень порадовала новость об оптимизации js-скриптов уже на уровне стандартной поставки жвижка!
но волнут 2 других вопрса. Как будет с производительностью? Ведь всякое усложнение кода ведет за собой дополнительные затраты процессорного времени. И второй вопрос, нунжо будет что-то придумаь с упрощенным переездом на новую версию движка. Просто у многих польхователей стоит куча дополнительных модулей и просто хаов.
avatar
1) Там не так уж всё и усложнено, все операции по формированию и сжатию css, js выполняются единожды. Результаты сохраняются в папке caсhe.
2) Если посмотреть SVN то очевидно что нереально перевести 0.3.1 с модулями (неизвестно какими) на 0.4 автоматической операцией… Только ручками… пилить и строгать… пилить и строгать… пилить и строгать
Вообще Пока не выйдет версии 1.0 не стоит ждать чего-то автоматического… Ведь движок ещё только формируется.

Чёт я совсем загнался — отвечаю на вопросы заданные создателям движка ))
avatar
1) Единожды для каждого уникального списка js и для каждого уникального списка css. По поводу производительности еще рано отвечать на этот вопрос. Все станет на свои места тогда, когда будет тестировать финальная сборка. Тем более версия с SVN всегда доступна — можно ставить и тестировать :)
avatar
Если для вывода блоков экшн указывать page, то блоков на страницах не появляется, а очень хотелось бы.
avatar
Так сделан шаблон.
/templates/skin/new/actions/ActionPage/page.tpl


{assign var="bNoSidebar" value=true}

вот эту строку уберите.
avatar
Спасибо. Появился ещё вопрос, в экшнах, которые не указанны в конфиге вылезает ошибка Notice: Undefined index: path in www/engine/modules/viewer/Viewer.class.php on line 490.
avatar
Немного не понял проблему: о какой части конфига идет речь?
avatar
Я не совсем понял способ использования вьювера. Правила куда надо писать и как ими потом пользоваться? Я лихо добавил приведенные в примере строки в общий конфиг и напоролся на то, на что напоролся.
avatar
1) Правила нужно вписывать в основной конфиг. Или в любое другое место, где они будут добавлены в основной конфиг.
2) Правила не нужно использовать, они используются Viewer`ом автоматически.
3) Приведенные в примере строки уже добавлены в конфиг ядра.
avatar
Какая судьба ожидает скин «developer»?
avatar
присоеденюсь, тоже волнует этот вопрос.
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
avatar
А как в конфиге прописать несколько правил загрузки JS и CSS для разных модулей?

Вот есть правило для page
$config['head']['rules']['page'] =array(
    'path'=>$config['path']['root']['web'].'/page/',
    'js' => array(
        'exclude' => array(
            "___path.static.skin___/js/vote.js",
            "___path.static.skin___/js/favourites.js",
            "___path.static.skin___/js/questions.js",
            "http://maps.google.com/maps/api/js?sensor=true",
        )
    ),
);


А как мне добавить сюда еще правило для people и profile к примеру, хочу разные наборы JS и CSS для этих модулей?
avatar
По аналогии. Выше описаны правила как добавлять\удалять из наборов файлы.
avatar
Не понял.
$config['head']['rules']['page'] — у нас массив как я понял только для одного правила. Если следом за ним написать еще раз $config['head']['rules']['page'] и в нем другое правило для другого пути, то предыдущее правило затрется новым.
avatar
А кто вам мешает новое правило назвать по новому? Например, $config['head']['rules']['А_ТУТ_ВАШЕ_ИМЯ_ПРАВИЛА'].
avatar
Махонький глючок: AppendScript() — добавляет скрипт в начало списка, а PrependScript() — в конец, хотя, судя по их названиям, должно быть наоборот :)

AppendStyle() и PrependStyle() не проверял
avatar
Есть предложение: в методах AppendScript(), PrependScript(), AppendStyle(), PrependStyle() добавить параметр, показывающий, надо ли добавлять скрипт/стиль в общий «пакет». Иногда, если требуется добавить небольшой файлик (особенно для плагина) разумнее его (файлик) просто подгружать отдельно, чтоб не плодить кучу больших файлов.
avatar
Предусмотрен механизм «сброса» кеша при замене\внесении изменений в js или css файл. Также разработан cron-процесс для периодической «зачистки» cache-директории от старых js/css файлов.
Можно подробнее? Как он работает? Решил сверстать шаблон, вношу изменения и ничего…

ИМХО: как то мудрено вышло, разобраться бы…

P.S. Если я что-то пропустил при прочтении, то не пинайте.
  • tito
  • 0
avatar
вношу изменения и ничего…
Список «сжимаемых» js\css файлов задается через конфигурацию, а не в шаблоне.
avatar
спасибо, разобрался, одновременно написали :)
avatar
все разобрался, нада было сначала потыкать прежде чем писать :)
avatar
Алексей, есть необходимость добавить CSS-файл. Хотелось бы его именно в заголовок засунуть, но при этом мне НЕ надо, чтоб он сливался с другими. Засовывать хардкодом в шаблон тоже не хочется его. Покрутив Вьюер, понял, что сейчас нет такого инструмента, чтоб это сделать из экшена. Предлагаю добавить метод, что-нибудь вроде AddHtmlHeadFile($sFile), который будет добавлять еще один файл к списку. Дешево и сердито. Делов на 3 минута, а польза будет.
avatar
Добавляй его в отдельный блок имени самого себя, и он (файл) не будет сливать с остальными.
avatar
1. Но будет перемещаться в папку с css/js-кешем. А мне как раз этого надо избежать. Т.е. уже не устраивает.
2. Надо править config.php, а хотелось бы делать это динамически из экшена.
avatar
2. Надо править config.php, а хотелось бы делать это динамически из экшена.
AppendStyle(), PrependStyle() работают из action`а. Или я не понял задачу?
avatar
А AppendStyle(), PrependStyle() разве не к дефолтному блоку цепляют файлы? Мне нужен вариант, при котором css-не будет ни с кем сливаться, и останется на своем месте. И даже объясню для чего — мне надо, чтоб из цсс-файла урлы к картинкам предсказуемо работали.
avatar
Кстати, раз уж зашла речь об AppendStyle() и проч. — хотелось бы уметь в этих методах добавлять файлы в конкретные блоки, а не только в дефолтный блок.
avatar
А как тогда управлять блоками, которые находятся внутри плагина?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.