Engine v4.1

Случайный афоризм:
«Не заботится о личной пользе» — слова эти просто фиговый листок. В сущности они значат: «Я разучился понимать, в чем моя польза». Человек погиб, раз он сделался альтруистом.

Ф. Ницше. «Сумерки кумиров или как философствовать молотом»

Engine v4.1

Q1. Что это такое и для чего оно нужно?

A1. Это база данных с методами для работы с ней, рассчитанная на хранение страниц сайта.

Особенностью базы данных является то, что она рассчитана на хранение произвольных, разнородных данных и может быть настроена через админ для конкретных целей.

Если вдруг выяснится, что одна или много страниц, которые нужно добавить к уже созданному на базе engine-а сайту кардинальным образом отличается от того, что уже было сделано - ничего страшного нет, база уже готова к этому и переделывать как правило ничего не нужно.

Q2. А можно кратко об основных концепциях ENGINE-a?

A2. Конечно.

Положение 1: В базе хранится дерево объектов. Каждый объект имеет родителя, таким образом они выстраиваются в древовидную структуру на сайте, и благодаря этому не нужно для каждого объекта хранить полный путь от корня сайта. Если мы изменили путь у родительского объекта, то и у его детей автоматически изменится полный путь на сайте и нам не нужно больше ничего править руками.

Положение 2: У каждого объекта есть фиксированный (но изменяемый) набор основных полей. Именно эти поля определяют основную функциональность объекта. Это то, что может быть специфично для сайта и то, над чем в первую очередь нужно думать, создавая таблицы. Основные поля обязательны, без них ENGINE жить не будет, а дополнительные мы можем создать описав их в файле _objects_additional_fields.cfg и ENGINE будет доставать данные из этих полей. Соответственно из обработчиков можно будет работать с ними.
Нужно помнить, что этот фиксированный набор работает существенно быстрее, чем динамические блоки данных.

Положение 3: К каждому объекту мы можем привязать обработчик (хоть для каждого объекта свой) который представляет собой код (парсерный) и который знает что нужно сделать с объектом чтобы сформировался его xml. По умолчанию, если не привязан никакой обработчик, результирующий xml формируется из xml всех блоков привязанных к объекту (без установленного флажка: «только при ручном вызове») + всех полей объекта + всег блоков глобальных объектов.

Положение 4: К каждому объекту мы можем привязать xsl шаблон (хоть для каждого объекта свой) который знает как преобразовать пришедший от обработчика страницы xml и сформировать окончательный результат (обычно html).

Положение 5: К каждому объекту мы можем привязать любое количество динамических блоков, мы может определить функциональность этих блоков с помощью написанных для них обработчиков (парсерный код). Обработчик блока знает что нужно сделать с данными содержащимися в блоке перед складированием их в общую пачку xml-данных объекта.

Положение 6: Для хранения дополнительных файлов объекта (например картинки меню, фотографии, описания, скачиваемые файлы и т.д.) используется структура на диске аналогичная структуре дерева сайта и загруженный файл попадает в каталог, который для каждого объекта свой.
Нигде в базе данных эти файлы не регистрируются, что позволяет использовать альтернативные методы работы с ними (ftp), позволяет легко найти/заменить/добавить/удалить файл(ы).

При изменении пути объекта в дереве его файлы автоматически перемещаются на новое место. Для работы с этими файлами есть методы, которые достают их по имени, маске и т.д. При этом не нужно указывать пути, т.к. для данного объекта они всегда однозначно определены.

Q3. Это наверное жутко навороченная и огромная структура, заранее заточенная под множество целей? Можно посмотреть структуру базы данных?

A3. Да вот она:
Engine v 4.1 database structure

Q4. Можно прокомментировать таблицы и поля в них?

A4. Да пожалуйста:

LANG:
В этой таблице хранится список языков, используемых в системе. Есть "специальный" язык с lang_id = 255. Блоки, у которых указан этот язык показываются во всех языковых версиях.

  • ABBR - двух символьная аббревиатура языка (ru, en, de, fr...)
  • CHARSET - кодировка, в которой выдаются языковые версии сайтов на данном языке
  • SORT_ORDER - порядок сортировки языков в системе
SITE:
В этой таблице хранится список сайтов, для которых в этой базе данных хранятся объекты.
  • NAME - название сайте
  • DOMAIN - домен сайта
  • LANG_ID - язык по умолчанию
  • ERROR_OBJECT_ID - id объекта, который будет показан если не было найдено объекта с запрошенным путем
  • CACHE_TIME - время кэширования документов для этого сайта «по умолчанию»
  • SORT_ORDER - порядок сортировки списка сайтов

SITE_TO_LANG:
В этой таблице хранится связки: какие языки на каких сайтах используются.

OBJECT_TYPE:
В этой таблице хранится список типов объектов.

  • NAME - название типа объекта
  • ABBR - символьная аббревиатура типа
  • IS_FAKE - признак что объект данного типа фиктивный, т.е. не имеет собственного представления на сайте
  • CONSTRUCTOR - инструкции, по которым будет происходить создание объектов данного типа
  • SORT_ORDER - порядок сортировки типов объектов в админе

OBJECT:
В этой таблице хранится информация об объектах без текстов.

  • PATH - путь объекта. Это не полный путь от корня, а кусочек пути. Если у объекта нет пути, он не может быть отображен на сайте (например, если это фиктивный объект или сервисный центр, у которого есть параметры, но который не имеет собственной страницы для отображения не сайте).
  • SITE_ID - сайт, которому принадлежит объект
  • OBJECT_TYPE_ID - тип объекта
  • PARENT_ID - «родитель» в дереве (если объект расположен в корне дерева, то parent_id = 0)
  • TEMPLATE_ID - xsl-шаблон, который будет использован при отображении объекта
  • DATA_PROCESS_ID - обработчик, который будет использован для обработки xml данных объекта перед применением xsl шаблона
  • IS_PUBLISHED - показывать объект на сайте или нет
  • IS_SHOW_IN_MENU - показывать объект в меню или нет
  • IS_SHOW_ON_SITEMAP - показывать объект на карте сайте или нет
  • URL - нужен, если объект в дереве есть на самом деле есть ссылка на страницу, расположенную на другом сайте
  • LINK_TO_OBJECT_ID - ссылка на другой объект. Если у объекта указана ссылка на другой объект, то при обращении к этому объекту будет показана информация объекта, на которого ссылается данный объект
  • LINK_TO_OBJECT_TYPE_ID - тип ссылки на другой объект. бывают разные ссылки.
  • CACHE_TIME - время жизни кэша для данного объекта
  • CONSTRUCTOR - инструкции, по которым будет происходить создание «дочерних» объектов
  • AUSER_ID - владелец объекта (для разделения доступа)
  • IRF - маска наследуемых прав (для разделения доступа)
  • THREAD_ID - object_id корневого объекта, заполняется автоматически. Нужно для увеличения быстродействия.
  • NESTING - на каком уровне находится объект. заполняется автоматически. Нужно для увеличения быстродействия некоторых специфических операций
  • DT_UPDATE - дата/время последней модификации объекта, заполняется автоматически.
  • FULL_PATH - полный путь объекта, заполняется автоматически. Нужно для увеличения быстродействия.
  • SORT_ORDER - порядок следования объектов на одном уровне/
  • ... - да, именно многоточие. Структура определяется детально для каждого конкретного случая, но engine уже будет уметь работать с ней, т.к. мы опишем дополнительные поля в файле _objects_additional_fields.cfg

OBJECT_TEXT:
В этой таблице хранятся тексты объектов.

  • OBJECT_ID - к какому объекту привязаны тексты
  • LANG_ID - на каком языке данные тексты
  • NAME - имя объекта
  • WINDOW_NAME - title страницы (если не определен, берется NAME)
  • DOCUMENT_NAME - заголовок (h1) страницы (если не определен, берется NAME)

TEMPLATE_TYPE:
В этой таблице хранится список типов шаблонов. От типа шаблона зависит что можно с ним делать. Например, шаблон документа можно привязать к объекту, а «вспомогательный шаблон» можно только видеть/редактировать в админе и делать import из других шаблонов.

  • NAME - название
  • SORT_ORDER - порядок сортировки

TEMPLATE:
В этой таблице хранятся шаблоны для отображения объектов. Шаблон не имеет понятия о том, какие xml-данные ему придется отображать, он не хранит их. Он знает что нужно сделать с xml-данными, которые ему передают.

По сути шаблон есть файл на диске, а в базе хранится только ссылка на этот файл.

  • TEMPLATE_TYPE_ID - тип шаблона.
  • NAME - название шаблона. Оно показывается в списке, и по нему ориентируются, когда выбирают шаблон
  • DESCRIPTION - описание шаблона. Комментарий, но он очень важен, чтобы не приходилось открывать файл с шаблоном и из кода выяснять, что делает тот или иной шаблон.
  • FILENAME - имя файла, который лежит в каталоге /templates/
  • DT_UPDATE - дата/время последней модификации шаблона
  • SORT_ORDER - порядок сортировки

TEMPLATE_GROUP:
В этой таблице хранятся группы шаблонов. Фактически имеется возможность одни и те же данные преобразовать в разное визуальное представление. Например, одни и те же данные могут быть выданы в виде обычной html версии, в виде версии для печати, в виде plain text версии или в версии для WAP броузеров.

Это делается с помощью групп шаблонов.

  • NAME - название
  • DESCRIPTION - описание
  • DIRECTORY_NAME - имя подкаталога в каталоге /templates/ в котором лежат шаблоны данной группы
  • SORT_ORDER - порядок сортировки

DATA_PROCESS_TYPE:
В этой таблице хранится список типов обработчиков. От типа обработчика зависит, что он может делать. Например, обработчик страницы знает как и из чего нужно сформировать данные страницы перед xsl-трансформацией, а обработчик блока знает что нужно сделать с данными блока перед помещением их в общую кучу xml-данных страницы.

  • NAME - название типа (например: Обработчик страницы, Обработчик блока)
  • SORT_ORDER - порядок сортировки

DATA_PROCESS:
В этой таблице хранятся обработчики объектов и блоков: код на парсере. Обработчик не имеет понятия о том, как будут показаны данные, но он знает как их нужно модифицировать. Один обработчик эти данные пропустит через типографику, а другой - на основании переданных ему данных определит заголовки страницы, третий воспримет эти данные как параметры и на их основании достанет и отобразит заголовки новостей и т.д.

Обработчик - это файл на диске, а в базе данных хранится только ссылка на этот файл.

  • DATA_PROCESS_TYPE_ID - тип обработчика. нужно фактически только для внутренних целей. Чтобы к объектам можно было привязывать только обработчики страниц, а к блокам - блоков.
  • NAME - название обработчика. Оно показывается в списке, и по нему ориентируются, когда привязывают обработчик
  • DESCRIPTION - описание обработчика. Комментарий, но он очень важен, чтобы не приходилось открывать файл с обработчиком и выяснять его функционал из кода.
  • FILENAME - имя файла, который лежит в каталоге /processes/ и где хранится код обработчика.
  • DT_UPDATE - дата/время последней модификации кода обработчика
  • SORT_ORDER - порядок сортировки обработчиков

DATA_TYPE:
Описание типов данных, которые бывают в блоке. Используется только в административном интерфейсе, чтобы при редактировании разных данных иметь разные возможности.

  • NAME - название типа данных (например: Дата, Число, Строка...)
  • ABBR - абревиатура, по которой в специальном классе ищется код для редактирования блока в админе и сохранения изменений
  • DESCRIPTION - описание типа данных блока
  • SORT_ORDER - порядок сортировки

BLOCK:
Самое интересное. Все данные, которые мы можем выделить из документа по каким-либо критериям есть блоки, принадлежащие объекту.

  • DATA - тут лежат сами данные, вне зависимости от их типа. Это может быть xml, текст и т.д.
  • DATA_TYPE_ID - тип данных в этом блоке. Определяет, как именно в админе будет редактироваться содержимое данного блока.
  • DATA_PROCESS_ID - обработчик, который привязан к блоку.
  • NAME - имя блока. Именно по имени мы обращаемся к блокам из обработчика и именно его имя принимает участие в формировании xml блока! Существуют групповые операции для блоков («вытащить все блоки начинающиеся на main и обработать их», операции с одним блоком: «достать блок с именем main и обработай его», операции извлечения блоков: «дай мне список блоков текущего объекта», «дай мне список блоков вот этого объекта» и т.д.)
  • DESCRIPTION - описание блока. Например, этот блок для объекта новость называется «тело новости», и в админе он будет виден как «тело новости», а для обращения он будет иметь имя, ну например, body.
  • IS_PUBLISHED - показывать блок на сайте или нет. Например для временного отключения блока.
  • IS_SHARED - блок может быть использован другими объектами, не редактируемое поле.
  • IS_HIDE_PUBLISHED - флажок для запрещения отображения в админе поля IS_PUBLISHED.
  • IS_PARSED_MANUAL - блок будет обработан только при ручном вызове его из обработчика или другого обработчика блока
  • IS_NOT_EMPTY - 1, если поле data не пустое. Нужно для ускорения обработок, не редактируемое поле
  • DT_UPDATE - дата последней модификации данных в блоке.
  • мы вызовет обработку такого блока, то они правильно обработаются в заданном порядке.
  • ATTR - пока не используются

BLOCK_TO_OBJECT:
Связи определяющие какие блоки принадлежат каким объектам.

  • SORT_ORDER - порядок сортировки. Т.к. поле для сортировки находится в таблице BLOCK_TO_OBJECT то два shared блока могут быть отсортированы по разному для разных объектов.

LANG_TO_BLOCK:
Указание, на каком языке данный блок.

EVENT_LOG:
Таблица, в которой хранятся записи обо всех событиях по модифицированию сайта, совершенных в административной интерфейсе.

  • REFERRER_TYPE - с какой таблицей производились изменения: object, block, data_process, template...
  • REFERRER_ID - id записи, которая изменялась
  • AUSER_ID - идентификатор пользователя, кто совершил действие (если включен разделенный доступ)
  • DT - дата и время совершения операции
  • EVENT_TYPE - тип изменения: INSERT, UPDATE или DELETE
  • STAT - результат выполнения операции. если 0, то операция завершилась успешно
  • EDITOR - строка с IP/HOST того, кто производил изменения
  • CONTENT - пока не используется

Q5. Тут что-то упоминалось про CACHE_TIME, но получается, что для того, чтобы определить время кэширования объекта нам уже нужно лезть в базу? А подключение к БД достаточно медленная операция. Разве это хорошо?

A5. Да, несомненно, это плохо, именно поэтому ENGINE не использует такой метод :)

CACHE_TIME используется для хранения этой информации и на основании неё при любой модификации объектов в БД автоматически создается cfg-файл. А вот уже на основании этого cfg-файла работают механизмы кэширования, и при отображении страницы из кэша не подключаются даже основной класс engine (который занимает ~ 78 КБ).

Q6. Все это здорово, но не говорите, что может быть удобно редактировать новости компании и, например, список дилеров одним механизмом. Да, он может быть универсальным, но при этом он не будет удобным для всех случаев.

A6. Согласен. Поэтому следует помнить о следующих вещах:
  • Все таки всегда можно все редактировать из основного средства редактирования, которое универсальное, но не всегда удобное.
  • Основное средство редактирования включает в себя конструкторы, которые существенно облегчают управление данными. Если у нас в разделе news лежат новости и после создания объекта-новость мы должны создать 4 блока с определенными именами/описаниями, то мы можем определить это в конструкторе родителя, и после создания нового объекта он сразу будет содержать эти поля, и иметь необходимые параметры объекта (обработчик, шаблон, тип...)
  • Можно создать специализированные средства редактирования, которые будут управлять содержимым частей дерева и выполнять там специфические вещи, скрывая от редактора такие операции как создание блоков объекта, задание их типов и т.д.
  • Структуры, которые неудобно хранить в дереве объектов можно вынести в отдельные таблицы БД и механизмы по извлечению этих данных и отображению их поместить в соответствующие обработчики.

Q7. А какие отличия имеет версия 4 от предыдущей версии?

A7. Отличия следующие:
  • Кодировка, в которой работает административный интерфейс и в которой хранятся все файлы теперь UTF-8.
  • Добавлена поддержка многодоменности: в одном административном интерфейсе теперь можно управлять несколькими сайтами.
  • Добавлена поддержка многоязычности: в системе можно завести несколько языков и указать что на одном сайте есть русская и английская языковые версии, а на другом - английская и немецкая.
  • Появился import/export объектов.
  • Для каждого языка можно указать в какой кодировке выдавать страницу броузеру.
  • Все тексты административного интерфейса теперь вынесены в отдельные xml файлы, и чтобы добавить ещё один язык в административный интерфейс достаточно перевести два текстовых файла. Уже доступны русская, английская, болгарская и украинская версии административного интерфейса.
  • Изменения в API методов, используемых в обработчиках. Теперь не бывает таких конструкций: ^parseBlock[body;13;;;noXml], вместо этого нужно писать так: ^parseBlock[body;$.object_id(13)$.no_xml(1)]
  • Теперь доступна не только информация о времени и авторе последних изменений объектов и блоков, а все операции по изменению объектов, блоков, обработчиков, шаблонов и типов данных.
  • Теперь выдается правильный заголовок last-modified, поэтому броузеры могут нормально кэшировать страницы.
  • Удалена таблица BLOCK_TEMPLATE. Заголовки блоков теперь хранятся в таблице BLOCK без привязок к объектам
  • Появились групповые операции над объектами
  • К существовавшим ранее типам данных ("строка", "число", "флаг", "дата") добавлены новые: "файл", "изображение", "изображение с превью", "список объектов", "разделитель"

Q8. И что? Прямо все так круто и нету недостатков?

A8. Конечно есть! Во первых это все-таки медленный доступ к данным, обусловленный их блочной структурой. Это отчасти решается кэшированием и внутренней реализацией ENGINE-а (вытаскивание всех таблиц template и data_process, а не постоянные join к ним, кэширование шаблонов, обработчиков, объектов, блоков, компиляция обработчиков...), но все равно для работы с интенсивно обновляемыми данными следует искать другой путь. Во вторых... А хватит. Недостатков можно придумать много, как многие из них можно обойти, если все делать с умом. Следует не забывать, что ENGINE может работать на сайте рядом с любыми другими системами доступа к данным.

Что или уже изменил или изменю в самое ближайшее время:
  • таблицы template и data_process объединятся, т.к. суть одна: записи в этих таблицах описывают файлы, лежащие на диске.

P.S. На самом деле не все так плохо, для построения типовой страницы производится примерно 10 достаточно простых SQL запросов. Все запросы используют индексы и выполняются достаточно быстро.

Краткое описание доступных механизмов engine-а:

  1. Посмотреть xml объекта можно следующим образом: http://domain/url/?mode=xml
  2. Посмотреть неопубликованный документ можно так: http://domain/url/?mode=preview
  3. Получить debug информацию можно так: http://site_url/doc_url/?mode=debug
    При этом в файл /../data/sql.txt запишется информация обо всех sql запросах, которые были сделаны при формировании страницы с указанием времени их выполнения и количеством использованной ими памяти.
  4. В админе есть механизмы, позволяющие выполнять бакап БД, проверять её на наличие ошибок и автоматически исправить некоторые из них.
  5. В админе есть механизм, позволяющий копировать объекты с разными опциями (копировать только параметры объекта, параметры объекта + структуру блоков, параметры объекта + структуру блоков с их содержимым)
  6. В админе есть механизм, позволяющий делать import/export объектов
  7. В админе не производится загрузки сразу всех объектов и отображения дерева сайта целиком. Куски дерева подгружаются по мере необходимости (загрузка xml), таким образом управлять структурой из 5000 страниц не намного медленнее, чем из 50 страниц.
  8. Сортировка объектов. Объекты показываются на сайте в том виде, в котором они видны в админе. А отсортированы они могут быть примитивным drag & drop-ом.
  9. Кэширование страниц. Страницы кэшируются автоматически. Не кэшируются страницы, если на них идет отправка данных методом POST или если установлено время кэширования 0 (логику несложно изменить)
  10. Для всех документов выдаются корректные заголовки last-modified и expires. При этом сами заголовки кэшируются вместе с телом страницы специальным классом. Уменьшается количество запросов, а так-же исходящий с сервера траффик (и входящий трафик пользователей). Правда тем, кто пишет обработчики, приходится делать дополнительные телодвижения.
  11. Кэширование шаблонов/обработчиков. Данные о зарегистрированный с системе шаблонах кэшируются на диске. Кроме этого информация обо всех шаблонах/обработчиках разом загружается в память (но не код), таким образом спасаемся от большого количества join-ов.
  12. Компиляция обработчиков. При обработке блока, к которому привязан обработчик происходит компиляция текста обработчика и при обработке последующих блоков, к которым привязан этот обработчик, используется уже скомпилированный код и не происходит повторный process текста обработчика. Это существенно ускоряет обработку.
  13. Кэширование обращений к объектам/блокам. Если у нас обработчик обращается к одному блоку 5 раз, то этот блок достается из базы данных только один раз. Более того, при обращении к первому блоку объекта достаются и запоминаются все его блоки (одним запросом). Обращения к последующим блокам не производят запросов в БД. Тоже самое касается объектов: если мы достаем объекты какого-либо треда, а потом независимо, в другом обработчике достаем данные объекта, который уже был в этом треде - повторных запроса к БД не будет.
  14. Упреждающее кэширование блоков. При вызове типовых методов, в некоторых случаях сразу после доставания из БД объектов происходит доставание всех их блоков. Этот механизм также дает большое сокращение количества запросов к БД.
  15. Типы данных блоков. Если нам нужен блок, в котором будет храниться всего лишь одна строка, не имеет смысла смотреть на эту строку в textarea. Можно указать у блока при его создании тип - строка, и поле для редактирования будет занимать меньше места. При копировании/создании конструктора тип блока будет учтен. Кроме того есть сложные типы данных, позволяющие загрузить изображение/файл и добавить к нему описание. Дополнительные типы данных могут быть добавлены при необходимости.
  16. Есть такое понятие, как «shared блок», это блок, использующийся одновременно двумя или более объектами. Физически, в базе хранится одна копия блока, и изменение этого блока у одного объекта приводит к его изменению во всех местах. Иногда требуется, чтобы одинаковые данные присутствовали у нескольких объектов, тогда решение, лучшее чем copy/paste - это shared блок. В этом случае, при исправлении данных нам надо править их в одном месте. Тело этого блока в админе показывается на «сереньком фоне», и при onfocus выдается предупреждение, что это shared блок (можно отключить). Следует помнить, что обработка shared блока осуществляется в контексте объекта, из какого вызывается блок. Например, если в блоке есть конструкция <file alias="file.pdf" ..., и блок принадлежит объектам А и Б, то для корректного вывода ссылки на файл он должен присутствовать у обоих объектов (или у <file/> должен быть прописан атрибут object-id).
  17. Конструкторы. Они созданы для облегчения создания новых объектов. Это своего рода шаблоны для создания новых объектов. Например, если у объекта А есть конструктор, то когда мы создаем у этого объекта ребенка, выполняется этот конструктор и ребенок получает все параметры, которые описаны в конструкторе родителя. Если у объекта А нет конструктора, но у нас определен конструктор для объекта типа "документ", то в случае, если мы создаем ребенка-директория у объекта А, то блоки к этому объекту приделаны не будут, а если создаем ребенка-документ - будут. Конструктор родительского объекта полностью перекрывает конструктор типа объекта.
  18. По умолчанию при обработке блоков происходят следующие преобразования:
    <img alias="image.gif".../> -> <img src="/off-line/.../image.gif" width="xx" height="xx" .../> (если файла не существует - тег вставлен не будет)
    <file alias="file.zip".../> -> <file src="/off-line/.../file.zip" ext="zip" size="размер файла" icon="/i/icons/zip.gif" icon-width="xx" icon-height="xx" .../>
    <a alias="image.gif">xxx</a> -> <a href="/off-line/.../image.gif">xxx</a> (если файла не существует - ссылка поставлена не будет)
    <a object-id="123">xxx</a> -> <a href="/Путь_К_Объекту_с_object-id/">xxx</a>
    <a object-id="123"/> -> <a href="/Путь_К_Объекту_с_object-id/">Название объекта с object-id</a>
    <parser:variable [form|env|request|response]="имя" /> или {$parser/[form|env|request|response]/имя} -> добавит в заданное место значение из $form:имя, $env:имя, $request:имя или $response:имя соответственно
  19. Если в админе указать у объекта URL («Ссылка на другой сайт»), то при выдачи информации о дереве объектов (<branches ..>) будет выдан не реальный URI этого объекта на данном сайте, а тот, что указан в этом поле
  20. Если в админе указать «ссылку на объект», то в случае обращения к этому объекту выдастся информация не по этому объекту, а по тому, куда указывает ссылка, при этом дерево сайта будет показывать, как будто мы находимся в контексте запрошенного объекта.
  21. По умолчанию, при обращении к странице, выдаются следующие данные (xml): текущая дата (info/date), информация о посетителе (info/client), все поля текущего объекта (document), информация о корневых объектах и текущей ветке объектов (<navigation><branche .../>...<navigation>), и данные обо всех блоках, привязанных к объекту (если у объекта есть блоки body и title, то будет выдано: <body>содержимое body</body><title>содержимое title</title>)
  22. Для того, чтобы обработать блок текущего объекта в обработчике нужно написать ^parseBlock[имя блока] при этом, если у нас существует несколько блоков с указанным именем, то обработаются они все в последовательности, заданной в админе.
  23. Если нам нужно обработать блок другого объекта, нужно написать:
    ^parseBlock[имя блока;$.object_id(id объекта)]
  24. Если нам надо обработать несколько блоков по маске (regexp) нужно написать:
    ^parseBlockByMask[маска]

Updated: 29.06.2007



© 1998 — 2017