API делает возможной специальную темизацию всех форм (включая формы из основных модулей). Эта специальная темизация становится возможной, когда все элементы, темизация которых жестко задана в коде, будут выделены, так что их можно переписать в процессе создания формы. Выделение производится при помощи следующих методов:
Это атрибуты '#prefix' и '#suffix', что поместит заявленную разметку либо до, либо после указанного элемента.
Например, данный код
поместит теги div до и после всей группы формы (что означает, что элементы формы тоже будут заключены в div). Если вы вставите эти атрибуты внутрь одного из элементов формы, размещенного в группе, то они обернут только данный элемент, и т.д.
Существует тип '#markup', который вы можете разместить в любом месте формы, и его значение будет выводиться непосредственно в указанном месте в иерархии формы, когда та будет обрабатываться. Например:
Этот элемент разметки формы затем может быть извлечен или обработан по его имени в массиве 'div_tag'.
ОБРАТИТЕ ВНИМАНИЕ: здесь нет никакой необходимости точно указывать #type, поскольку даже если он опущен, по умолчанию используется 'markup'.
Выделение разметки в отдельную функцию темы. Это особенно предпочтительно, если разметка достаточно сложна. Это делается при помощи создания функции темы с приставкой theme_ к имени ID формы, которую нужно темизировать. В случае, если вы хотите иметь одинаковую функцию темизации для более чем одной формы, вы можете включить дополнительный аргумент обратного вызова в drupal_get_form—в этом случае третий аргумент drupal_get_form будет строкой, содержащей имя функции обратного вызова, которая будет вызываться при создании формы, и имя функции темизации будет предваряться приставкой theme_
Пример:
Для формы, которую мы создали выше, мы следующим образом можем создать функцию темизации:
Несколько замечаний:
API формы имеет общий способ проверки формы, который применяется ко всем отправленным формам. Если при отправке формы нужно провести дополнительную проверку, вы можете для этого создать функцию. Именем этой функции является ID формы с приставкой _validate после него. Функция имеет два аргумента - $form и $form_state. $form является массивом проверяемой формы, а $form_state['values'] содержит значения формы, которые вы хотите проверить. (На заметку – в более сложном случае несколько форм могут иметь общих _validate или _submit функций – так что если нужно использовать несколько ID форм, их можно извлечь из $form['form_id']['#value'] или $form_state['values']['form_id'].)
Здесь приведен пример функции проверки правильности заполнения для нашего кода:
Отправка формы
Обычным методом отправки формы через API является использование функции отправки. Ее название использует те же соглашения для наименований, что и функция проверки, за исключением того, что имеет сзади приставку _submit. В любую форму, которая отправляется кнопкой type => 'submit', будет вставлена соответствующая функция отправки, если она существует.
Пример:
Несколько замечаний:
Если форма имеет функцию отправки, вам не нужно использовать скрытые значения формы. Вместо этого любые значения, которые вам нужно добавить в $form_state['values'], могут быть объявлены следующим образом:
Затем его можно извлечь из $form_state['values']['foo'] со значением bar. Такой метод является более предпочтительным, поскольку значения не передаются в броузер.
Для того чтобы определить, на какую страницу пользователь должен перейти после отправки формы, функция _submit может в form_state['redirect'] содержать путь или URL, которые являются целью drupal_goto; каждая форма после отправки будет перенаправлять пользователя туда. Если вы ничего не сохраняете в form_state['redirect'], пользователь после отправки формы будет перенаправлен на ту же страницу. Для того чтобы сообщить пользователю, что отправка формы прошла успешно, принято использовать drupal_set_message().
Важным понятием Form API по сравнению с использованием необработанных HTML форм (которые использовались в Drupal 4.6 и ранее) является то, что функция drupal_get_form()обрабатывается как при создании, так и при отправке формы. Это означает, что созданный в вашей функции массив сначала будет строиться при вызове формы, а потом при ее отправке.
Практически это означает, что многие разработчики сразу зададут себе вопрос «А где же хранятся мои данные?». Ответ прост – нигде. Вы одновременно вставляете данные в форму, возможно, грузите объект из базы данных и заполняете значения в #default_values, и затем построитель формы сверяет все это с тем, что было объявлено. Однако то, что вы получите таким методом, будет обрабатываться FormsAPI безопасным образом. Подмена POST становится намного более сложной, поскольку такой метод не позволяет значениям, которые реально не были в форме, через массив $form_state['values'] попасть в функции отправки и поля 'select', поскольку проверка гарантирует, что значение реально существовало при его выборе. Если это не так, форма будет отклонена. Кроме того, по умолчанию Drupal к каждой форме добавляет секретные символы, которые могут защитить против XSRF атак.