Формы в Joomla

Рассматриваем принцип работы форм в Joomla.

Форма в Joomla - это по сути XML-файл (манифест), описывающий содержимое формы. Файл манифеста заполняется типами полей, которые содержат метаданные этих полей, а также данные о фильтрации / валидации полей.

За обработку форм в Joomla отвечает пакет классов Form.

Использование форм

Гибкость форм в Joomla позволяет использовать их для различных целей. Чаще всего мы можем встретить использование форм для описания параметров конфигурации и установочных файлов расширений.

В типичном расширении Joomla формы используются для получения данных от пользователя, при этом файлы манифеста формы располагаются в папке forms расширения, а классы пользовательских полей в папке fields.

Если мы создаем компонент, то для работы с формами в Joomla существуют специальные MVC классы, которые упрощают работу с формами. Например, FormController или FormModel.

Концепция XML-файла формы

В форме есть три основных понятия: группа полей (fields), набор полей (fieldset) и поле (field).

Группа позволяет группировать поля и наборы полей. При получении данных формы каждой группе присваивается своё значение в виде массива полей.

Набор полей объединяет общие поля и может рассматриваться так же, как набор полей HTML. По сути это группировка полей для удобства их вывода, которая никак не влияет на значение при получении данных формы.

Между группой и набором поддерживается двухсторонняя вложенность, то есть группа может быть вложена в набор и наоборот.

Поля описывают отдельные поля формы. При определении полей важно определять только одно поле с заданным именем на группу.

Пример ниже иллюстрирует эти понятия:

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fields name="myGroupOfFields">
        <fieldset name="myFieldSet">
            <!-- Здесь определяются поля -->
<pre><code>    </fieldset>
    <fieldset name="myOtherFieldSet">
        <!-- Здесь определяются поля -->
    </fieldset>
</fields>

Определение полей формы

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

Стандартные поля

По умолчанию в Joomla имеется довольно большое количество полей, которые покрывают практически все случаи использования. Вот так выглядит определение текстового поля myTextField:

<field
    type="text"
    name="myTextField"
    id="myTextField"
    label="MY_TEXT_FIELD_LABEL"
    description="MY_TEXT_FIELD DESCRIPTION"
    class="myTextFieldClass"
    size="80"
    maxLength="255"
/>
  • Атрибут type (тип) является обязательным и используется для определения того, какой тип поля мы описываем.
  • Атрибут name(имя) также обязателен, это имя используется для передачи входных данных на сервер.
  • Атрибут id (идентификатор) не обязателен. Если мы не укажем идентификатор, будет использован атрибут name.
  • Атрибут label (метка) - это обязательный атрибут, отображаемый в виде HTML метки, а необязательный атрибут description (описание) используется как заголовок HTML метки. Значения в этих двух атрибутах переводятся классом Text, поэтому задаются в верхнем регистре.
  • Атрибут class задаёт CSS-класс поля.
  • Атрибуты size и maxLength являются специфическими для текстового поля. Они определяют размер отображения поля и максимальную длину любого значения, введенного в поле.

Давайте посмотрим на чуть более сложный пример, определение поля списков:

<field
    type="list"
    name="myListField"
    id="myListField"
    label="MY_LIST_FIELD_LABEL"
    description="MY_LIST_FIELD DESCRIPTION"
>
    <option value="0">OPTION_1</option>
    <option value="1">OPTION_2</option>
</field>

Это очень похоже на определение текстового поля. Здесь есть все те же атрибуты type, name, id, label и description. Дополнительно мы описываем значения опций списка, используя элементы option.

А вот как просто можно вывести поле редактора:

<field
    type="editor"
    name="myEditorField"
    id="myEditorField"
    label="MY_EDITOR_FIELD_LABEL"
    description="MY_EDITOR_FIELD DESCRIPTION"
    filter="safehtml"
    rows="5"
    cols="200"
/>

Полный список атрибутов поля можно найти здесь.

Пользовательский тип поля

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

Определение своего типа поля практически не отличается от определения стандартных полей:

<field addfieldpath="path/to/field"
    type="Custom"
    name="Custom"
    label="CUSTOM_FIELD_LABEL"
    description="CUSTOM_FIELD DESCRIPTION"
/>

Отличие от стандартного поля заключается только в типе поля и наличии атрибута addfieldpath, в котором указывается путь до расположения класса поля. Этот атрибут можно добавлять также к группам и наборам полей.

Подробнее о создании своего типа поля можно почитать в документации Создание своего типа поля.

А теперь, возвращаясь к нашему примеру XML-файла, давайте соберем всё вместе:

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fields name="myGroupOfFields">
        <fieldset name="myFieldSet">
            <field
                type="text"
                name="myTextField"
                id="myTextField"
                label="MY_TEXT_FIELD_LABEL"
                description="MY_TEXT_FIELD DESCRIPTION"
                class="myTextFieldClass"
                size="80"
                maxLength="255"
            />

            <field
                type="list"
                name="myListField"
                id="myListField"
                label="MY_LIST_FIELD_LABEL"
                description="MY_LIST_FIELD DESCRIPTION"
            >
                <option value="0">OPTION_1</option>
                <option value="1">OPTION_2</option>
            </field>
        </fieldset>

        <fieldset name="myOtherFieldSet">
            <field
                type="editor"
                name="myEditorField"
                id="myEditorField"
                label="MY_EDITOR_FIELD_LABEL"
                description="MY_EDITOR_FIELD DESCRIPTION"
                filter="safehtml"
                rows="5"
                cols="200"
            />

            <field addfieldpath="path/to/field"
                type="Custom"
                name="Custom"
                label="CUSTOM_FIELD_LABEL"
                description="CUSTOM_FIELD DESCRIPTION"
            />
        </fieldset>
    </fields>
</form>

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

Вывод формы пользователю осуществляется с помощью класса Form и FormField.

Сначала мы получаем объект класса формы:

$form = Form::getInstance('myform', $pathToMyXMLFile);

В качестве первого параметра мы передаем уникальное имя формы. Имя должно совпадать с названием XML-файла формы. Исходя из примера выше, название файла будет myform.xml, путь до которого указывается во втором параметре.

Объект формы кэшируется на основании имени формы. При следующем вызове формы с этим же именем мы получим уже сформированный объект.

Теперь мы готовы выводить поля формы. Самый простой способ, это пройтись циклом по наборам полей с применением методов класса Form:

foreach ($form->getFieldsets() as $fieldset)
{
    echo $form->renderFieldset($fieldset);
}

Если мы хотим получить более тонкий контроль над выводом полей, то можно использовать возможности класса FormField:

foreach ($form->getFieldsets() as $fieldset) 
{
    // Массив классов FormField
    $fields = $form->getFieldset($fieldset->name);    

    if (count($fields)) 
    {
        foreach ($fields as $field) 
        {
            // Вывод поля
            echo $field->renderField();

            // Вывод элементов поля
            echo $field->type;
            echo $field->label;
            echo $field->input;
        }
    }
}

Практически все стандартные поля Joomla поддерживают переопределение макетов вывода, которы должны располагаться в /templates/{активный_шаблон}/html/layouts/joomla/form:

  • field — папка для размещения макетов вывода полей;
  • renderfield.php - файл вывода поля;
  • renderlabel.php - файл вывода метки.

Фильтрация данных поля

Фильтрация данных - это возможность обезопасить ввод данных на уровне определения поля, путём добавления атрибута filter. Он может принимать такие значения как: int, word, safehtml, string, tel, email, url и другие.

По умолчанию ко всем полям применяется фильтрация, которая удаляет весь HTML-код.

Подробнее о фильтрах полей читаем здесь.

Валидация данных поля

Валидация данных делится на два типа: проверка на стороне клиента и проверка на стороне сервера.

Валидация на стороне клиента задается через добавление специального класса validate-* для поля.

Например, для валидации адреса электронной почты используем класс validate-email:

<field
    name="email"
    type="text"
    class="validate-email"
/>

При этом обязательно перед выводом формы необходимо подключить скрипты, ответственные за проверку:

HtmlHelper::_('behavior.formvalidator');

А самой форме задать класс form-validate:

<form class="form-validate"> ... </form>

Кроме стандартных типов валидации, мы можем создавать свои.

Подробнее о проверке на стороне клиента можно почитать в документации Валидация полей на стороне клиента.

Валидация на стороне сервера задается через атрибут validate. В качестве значения атрибута выступает правило (rule), которое определяет поведение проверки поля. Правила являются классами, которые наследуются от класса FormRule.

Кроме стандартных правил мы можем задавать свои, устанавливая путь до класса правила через атрибут addrulepath.

Подробнее о проверке на стороне сервера можно почитать в документации Валидация полей на стороне сервера.

© 2019 BinaryCraft. Все права защищены.