Категория:XML

Материал из ISPWiki
Перейти к: навигация, поиск


Введение

Все описания форм, таблиц, меню и сообщения панели управления хранятся в XML-файлах в каталоге /usr/local/mgr5/etc/xml. Все используемые панелью XML-файлы написаны в кодировке UTF-8. Результатом выполнения панелью управления любой операции изначально также является документ XML.

Мы не рекомендуем изменять файлы XML, которые идут в комплекте с панелью управления. Но, тем не менее, вы можете добавлять собственные формы и таблицы, добавлять или убирать поля существующих форм с помощью механизма Плагинов и Событий.

Данная статья посвящена описанию файлов XML, используемых панелью управления.

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

атрибут if
Определяет условие (Feature), при котором этот элемент доступен.
атрибут before
Определяет, перед каким элементом должен быть размещен этот элемент. В случае, если этот атрибут задан, панель просматривает все элементы находящиеся в том же контексте и помещает этот элемент перед одноименным элементом, у которого значение ключевого атрибута совпадает со значении атрибута before.
атрибут after
аналогичен before, но элемент будет размещен после указанного.
атрибут first
допустимое значение - "yes". Элемент будет размещен первым в списке.
атрибут last
допустимое значение - "yes". Элемент будет размещен последним в списке.
атрибут level
вы можете использовать этот атрибут для любого элемента внутри metadata и mainmenu, чтобы указать, какой уровень доступа должен быть у пользователя, чтобы увидеть те или иные данные. Помимо удаления элементов из metadata будут удалены и данные, которые соответствуют этим элементам. Для элемента col, описывающего столбец в таблице, все соответствующие элементы из строк таблицы. Для input, select, slider, textarea, text, htmldata - соответствующие элементы верхнего уровня. Атрибут может содержать несколько значений разделенных пробелом. Каждое значение имеет следующий формат:
  • цифра от 0 до 31 - уровень доступа
  • строка - имя уровня доступа или маски
  • символ '+' после цифры или строки означает, что доступ должен быть не ниже указанного. При этом строка должна представлять имя уровня, а не маску.

В CORE существует ряд зарегистрированных имен:

  • nobody доступ с уровнем 0
  • super доступ с уровнем 30
  • admin доступ с уровнем 29
  • reseller доступ с уровнем 24
  • user доступ с уровнем 16
  • all маска - любой пользователь
  • registered маска - пользователь с доступом выше 0 (прошедший авторизацию)

Например, следующие записи аналогичны: nobody+, all, 0+

Для элементов metadata и mainmenu алгоритм обработки атрибута level отличается.

Ключевые арибуты

При загрузке данных из XML-файлов панель объединяет одинаковые элементы. В этот момент объединяется содержимое элементов и их атрибуты. Одинаковыми считаются элементы находящиеся в одном контексте, имеющие одинаковое имя и, возможно, одинаковое значение ключевого атрибута. Для большинства элементов это атрибут name. Часть элементов, например такие как: toolsep, jscript, if, else - не объединяются никогда.

При загрузке XML-файлов панель никак не меняет содержимое следующих элементов (анализ вложенных элементов не производится): jscript, func, event, query и msg.

Метаданные (metadata)

Метаданные служат для описания элементов интерфейса панели. Каждый элемент metadata описывает один элемент интерфейса.

атрибут type
Тип элемента интерфейса. Может принимать значения form (описывает форму ввода), list (описывает список данных), report (описывает отчет).
атрибут name
Задаёт имя функции, которую описывает данный элемент.
атрибут helpurl
Если присутствует этот элемент, то значение ссылки "помощь" берется из этого атрибута.
атрибут level
Указывает, для каких пользователей доступен этот элемент интерфейса (функция, имя которой указано в атрибуте name). Формат значения атрибута описан во введении.
атрибут secured
Если значение "yes" - данные будут спрятаны в ответах на запросы авторизованные по COOKIE, но содержащие неверный REFERER
элемент include
Позволяет добавить в элемент metadata содержимое другого элемента metadata. Имя включаемого элемента должно быть указано в атрибуте name. При загрузке metadata, имя которого было указанного в include, происходит обработка всех условий накладываемых атрибутами: if, after, before, first, last (т.е. изменение порядка узлов). Т.е. порядок узлов в подгружаемой через include XML будет изменен до объединения. Исключение сделано для metadata, имя которых начинается с префикса label_. Для таких metadata обработка атрибутов (if, after, before, first, last) не производится. Условия будут обработаны после объединения документов.
элемент externalscript
Служит для загрузки браузером кода JavaScript из внешних файлов.

Главное меню (mainmenu)

На данный момент реализована двухуровневая система. Все элементы меню обязательно должны быть сгруппированны по разделам. Разделы не должны содержать подразделов.

Пример описания главного меню для CORE:

<mainmenu level="30" startpage="session">
  <node name="srvset">
    <node name="product" action="product" type="list"/>
  </node>
  <node name="stat">
    <node name="session" action="session" type="list"/>
    <node name="journal" action="journal" type="list"/>
    <node name="longtask" action="longtask" type="list"/>
  </node>
  <node name="set">
    <node name="brand" action="brand" type="form"/>
    <node name="usermenu" action="usermenu" type="list"/>
    <node name="usrparam" action="usrparam" type="form"/>
  </node>
  <node name="mgrhelp">
    <node name="changelog" action="changelog" type="list"/>
    <node name="handbook" function="http://ru.5.ispdoc.com/index.php/core-handbook-30"/>
  </node>
</mainmenu>
атрибут level
Какой уровень доступа описывает данное меню.
атрибут startpage
Имя страницы, открываемой по умолчанию. Необходимо указать имя функции из главного меню. Если не указано, будет автоматически подставлено имя первой первого попавшегося пункта меню ссылающегося на список.
элемент node
Описывает элементы меню и его подразделы.

Для меню атрибут level является ключевым. Но, при формировании меню для конкретного уровня доступа, происходит объединение всех доступных на этом уровне элементов mainmenu.

Например, если вы хотите добавить элемент меню для всех уровней доступа, вы можете написать следующее:

  <mainmenu level="registered">
    <node name="stat">
      <node name="mystat" first="yes"/>
    </node>
  </mainmenu>

Данный XML код добавит элемент меню mystat в раздел stat (раздел stat будет создан, если его нет) для пользователей всех уровней (level="registered"). Причем mystat станет первым элементом в рзделе stat (first="yes").

Элемент меню (элемент node)

Элемент node описывает элемент меню (нет дочерних узлов), либо его раздел (дочерними node описываются элементы).

атрибут name
Имя функции, которую необходимо вызвать. Кроме того, служит для привязки к языкам.
атрибут type
Задает тип функции. Возможные значения: list или form. Этот атрибут подставляется автоматически.
атрибут action
Задает имя функции, которую необходимо вызвать. Данный параметр подставляется автоматически для тех пунктов, которые ссылаются на функции панели. Его значение копирует значение атрибута name.
атрибут function
Задает URL, по которому необходимо перейти. Этот параметр задается автоматически, если в панели заведена внешняя функция (extaction) с именем заданным в атрибуте name.

Элемент меню с именем handbook обрабатывается особым образом. Если существует такой элемент, вызывается функция help с параметроми topic=handbook и level=<уровень доступа текущей сессии>, которая должна вернуть URL. Этот URL будет подставлен в атрибут function.

Описание языков и переводы (lang)

Пример описания текстовых надписей CORE на английском языке (часть файла core_msg_en.xml):

  <lang name="en">
    <messages name="label_langs">
      <msg name="bg">Български</msg>
      <msg name="cn">汉语</msg>
      <msg name="cs">Český</msg>
      <msg name="de">Deutsch</msg>
      <msg name="en">English</msg>
      <msg name="es">Español</msg>
      <msg name="fi">Suomi</msg>
      <msg name="fr">Français</msg>
      <msg name="hu">Magyar</msg>
      <msg name="jp">日本語</msg>
      <msg name="ku">کوردی</msg>
      <msg name="nl">Nederlands</msg>
      <msg name="pl">Polski</msg>
      <msg name="pt">Português</msg>
      <msg name="ru">Русский</msg>
      <msg name="th">ภาษาไทย</msg>
      <msg name="ua">Українська</msg>
      <msg name="xx">Developer</msg>
      <msg name="zh">中文</msg>
    </messages>
    <messages name="usrparam">
      <include name="label_langs"/>
      <msg name="addr">Allowed IP-addresses</msg>
      <msg name="atallow">allow for listed IP-addresses</msg>
      <msg name="atany">allow for any IP-address</msg>
      <msg name="atype">Access to the control panel</msg>
      <msg name="button">Icons</msg>
      <msg name="buttontext">Icons and captions </msg>
      <msg name="buttonview">Toolbar view</msg>
      <msg name="confirm">Re-enter password</msg>
      <msg name="email">E-mail for notifications </msg>
      <msg name="hint_rows">Enter the number of rows per page that will be displayed by default</msg>
      <msg name="hint_startpage">Select a page that will be displayed once you log in to the control panel</msg>
      <msg name="hint_theme">Select the theme that will be used to display the control panel</msg>
      <msg name="hint_timezone">Select the time zone for your region </msg>
      <msg name="lang">Language</msg>
      <msg name="msg_error_notuniqueemail">The selected e-mail is already used </msg>
      <msg name="msg_passwd">Password do not match!</msg>
      <msg name="name">Username</msg>
      <msg name="password">Password</msg>
      <msg name="recordlimit">Number of records </msg>
      <msg name="rows">Rows per page</msg>
      <msg name="startpage">Start page</msg>
      <msg name="text">Text</msg>
      <msg name="theme">Theme</msg>
      <msg name="timezone">Time zone</msg>
      <msg name="title">General settings</msg>
      <msg name="title_new">General settings</msg>
    </messages>
  </lang>
атрибут name
Код описываемого языка. Например: en, fr, ru, es.
элемент messages
Описывает сообщения для определённой функции.

Описание сообщений для функций (элемент messages)

атрибут name
Имя описываемой функции.
элемент msg
Содержит сообщение.
элемент include
Импортировать сообщения из указанной секции.

В CORE существует ряд специальных секций messages. Они используются даже несмотря на то, что значению их атрибута @name не соответствует ни одной функции:

alert
Набор сообщений для банеров
common
Набор общих сообщений
msgerror
Набор сообщений для описания ошибок
form
Набор общих сообщений используемых в формах и отчетах
list
Набор общих сообщений используемых в списках и отчетах
report
Набор общих сообщений используемых в отчетах

Описание сообщения (элемент msg)

атрибут name
Имя сообщения.

Элемент не имеет дочерних узлов. В нём содержится текст сообщения.

Подсказки (hint)

Многие элементы интерфейса имееют текстовые подсказки (hint), которые всплывают при наведении. Они описываются в локализованных сообщениях, и имеют имя с префиксом hint_. Помимо plain текста подсказки могут содержать html теги, которые будут корректно отображаться.

Например, можно вставить в подсказку ссылку:

  <msg name="hint_multiselect">Можно выбрать более одного <a href="http://ru.5.ispdoc.com/" target="_blank">элемента</a></msg>

Или выделить особо важный текст:

  <msg name="hint_multiselect">Можно выбрать <span style="color:red;">более</span> одного элемента</msg>

Стоит помнить, что html теги должны быть валидны как xml теги.

Внешние обработчики (handler/library)

CORE manager предоставляет гибкий механизм для всевозможных изменений в поведении системы. Для написания логики таких модификаций вы можете использовать внешние обработчики написанные на любом языке программирования или библиотеки (shared libraries) написанные на C++.

Для описания внешних обработчиков используется элемент handler:

<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
  <handler name="lastlogin" type="cgi">
      <event name="auth" after="yes"/>
  </handler>
</mgrdata>
атрибут name
имя исполняемого файла, который должен находиться в каталоге addon
атрибут type
тип взаимодействия с обработчиком. Возможные значения: cgi и xml. В первом случае обработчик вызывается с использованием интерфейса CGI, он получает все данные через переменные окружения, а в стандартный поток ввода ему запишут содержимое POST запроса. При использовании типа xml, обработчик также получит все данные через переменные окружения и содержимое POST запроса с стандартный поток ввода. Плюс, после содержимого POST запроса он получит xml документ сформированный на данный момент для ответа на запрос. В обоих случаях результатом выполнения должен быть правильный xml документ записанный в стандартный поток вывода. В первом случае он будет объединен с xml документом сформированным внутри панели, во втором - полученный xml документ полностью заменяет собой тот, что был сформирован ранее.
элемент event
определяет функцию, на вызов которой будет срабатывать обработчик. Функция должна существовать. Если вы хотите определить новую - используйте элемент func.
элемент func
создает новую функцию панели (имя функции задается атрибутом @name этого элемента) реализация логики которой полностью ложится на ваш обработчик.

Для загрузки собственной библиотеки используется элемент library. Следующий xml приведет к загрузке библиотеки test из каталога lib:

<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
  <library name="test"/>
</mgrdata>

Обработчики событий (элемент event)

CORE manager позволяет не только добавлять собственные обработчики для событий, но и определять порядок их вызова. Для этого у элемента event существует ряд атрибутов:

атрибут priority
определяет порядок вызова обработчика. Может принимать значения before и after, для вызова обработчика перед или после базового (см. атрибут @base)
атрибут base
задает имя базового обработчика, относительного которого определен порядок атрибутом @priority. Если базовый обработчик не задан, то при @priority=before обработчик будет добавлен в начало очереди, а при @priority=after - в конец. Подробнее про значение этого атрибута можно узнать тут.

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

Если не существует обработчика, указанного в атрибуте @base, значение атрибута игнорируется.

Визуальное редактирование интерфейсов

Для удобства создания XML-описания, нами создан режим разработчика.

Кэширование

В связи с достаточно большой сложностью алгоритма обработки метаданных, панель не работает с исходными XML файлами напрямую. Используется двухуровневая система кэширования.

[code]sbin/xmlinstall --manager <manager> --meta-cache [--apply][/code]

На первом этапе мы объединяем все XML документы согласно правилам. Затем полученный xml делится на файлы (по одной metadata/messages в файле). Данный кэш перестраивается при запуске панели, если изменилась контрольная сумма исходных документов. Полученные XML документы сохраняются в каталог var/.xmlcache/<manager>.X, где X - число 0 или 1. ' Создается ссылка var/.xmlcache/<manager>, которая указывает каталог, который используется панелью в данный момент времени. Второй каталог используется для предварительного кэширования.

На втором этапе происходит обработка различных директив include, изменение порядка узлов согласно правилам, добавляются пропущенные сообщения из других модулей и т.п. Полученный результат сохраняется в каталоге var/.xmlcache/<manager>.X/checked. Он перестраивается в случае изменения набора возможностей (feature) панели или при перестройке всего кэша.

Предварительное кэширование