Механика FBI.
Основные принципы
В общих чертах всё работает следующим образом. В системе
висит alterator с модулями ensign (управляет бакендами) и fbi
(управляет фронтендами). Доступ к alterator осуществляется через
локальный UNIX-Socket. Рядом настроен http сервер и cgi
в нём. При поступлении http-запроса, в cgi происходит
декодирование, разбор нужных переменных среды, после чего работа
передаётся alterator. Alterator выясняет по адресу к какому
backend обращались, выясняет у его напарника (template-*) желаемый
frontend и передаёт ему запрос. Frontend делает всё
что ему требуется, в том числе запрашивает у backend
нужные подробности, берёт html-шаблон, модифицирует
его и отправляет ответ наверх. CGI принимает запрос,
преобразует в настоящий html, подправляет по ходу урлы
и отдаёт результат пользователю.
Замечание: путь / приравнивается к /index.
Каждый frontend регистрирует две функции, на обработку get и на обработку post запросов.
Данная инструкция должна быть последней в тексте frontend (по аналогии с object для бакенда).
Каждая функция принимает следующие параметры:
- url – URL по которому было произведено обращение
- url-args – параметры запроса. В случае запроса POST
url-args также включают в себя данные формы. В случае наличия
одинаковых параметров в строке запроса и в форме предпочтение
отдаётся вторым. Их формат – список пар (параметр .
значение). Парметр – строка.
- template-args – параметры переданные
помощником бакенда специально для шаблона, чтобы задать
специфическое повееие. Формат – список пар (параметр . значение).
Параметр – символ.
Генерируем HTML
Как было сказано, результат каждой процедуры обработчика –
генерация строк. В случае работы с HTML – соответственно надо
сгенерировать содержимое Web-страницы.
Замечание: Все дальнейшие процедуры работают
с XHTML, соответственно крайне рекомендуется проверять страницу
с помощью xmllint прежде чем работать с ней дальше,
fbi пока даёт не слишком вразумительный ответ в случае
неправильного XML.
Замечание: cgi квотирует все строки
переданные ему со стороны frontend, поэтому не пытайтесь
создавать теги вручную
1. Использование функций
html: и
@:
Поскольку каждый раз рисовать открыающие
и закрывающие теги очень не удобно, можно воспользоваться
функцией html:. В качестве первого параметра передаётся
имя тега, а далее передаются параметры и содержимое
создаваемого контейнера. Параметры создаются с помощью фунеции @.
Первый параметр этой функции – имя (символ), второй – значение
(строка).
2. Использование семейства функций
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>".
Замечание: На этом количестве функций можно не останавливаться. Если будут какие пожелания – заказывайте.
3. Использование 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 и content, тогда в случае нахождения требуемого тега,
процедура исполнится с options, равным полному набору атрибутов
найденого тега и content, содержащим внутреннее содержимое тега
в виде s-выражения. Таким образом можно например делать custom
теги управляемые параметрами.
В этом примере все теги custom будут заменены параграфом
содержащим перечисление их атрибутов. При желании процедуры
можно свободно перемешивать с обычным содержимым.
Интернационализация
Браузеры могут сообщать свой предпочитаемый язык. Можно этим
воспользоваться и сделать многоязычные интерфейсы. Делается
это следующим образом.
1. Отмечаем интересующие фрагменты текста тегами span с параметром
translate “_". Значение параметра translated – просто некоторое
ключевое слово. Задавая разные ключевые слова можно забирать переводы
фраз из разных словарей.
2. Поскольку xgettext не умеет вытаскивать переводы,
то пользуемся утилиткой alterator-xgettext в комбинации
с обычными xgettext.
3. В месте использования template добавляем инструкции для перевода
translate-tag:, первый параметр – ключевое слово, второй параметр – имя словаря.
Замечание: если захочется ещё чего-то странного – пишите, заказывайте.