Drupal Forms API. Часть 1 — для Drupal 6

    image
    Данная статья предназначена для тех, кто уже знаком с написанием простейших модулей, и хотел бы разобраться в принципах работы FAPI (Drupal Forms API) «на пальцах». В ней, мы разберем основы друпаловского программного интерфейса создания форм, и составим небольшой модуль, возвращающий введенное имя при помощи аяксового движка Друпала, именуемого AHAH. Как раз для этой простой формы нам и понадобится FAPI.

    Зачем статья на эту тему? В сети, и на Хабре в частности, есть несколько примеров модулей с FAPI. Для меня в прошлом представляло определенное затруднение разобраться в том, как создаются формы — и такое объяснение «на пальцах» очень бы мне пригодилось. Я не могу вернуться в прошлое — но могу помочь тем, кто испытывает подобные затруднения.

    Статья соответствует 6.x версии Друпала. Я планировал в статье осветить параллельно и 7 версию — но отличие в API существенно, поэтому я опишу тот же фунционал для 7 версии API во 2 части статьи.



    Зачем использовать формы FAPI?


    Естественно, можно написать форму в виде HTML и просто напечатать ее на странице, или присоединить ее к модулю как include — файл. Но если использовать FAPI, появятся следующие преимущества:
    1. Форма сможет пользоваться средствами валидации, темизации Друпала, его яаксовой системой AHAH (AJAX, начиная с 7 версии Друпала).
    2. Форма сможет переводиться, прогоняясь через интерфейс перевода через функцию t().
    3. Форму можно предоставить для редактирования другим модулям через хук.
    4. И, что немаловажно, форма будет отформатирована согласно общим правилам форм Друпала, что сделает ее более «родной» для ее последующей темизации.


    Создадим простейший модуль


    Назовем наш модуль fastcontact. Создадим папку /sites/all/modules/fastcontact — это будет корневая папка нашего модуля. В ней, создадим два файла — fastcontact.info и fastcontact.module — этого будет достаточно.

    В .info — файл впишем:

    ; "Человеческое" имя модуля
    name = Fast Contact
    ; Описание для списка модулей
    description = Test module for learning FAPI     
    ; Версия модуля
    version = "6.x-1.0" 
    ; Версия поддерживаемого ядра Друпала
    core = "6.x" 
    ; "Машинное" имя модуля
    project = "fastcontact"
    ; Раздел в списке модулей
    package = "Other"
    ; Дата создания модуля
    datestamp = "1294001844"
    


    Теперь, можно перейти к коду, описывающему форму.

    Формы и элементы форм FAPI


    Каждая форма описывается в виде функции. Функция фозвращает массив с элементами формы. Каждый элемент массива соответствует элементу формы, обладает именем, и содержит в себе массив атрибутов этого элемента. Сводная таблица элементов и их атрибутов доступна для ознакомления на сайте Drupal API.

    Создадим простую форму с одним текстовым полем.

    function fc_form() {
      $form = array();
      
      // Элемент формы 'name'
      $form['name'] = array(
        // Текстовое поле
        '#type' => 'textfield',
        // Переводимое описание элемента
        '#description' => t('Ваше имя'),
        // Размер элемента              
        '#size' => '25',                                  
      );
      
      // Элемент с именем 'submit'
      $form['submit'] = array(
        // И типом Submit (кнопка отправки формы)
        '#type' => 'submit',
        // Надпись на кнопке
        '#value' => 'Submit',   
        // Элемент AHAH (Аякс в Друпале 6)
        '#ahah' => array(
          // Отреагирует на click (событие из JQuery)
          'event' => 'click',
          // Путь, куда будет передана заполненная форма
          'path' => 'fastcontact/js',
          // Оболочка формы для вывода результата
          'wrapper' => 'fc-form',
          // Метод вывода результата (метод JQuery)
          'method' => 'append',
          // Эффект JQuery для применения вывода
          'effect' => 'fade',
          // Вид прогрессбара
          'progress' => array('type' => 'throbber'),       
        ),
      );
      return $form;
    } 
    


    Таким образом, будет создана форма с текстовым полем и кнопкой submit, работающей на аяксе (AHAH).

    Обработка запроса


    Теперь, нам нужно создать функционал по обработке АНАН-запроса. Для этого, нужно создать путь, указанный в атрибуте path элемента ahah (в форме мы указали путь 'fastcontact/js'). Это делается через hook_menu().

    Друпал использует модуль menu даже тогда, когда в «меню» как таковое ничего не попадает. Но он хранит в себе пути страниц. Элементы меню также создаются через массив.

    /**
     * Используем hook_menu()
     */
    function fastcontact_menu() {
      // Элемент меню с соответствующим путем
      $items['fastcontact/js'] = array (
        // Функция, которая будет "обрабатывать" путь
        'page callback' => 'fastcontact_ajax',
        // Права на доступ к пути
        'access arguments' => array('access content'),
        // Элемент не будет отображаться в меню сайта
        'type' => MENU_CALLBACK, 
      );
      return $items;
    }
    


    Мы указали MENU_CALLBACK в качестве типа элемента меню, так как не хотим, чтобы по этому пути можно было перейти по ссылке из меню сайта (это ведь путь для обработки запроса).

    Наша функция обработки запроса не имеет прямого отношения к работе форм, поэтому не изощряясь, мы просто вернем ее назад через AHAH, чтобы показать, что модуль работает.

    /* Обработка запроса */
    function fastcontact_ajax() {
      // Получаем имя из переменной $_POST
      // Хорошая практика фильтровать на предмет зловредного кода через check_plain()
      $name=check_plain($_POST['name']);
      // И готовим его для вывода на экран в оболочке формы для вывода результата (мы указали fc-form)
      $output = 'Вы ввели имя <i>'.$name.'</i>.';
      // Возвращаем флаг успеха операции и наш обработанный ответ
      drupal_json(array('status' => TRUE, 'data' => $output));
    }
    


    Отображение формы


    Теперь, нам осталось собрать форму и сделать все необходимое для ее рендеринга. Сначала, составим функцию, которая будет отображать нашу форму. Для этого будет использоваться drupal_get_form().

    /* Рисуем форму */
    function render_fc_form() {
      // Вот мы и рендерим форму
      $out  = drupal_get_form('fc_form');   
      return $out;
    }
    


    Мы могли бы создать блок через hook_block() — но чтобы не усложнять, мы можем просто создать блок с фильтром ввода и отобразить форму через php-код:

     echo render_fc_form(); 


    Ожидаемый результат работы модуля


    В случае успешной работы кода, под формой ввода появится фраза «Вы ввели имя ...», где вместо троеточия будет стоять введенное вами имя, без перезагрузки страницы.
    • +18
    • 7,6k
    • 5
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

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

      0
      Спасибо за статью )
        +1
        Очень доступно написано.
        Хотя если используем AHAH я бы отключил action по умолчанию.
          0
          Спасибо. Я старался сделать стать как можно доступнее и проще, даже не смотря на то, что это создаст вопросы или даже возражения, типа «А где валидация?» «Почему форма всего лишь возвращает имя?» «А почему не проработан вариант без джаваскрипта?». С другой стороны, если сделать это, статья станет гораздо сложнее. Поэтому я все-таки выбрал вариант, в котором даются основы, в расчете на то, что при написании конкретного модуля человек будет строить уже дальше на этом примитивном основании. Мне в свое время именно такой примитивной статьи не хватало чтобы разобраться, понять суть процесса.
            0
            Аналогично. Формы постигал на основе статьи 10 шагов к формам и форума коммьюнити.
          0
          Фокус с работой этой формы без js мне кажется достаточно важным для понимания основопологающего свойства форм в Друпале. Там доработки то совсем чуть чуть, зато будет ясен алгоритм создания форм. Самое главное что нужно понять про формы, это то что билд формы происходит как при первом ее показе, так и при сабмите.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое