Шаблоны интерфейсов в FBI.
Основные принципы
Основная работа по созданию интерфейсов в FBI состоит в связывании бакендов с формами (основной вариант HTML-формы, но ничто не мешает работать с другими интерфейсами). Формы описываются при помощи так называемых шаблонов. Существует два основных приёма работы:
1. Связывание шаблона с URL. При обращении браузера по данному URL происходит запуск связанного с ним шаблона и генерация требуемых форм.
2. Регистрация шаблона по имени. При обращении браузера по данному URL происходит запрос бакенда-спутника (с префиксом template) с именем равным первой компоненте пути. Например при обращении по URL a/b/c запрашивается бакенд template-a. У бакенда выясняется (через вызов операции template) имя шаблона и параметры к нему после чего собственно и производится запуск требуемого шаблона и передаются ему требуемые параметры.
Замечание: путь / приравнивается к /index.
Замечание: при наличии двух вариантов одновременно система отдаёт предпочтение первому.
Второй способ удобен в случае когда администратор выполняет некоторую типовую задачу, совершенно не хочет задумываться о создании какого-либо интерфейсного шаблона, но отлаживать желает уже в некотором интерфейсе. Существуют два заранее подготовленных шаблона: object (для работы со свойствами объекта), list (для работы с группой объектов). В этом варианте работы возможно не создавать отдельного бакенда, а разместить обработку операции template и связанных с ней в основном бакенде и сделать на него символическую ссылку с именем template-<бакенд>.
Первый способ предпочителен на этапе создания законченного продукта с удобным дизайном пользовательского интерфейса. В этом случае вполне возможно что основной дизайн страниц выполняется отдельным человеком.
Возможно сочетание обоих способов работы, когда в особых случаях создаются специализированные формы, а в случае повторения интерфейсов делаются заранее готовые шаблоны.
Замечание: В связи с последним предложением – заказывайте шаблоны, если они будут чётко формализованные – сделаем и добавим в пакет.
Создание и регистрация шаблонов
Файл шаблона размещается в каталоге /usr/share/alterator/templates/. Описание шаблона представляет собой маленькую программу на языке програмирования Scheme (нет никаких проблем в будущих версиях сделать возможной разработку шаблонов на произвольных языках программирования)
Каждый шаблон представляет собой функцию, в результате исполнения которой получается строка – она и отдаётся в качестве ответа Web-браузеру.
Регистрация шаблона по адресу:
- (register-get-url <url> <url-template-proc>) – регистрация процедуры-обработчика запросов <url-template-proc> как шаблона связанного с адресом <url>, возможно задание группы адресов при помощи регулярного выражения. Данная процедура будет вызываться в случае запроса GET (запрос на получение интформации).
- (register-post-url <url> <url-template-proc>) – регистрация обработчика для запроса POST (запрос на изменение информации).
Каждая процедура <url-template-proc> принимает следующие параметры:
- url – URL по которому было произведено обращение
- url-args – параметры запроса. В случае запроса POST url-args также включают в себя данные формы. В случае наличия одинаковых параметров в строке запроса и в форме предпочтение отдаётся вторым.
Регистрация шаблона по имени:
- (register-get-template <name> <name-template-proc) – регистрация процедуры-обработчика запросов <name-template-proc> как шаблона с именем <name>. Данная процедура будет вызываться в случае запроса GET.
- (register-post-template <name> <name-template-proc>) – регистрация обработчика для запроса POST.
Каждая продедура <name-template-proc> принимает те же параметры что и <url-template-proc> и ещё один дополнительный:
- template-args – параметры шаблона, переданные бакендом-спутником.
Генерируем HTML
Как было сказано, результат каждой процедуры обработчика – генерация строк. В случае работы с HTML – соответственно надо сгенерировать содержимое Web-страницы.
Замечание: Все дальнейшие процедуры работают с XHTML, соответственно крайне рекомендуется проверять страницу с помощью xmllint прежде чем работать с ней дальше, fbi пока даёт не слишком вразумительный ответ в случае неправильного XML.
HTML – можно генерировать вручную, а можно воспользоваться накопленным опытом предыдущих поколений. Рассмотрим все эти варианты.
1. Использование функции format.
Полный аналог функции C printf – осуществляет форматированный вывод в строку. Синтаксис формата отличается от принятого в C, вместо % используется знак, возможны следующие варианты:
- % – перевод строки
- A – вывод выражения как если бы использовалась команда display (проще говоря красивый вывод)
- S – выыод выражения как если бы использовалась команда write (вывод так чтобы потом можно было прочитать обратно read, например строки выводятся закавыченные)
2. Использование функций html: и @:
Поскольку каждый раз рисовать открыающие и закрывающие теги очень не удобно, можно воспользоваться функцией html:. В качестве первого параметра передаётся имя тега, а далее передаются параметры и содержимое создаваемого контейнера. Параметры создаются с помощью фунеции @. Первый параметр этой функции – имя (символ), второй – значение (строка).
3. Использование семейства функций html:* :
Создавать html уже стало легче, но в лучших традициях Scheme для самых распространённых элементов существуют заранее подготовленные функции:
- html:input – создание строки ввода, принимает два параметра – имя и значение. Возможна передача дополнительных параметров.
- html:textarea – создание текстового поля, принимает два параметра – имя и значение. Возможна передача дополнительных параметров.
- html:select – создание поля выбора, принимает три параметра – имя, текущее значение и список возможных вариантов.
- html:a – создание гипер-ссылки, первый параметр – текст внутри ссылки, все остальные параметры склеиваются в URL, к URL автоматически добавляется в начале путь к скрипту, поэтому для создания гиперссылок лучше всего именно этой функцией, а ручное создание оставить на исключительные ситуации.
- html:tr – создание «строки» в таблицы. Каждый из принятых параметров автоматически огружается тегами td. Например (html:tr “a” “b”) равносильно строке "<tr><td>a</td><td>b</td></tr>".
Замечание: На этом количестве функций можно не останавливаться. Если будут какие пожелания – заказывайте.
4. Использование html-шаблонов.
Даже при наличии большого количества функций высокого уровня рисовать html не так удобно. Остаётся ещё масса тегов которые приходится таскать с собой «в нагрузку». Кроме того, давайте дадим поработать дизайнеру (или программе nvu). Загрузка готовго html-шаблона происходит командой template.
Если файл менять не надо, то на этом можно и остановиться, но так бывает крайне редко. Зачастую требуется заполнить форму реальными данными или вообще пересоздать её в зависимости от требований пользователя. Говоря языком разработчика – требуется «наложить заплатку» (patch) на html-файл. Для указания тега с которым надо провести дополнительную работу используется команда *tag:*, первый обязательный параметр команды – имя тега.
В примере выше будет произведена замена содержимого внутри всех тегов p. Если требуется уточнить теги с какими параметрами должны подлежать обработке, то эти параметры указываются в привычном уже синтаксисе:
В этом примере будет произведена содержимого внутри тегов div с атрибутом ' class="a" ' на слово “class a”, а содержимое тегов div с атрибутом ' class="b” subclass="c” ' станет «class b/c”.
Возможно не только замена содержимого тегов, особые виды операций указываются в виде параметра 'template-operation. Возможны варианты: replace-content (по-умолчанию), append-content (добавить новое содержимое), replace-tag (заменить весь блок отмеченный данным тегом на что-то новое).
В этом примере теги div с классом “will-be-replaced” будут заменены на теги p с содержимым new-content, а в таблицу будет добавлена новая строчка. Но на этом возможности по изменению не заканчиваются. В качестве нового содержимого можно указать процедуру принимающую один параметр options, тогда в случае нахождения требуемого тега, процедура исполнится с options, равным полному набору атрибутов найденого тега. Таким образом можно например делать custom теги управляемые параметрами.
В этом примере все теги custom будут заменены параграфом содержащим перечисление их атрибутов.