Работаем с CGI::FormBuilder

| Комментариев: 5 | Нет трекбэков

CGI::FormBuilder  - очень удобный модуль для работы с web-формами, особенно когда в проекте их много, и в них много элементов. При этом он активно используется в связке с Catalyst'ом, но им можно пользоваться и отдельно, что я и рассмотрю в этой заметке. Модуль работает в связке с TT или HTML-Template, и кажется, он работает даже с Mason.

Итак, для наглядности создадим небольшую форму для обратной связи с помощью данного модуля. Будем использовать HTML-Template для обработки шаблонов (при этом нам не надо отдельно загружать данный модуль, CGI-FormBuilder будет использовать его абсолютно прозрачно для пользователя).

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


  11    my $form = CGI::FormBuilder->new(
  12                            source      => './feedback.fb',
  13                            messages    => './messages.ru',
  14                            template    => './feedback.html',
  15                            title       => 'Форма обратной связи',
  16                                      );

Создаем объект для работы с формой. Рассмотрим опции переданные в конструктор new.

Source - указывает путь к файлу-шаблону формы

Message - указывает путь к файлу-шаблону для сообщений JavaScript, которые выводятся при проверке формы на валидность (по умолчанию модуль выводит сообщения на английском языке, и если вам нужна локализация - указываете нужный файл, о его формате я расскажу позже)

Template - указывает путь к файлу-шаблону HTML-Template

Title - это уже один из параметров для шаблона HTML-Template

Теперь напишем небольшой блок условий, для обработки добавленной формы:


  20    if ($form->submitted && $form->validate) {
  21           $form->title('Успешно добавлено');
  22           $in{name} = $form->field('name');
  23           $form->tmpl_param(user  => $in{name});
  24           print $form->confirm template => './success.htm');
  25    }
  26    else { 
  27            print $form->render(sticky => 1);
  28    }

 

Методы CGI-FormBuilder submitted и validate возвращают true, если форма отправлена и прошла проверку, в противном случае возвращаем форму. Параметр sticky => 1 позволяет сохранить уже введенные пользователем данные и не очищать форму («приклеивает» значения формы).

Итак, если форма добавлена, мы перезаписываем title страницы с информацией типа «Успешно добавлено». Затем получаем из формы значение поля name, для этого используется модуль CGI. (NB: модуль предполагает использование CGI.pm для работы с входными/выходными данными, в данном случае я использую его так: use CGI qw (param header)).

Вот собственно и весь код по отображению формы. Теперь перейдем к написанию шаблонов.

Начнем с шаблона формы feedback.fb

# метод пост, заголовок не отправлять

method: POST

header: 0

 

# define fields

fields:

# имя

    name:

        label:      Ваше имя

        # type:       text по умолчанию

        size:       30

        style:      background:#FFF39C;text-align:right;

        required:    1

 

# E-MAIL

    email:

        label:      Эл. почта

        size:       30

        validate:   EMAIL

        style:      background:#FFF39C;text-align:right;

        required:    1

 

# сайт

    domain:

        label:      Ваш сайт

        size:       30

        validate:   /^.+\.ru/

        style:      background:#FFF39C;text-align:right;

        required:    1

 

# сообщение

    message

        label:      Сообщение

        type:       textarea

        rows:       5

        cols:       50

        style:      background:#FFF39C;text-align:right;

        required:    1

 

 

# Кнопка сабмита             

submit:  Отправить вопрос

 

Язык описания шаблона формы - YAML, довольно простой и удобный, для интересующихся отправляю на википедию. Несколько пояснений:

- LABEL необходим для того чтобы JavaScript при генерации ошибок выдавал не имя формы из HTML (тэг name), а что-то человекопонятное.

- TYPE - по умолчанию text, для типа select можно передавать ссылку на массив в опции options

  type:       select

        options:    \&return_sources

При этом опция options: принимает ссылку на функцию, которая и возвращает нужный формат данных (return_sources - обычная функция описанная в теле основного скрипта, и не вызываемая оттуда, а просто описанная там в блоке sub {} )

-          REQUIRED - опция принимает 0 или 1, и определяет является ли поле обязательным к заполнению

-          STYLE - custom стиль для элемента

-          VALIDATE - проверка для поля, поддерживает уже предопределенные регэкспы типа: EMAIL, PHONE, INT и т.п., а также custom регэкспы (никак не отвяжусь от этого custom...)

Опции также предусматривают custom JavaScript, То есть написанный прямо в этом файле в опциях конкретного поля.

Думаю, достаточно о шаблонах для формы, теперь к шаблону HTML.

Шаблон почти полностью повторяет стиль HTML-Template, только для того чтобы прописать где будет у нас находиться конкретное поле (тэг input) пишем:

<td height=30> <b>Ваш email: *</b></td>

<td bgcolor=#ffffff> <tmpl_var field-email></td>

Для того чтобы определить границы формы (тэги <form> и </form>) используем:

<tmpl_var form-start> и <tmpl_var form-end>, соответственно.

Для того чтобы модуль CGI-FormBuilder генерил JS код, необходимо в тэгах <head></head> вставить:

<tmpl_var js-head>

Вот собственно и все.

Шаблон для custom-сообщений JS (messages.ru) выглядит так:

#

# messages.ru - messages for Russian

#

js_invalid_start    Обнаружено %s ошибок:

js_invalid_default  - Поле "%s" заполнено неверно

js_invalid_input    - Поле "%s" заполнено неверно

js_invalid_end      For more help, click the "Help" button

form_invalid_text   Форма заполнена неверно или с ошибками!

js_invalid_select   - Не выбрана опция "%s" из списка

js_invalid_textarea - Не заполнено поле "%s"

 

# - Это комментарии, а дальше просто описаны события и значения для них на русском. Не буду подробно расписывать эти события, я думаю вы без труда отыщите и не описанные мной.

Итак - наша форма готова и работает:

 

Форма обратной всязи

Обработка ошибки

Успешно добавлено!

Весь код описанный в заметке лежит здесь.

Резюме:

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

Нет трекбэков

URL для трекбэков: http://perlmonks.org.ru/cgi-bin/MT/engine/mt-tb.cgi/31

Комментариев: 5

Интересно, обязательно прочитая вдумчиво еще раз. На мой взгляд пока из того что я видел мне больше врего пока нравится HTML::FormHandler в плане гибкости и того, что мне требовалось.

Незнаю насчет HTML::FormHandler, но то что я увидел в exampl'ах на спан по этому модулю - на мой взгляд определение формы там внесено в код, в отличие от CGI-FormBuilder, где оно вынесено в шаблон. Хотя я не работал с этим модулем, и могу ошибаться неверно истолковав примеры, или они просто не слишком удачные.

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

Меня лично всегда пугала громоздкость таких решений как Catalyst, Moose и т.п. Если описание формы в коде - то разделение представления от контроллера уже менее гибкое.

Если пугает Moose, значит Perl6 заставит вас побороть эти фобии.
В случае HFH при описании используется syntactic sugar - по сути это тоже что и в FB только получаете все плюсы Moose. Если подвести итог, то можно сказать: Если решение позволяет вам реализовать ваши потребности, то это хорошее решение и за модой бежать не нужно.

Комментировать

Об этой записи

Сообщение опубликовано 15.10.2009 16:37. Автор — Monks.

Предыдущая запись — Очередная оценка популярности языков. Perl лидирует!

Следующая запись — Играемся со Skype из Perl (SkypeAPI)

Смотрите новые записи на главной странице или загляните в архив, где есть ссылки на все сообщения.

Страницы


 


 

Page copy protected against web site content infringement by Copyscape