Александр Павлов

Optiweb vs. Netcat

На конференции Сайт-2009 Дмитрий Васильев подарил Диме Фитискину коробочную версию небезызвестной CMS  Netcat. У меня, как у молодого и амбициозного технолога, возникло непреодолимое желание попробовать ее в деле, а заодно сравнить с нашей, студийной CMS  Optiweb.

О соперниках.

Netcat, думаю, не нуждается в представлении. Это одна из наиболее популярных на сегодняшний день система управления сайтами. 11.5% сайтов рунета, по версии CMS Magazine используют Netcat.

Optiweb  неизвестная система, разработанная в стенах студии еще в 2003 году, и с тех пор ядро системы практически не изменялось.

Интерфейс

Netcat встретил меня приятным интерфейсом. Простым и понятным. Интерфейс для пользователя. Некоторые моменты, конечно, на большом экране смотрятся ущербно, например таблицы в базовых настройках системы, но в целом зачет. Особенно порадовало наличие дрэг-н-дроп в редактировании дерева.

В Optiweb не все так гладко. Верстка хромает, задний фон немного отвлекает внимание. В принципе, к этому быстро привыкаешь, но первое впечатление складывается не самое лучшее. Но если открыть админку в IE, то там Optiweb выглядит вполне нормально (парадокс).

Netcat выигрывает в плане интерфейса. Потянет, пожалуй, на твердую четверку. Отпугивает огромное количество бесполезных наворотов, типа встроенного php/html редактора. Зачем встраивать в CMS редактор с подсветкой кода? Ответ в следующем параграфе.

Базовая интеграция.

Включает установку всех макетов дизайна на CMS и всех навигационных элементов (меню, хлебные крошки). Интеграцию я делал на примере корпоративного сайта компании Квадрат.

Макетирование.

Вот тут случилось самое большое разочарование в Netcat. Я по привычке полез искать файл макета, но не нашел его. Пришлось открывать руководство для разработчика, из которого я понимаю, что, оказывается, никаких файлов макета нет вовсе. Все данные (как выяснилось позже, не только данные макета) хранятся в базе. Все редактирование происходит через небольшое окошко формы. Фу, плохая киса! Я опечалился и закрыл Эклипс. На мой взгляд  это ужасная, грубая ошибка  лишать разработчика возможности «играть на родном поле». Я постоянно был вынужден копировать код из поля в редактор, жать кнопку сохранить. Это отнимало у меня массу времени. Поначалу я даже хотел заплакать прекратить дальнейшую работу с движком.

Проблем с назначением макета для главной и вторичных страниц не возникло, тут без нареканий.

У Optiweb проблемы излишнего использования базы нет. Файл макеты загружается на сервер, выбирается в админке, и все. Удобное назначение использования макета для станиц сайта: выбирается макет для главной страницы, и для всех вторичных.

Структура формирования макета у подопытных движков разная. В Netcat он разбивается на 2 части: Хедер и Футер, а все что посередине  блок контента. Это знакомым тем, кто работал с Битриксом. Optiweb поступает иначе: шаблон не разбивается, а в него помещаются блоки. То есть прямо в файле макета вставляется конструкция вида:


<!--#block src='blockname'-->

Парсер распознает этот комментарий как блок. Чтобы создать поле контента в нужном месте на странице пишем:

<!--#block src='content'-->

И создаем в разделе «блоки и шаблоны» раздел «content». Преимущество этого метода в том, что если допускаешь ошибку в вызове блока, то он отобразиться как простой комментарий. Тут стоит отметить, что блоки бывают нескольких типов: статический (текстовый блок), шаблоный (вывод данных по заданному шаблону), и динамический (блок вывода модулей, например новостей, каталога или навигации). Content  обычный текстовый блок.

Установка навигации.

С навигацией в Netcat ничего сложного. Вызываем блок меню в макете:


s_browse_level(0,$browse_sub[0])

и в шаблоне для вывода навигации работаем вот с такой конструкцией:


$browse_sub[0]['prefix'] = "<ul>";
$browse_sub[0]['suffix'] = "</ul>";
$browse_sub[0]['active'] = "<li><span class='selected'><a href=''>%NAME</a></span>".s_browse_level(1, $browse_sub[1])."</li>";
$browse_sub[0]['active_link'] = "<li><span class='selected'><a>%NAME</a></span>".s_browse_level(1, $browse_sub[1])."</li>";
$browse_sub[0]['unactive'] = "<li><span><a href='%URL'>%NAME</a></span></li>";
$browse_sub[0]['divider'] = "";

Здесь все, пожалуй, понятно. Навигация представляет собой список. Prefix  начало списка, suffix — окончание. Active  параметры родителя, когда активен потомок, ".s_browse_level(1, $browse_sub[1])." вывод навигации второго уровня. Аctive_link  параметры активного пункта, unactive  неактивного. Divider  разделитель, он мне не понадобился.

Аналогичным образом настраивается меню второго и выше уровней уровней. Без ложки дегдя не получится. В Netcat нельзя настраивать несколько типов навигации (вернее можно, но для этого надо схитрить). А на сайте есть 2 разных навигации: главная, и каталог домов. Чтобы сделать 2 навигации в Netcat: мы создаем в дереве дополнительный пункт меню, скрываем его на сайте, и вызываем в шаблоне:


s_browse_sub(E,$browse_sub[2])

E  это номер элемента в дереве, который использует шаблон $browse_sub[2]. Для главной навигации первое число  0, потому что отображаются все разделы сайта. Недостаток этого метода в том, что скрытый пункт меню отобразится в хлебных крошках, что нежелательно. В Optiweb можно создавать любое количество навигаций, и применять их к любому пункту в дереве. А настройка пунктов происходит аналогичным образом:

<!--#list src='root'-->
 <div id="nav">
 <ul>
 <!--#elem-->
 <!--#cond-->
 return $_ds->getParam('is_cur_active');
 <!--#endcond-->
 <li> <span class="selected"><a><!--#slot src='fullname'--></a></span><!--#slot link='suboptions'--></li>
 <!--#endelem-->
 <!--#elem-->
 <!--#cond-->
 return $_ds->getParam('is_active');
 <!--#endcond-->
 <li><span class="selected"><a href="<!--#slot src='url'-->"><!--#slot src='fullname'--></a></span><!--#slot link='suboptions'--></li>
 <!--#endelem-->
 <!--#elem-->
 <li><a href="<!--#slot src='url'-->"><!--#slot src='fullname'--></a></li>
 <!--#endelem-->
 </ul>
 </div>
<!--#endlist-->

Несколько громоздкая конструкция, но в целом понятная. List  это список, все, что находится внутри list, перед, или после elem  это аналог суффикса и префикса в Netcat. Elem  это элемент списка. Внутри <!--#cond-->  условие. Код внутри elem выполнится, если активен потомок элемент ('is_cur_active' -аналог Active в Netcat), если нет, то переходим к следующему элементу. Is_active  выполнится, если активен сам элемент <!--#slot link='suboptions'-->  второй уровень меню. Если ни одно из условий не выполняется, то выводится последний элемент списка, не имеющий условия. На мой взгляд, в Netcat таки удобнее реализован вывод меню.

Установка модулей и компонентов.

Компоненты в Netcat ставить просто. При редактировании разделы выбираем список используемых компонентов, и вызываем нужный нам компонент на страницу, например Новости. Компонентов можно вызывать несколько, но все они оказываются в разделе контент. Чтобы вывести вне контента, и заодно сделать выборку 2-х последних новостей на главной странице, пишем в шаблоне:


s_list_class(C,R,"recNum=2")

Где С  номер компонента, а R  номер раздела.

Дальше заходим в раздел компонентов, и настраиваем шаблон как нам нужно. Тут, конечно, хорошо бы иметь представление хотя бы о синтаксисе PHP, потому что не экранированные кавычки (например в названии классов) приводят к ошибке.

Аналогичным образом устанавливается компонент каталога. Но есть один нюанс. Понадобилось сделать вывод «параметров дома» в описании элемента. Оп, ноу проблем. Заходим во вкладку поля в настройках компонента, и сколько душе угодно создаем новых переменных. Вызываем нужные переменные в шаблоне вывода компонента:


<tr>
	<td>Площадь застройки m<sup>2</sup></td>
	<td>".opt_case( $f_sqr , '$f_sqr', "нет"; )."</td>
</tr>

И так для всех элементов, которые нам нужны. opt_case  Netcatовская функция условия. Буквально, если $f_sqr  существует, и не ноль, то выводить $f_sqr, иначе выводить «нет».

В Оптивебе задача вывода полей ложится на хрупкие плечи программиста. Технологу всего то и остается, что показать где быдет выводиться модуль, и настроить шаблон. Выглядит шаблон так же, как шаблон навигации, то есть имеет струкртуру list-elem-cond. List для вывода «Параметров дома» такой:


<!--#list src='item.paramList'-->
 <h3>Параметры дома</h3>
 <table>
 <tbody>
 <!--#elem-->
 <!--#cond-->
 return $elem->get('list.key') % 2 == 0;
 <!--#endcond-->
 <tr class="odd">
 <td><!--#slot src='name'--></td>
 <td><!--#slot src='value'--></td>
 </tr>
 <!--#endelem-->
 <!--#elem-->
 <tr>
 <td><!--#slot src='name'--></td>
 <td><!--#slot src='value'--></td>
 </tr>
 <!--#endelem-->
 </tbody>
 </table>
<!--#endlist-->

Красим табличку «зеброй»:


return $elem->get('list.key') % 2 == 0;

Берем номер эмемента, если остаток от деления на 2 = 0, то выводим код внутри <!--#elem-->, если не подходит, то переходит к следующему элементу. <!--#slot src='value'-->  аналог переменной (например: $f_sqr в Netcat), задается при наполнении внутри CMS.

Вместо эпилога

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

The end.

Субботин Александр
14 декабря
На мой взгляд главная ошибка во многих CMS - это создание собственных шаблонизаторов. Получается, для каждой CMS необходимо изучать свой "птичий язык", когда намного удобнее знать основы пхп и применять их.
Про удобство - с неткатом я не работал, и с оптивебом тем более, но самая удобная из всех CMS с которыми я сталкивался - это ModX. Ну и конечно же, хранить шаблоны в базе данных - не разумно:)
Фитискин Александр
15 декабря
Александр, шаблонизатор для того и нужен, чтобы отделить php и контент друг от друга. Это нужно во первых для того, чтобы с шаблонизатором могли работать далекие от php люди + для того, чтобы исключить всякую возможность в шаблоне писать код, который программист поленился осуществить в модуле. Чем меньше проникновения кода в шаблон — тем он логичнее, понятнее и надежнее. OptiWeb в этом случае не идеален, проникновение кода в шаблон в нем тоже есть, но оно довольно малое и о нем не все знают :)
draft
31 декабря
Александр, учитывая вышенаписанное, уже все знают ))
Максим
2 Февраля
Добрый день.
Как можно ознакомиться с вашей CMS/F?
Сейчас использую CMF Djem, доволен! Один недостаток: дорогая лицензия!
Вот ищу альтернативу.
NetCat, Amiro, Host... разочарование. (