Создание формы
Пошаговое руководство: создание таблицы, настройка form_config, поля, уведомления, встраивание через Twig.
Создание формы
apidcms позволяет создавать формы обратной связи, заявок, заказов и любых других — без программирования. Всё настраивается через админ-панель.
Как это работает
Форма состоит из трёх частей:
- Таблица в БД — куда сохраняются заявки
- Запись в реестре форм (
forms) — конфигурация: поля, уведомления, дизайн - Шаблон — как форма выглядит (Twig)
После настройки форму можно встроить в любую страницу одной строкой в Twig-шаблоне.
Шаг 1. Создайте таблицу для хранения заявок
- В админке нажмите «Создать таблицу»
- Укажите название (например,
form_callback) - Добавьте поля под ваши данные:
name→TEXT— имяphone→TEXT— телефонmessage→TEXT— сообщение
- Обязательно добавьте служебные поля:
pd_consent→INTEGER, по умолчанию0— для галочки согласия на ПДread_status→TEXT, по умолчаниюunread— для отметки «прочитано/не прочитано»form_name→TEXT— заполняется автоматически, нужно для фильтрации
- Нажмите «Создать»
Шаг 2. Зарегистрируйте форму
- В боковом меню админки нажмите «Формы»
- Нажмите «Добавить форму»
- Заполните поля:
Основные
| Поле | Описание | Пример |
|---|---|---|
| Имя формы (name) | Техническое имя, латиницей | callback |
| Отображаемое имя | Как форма называется в админке | «Обратный звонок» |
| Таблица для данных | Имя таблицы из Шага 1 | form_callback |
| Шаблон | Файл .html.twig в form/ |
default (стандартный) или свой |
Поля формы (fields) — JSON
Описывает, какие поля будут в форме. Формат:
{
"name": {
"label": "Ваше имя",
"type": "text",
"placeholder": "Иван",
"required": true
},
"phone": {
"label": "Номер телефона",
"type": "tel",
"placeholder": "+7 (999) 123-45-67",
"required": true
},
"message": {
"label": "Комментарий",
"type": "textarea",
"placeholder": "Опишите ваш вопрос",
"required": false
}
}
Доступные типы полей: text, email, tel, textarea, select, checkbox, number, date.
Важно: имена полей в JSON должны совпадать с названиями колонок в таблице. Поля id, created_at, updated_at, read_status — системные, их добавлять в fields не нужно.
Уведомления (notifications) — JSON
{
"admin_notify": true,
"admin_emails": ["your@email.ru"],
"admin_subject": "Новая заявка с сайта",
"auto_reply": false
}
| Поле | Описание |
|---|---|
admin_notify |
Отправлять уведомление админу (true/false) |
admin_emails |
Список email для уведомлений |
admin_subject |
Тема письма |
auto_reply |
Отправлять автоответ пользователю |
auto_reply_field |
Из какого поля брать email пользователя |
auto_reply_subject |
Тема автоответа |
Дизайн (design) — JSON
{
"submit_text": "Отправить заявку",
"submit_class": "btn btn--primary",
"form_class": ""
}
| Поле | Описание |
|---|---|
submit_text |
Текст на кнопке отправки |
submit_class |
CSS-класс для кнопки |
form_class |
Дополнительный CSS-класс для <form> |
field_class |
CSS-класс для полей ввода |
label_class |
CSS-класс для подписей к полям |
Шаг 3. Встройте форму на страницу
В любом Twig-шаблоне используйте функцию render_form():
{{ render_form('callback', {template: 'default'}) }}
Где callback — это значение поля name из реестра форм.
Параметры render_form()
Все параметры опциональны — значения по умолчанию берутся из реестра:
{{ render_form('callback', {
template: 'modal', # свой шаблон формы
submit_text: 'Позвоните мне',
submit_class: 'btn btn-primary',
form_class: 'my-form',
action: '/form-handler', # URL обработчика (по умолчанию)
hidden_fields: ['utm_source'],
field_overrides: {name: {label: 'Имя и фамилия'}},
field_defaults: {utm_source: 'organic'}
}) }}
Галочка «Политика конфиденциальности»
Если в таблице формы есть колонка pd_consent (тип INTEGER, default 0) — чекбокс согласия на обработку ПД добавляется автоматически. Ничего дополнительно настраивать не нужно.
Чекбокс будет обязательным — пользователь не сможет отправить форму, не отметив его.
Ссылка в тексте ведёт на /privacy — убедитесь, что такая страница существует на вашем сайте.
Как это выглядит в шаблоне
Если вы используете стандартный шаблон default, чекбокс уже встроен. Если пишете свой шаблон — добавьте:
{% if show_consent %}
{% include 'form/fields/consent.html.twig' %}
{% endif %}
Шаблоны форм
В комплекте три готовых шаблона:
| Шаблон | Описание |
|---|---|
default |
Стандартный — с лейблами над полями, Tailwind-стили |
minimal |
Минимальный — меньше отступов |
hero |
Для лендингов — крупный, с заголовком |
Свой шаблон
Создайте файл front/app/views/form/мой_шаблон.html.twig и укажите его имя в поле template при регистрации формы (без .html.twig).
Пример минимального кастомного шаблона (без лейблов, только placeholder'ы):
{% extends "form/_base.html.twig" %}
{% block form_content %}
<form method="post" action="{{ action|default('/form-handler') }}"
class="my-form {{ form_class }}"
data-table="{{ source_table }}"
data-form="{{ form_name }}"
novalidate>
<input type="hidden" name="form_name" value="{{ form_name }}">
{% for field_name, field in fields %}
{% if field_name not in hidden_fields|default([]) %}
<input type="{{ field.type }}"
name="{{ field_name }}"
placeholder="{{ field.placeholder|default(field.label) }}"
{% if field.required %}required{% endif %} />
{% endif %}
{% endfor %}
{% if show_consent %}
{% include 'form/fields/consent.html.twig' %}
{% endif %}
<button type="submit">{{ submit_text|default('Отправить') }}</button>
</form>
{% endblock %}
Доступные переменные в шаблоне
| Переменная | Описание |
|---|---|
form_name |
Техническое имя формы |
fields |
Массив полей из конфига |
show_consent |
true если в таблице есть колонка pd_consent |
csrf_token |
Токен CSRF-защиты |
action |
URL обработчика |
submit_text |
Текст кнопки |
submit_class |
CSS-класс кнопки |
form_class |
CSS-класс формы |
source_table |
Имя таблицы с данными |
success_message |
Текст при успешной отправке |
Просмотр заявок
Все заявки собираются в разделе «Уведомления» админ-панели:
- Общий список: количество заявок по каждой форме, непрочитанные выделены
- Детально: список заявок конкретной формы, фильтрация, отметка «прочитано»
- Просмотр: отдельная заявка с возможностью удаления
- Бейдж: красный кружок в боковом меню показывает общее число непрочитанных
AJAX-отправка (без перезагрузки страницы)
По умолчанию форма отправляется обычным POST с перезагрузкой страницы. Для AJAX-отправки добавьте на страницу скрипт, который перехватывает отправку формы и шлёт запрос с заголовком X-Requested-With: XMLHttpRequest.
Сервер сам определит, что это AJAX, и вернёт JSON вместо редиректа:
{"success": true, "message": "Спасибо! Форма успешно отправлена.", "id": 42}
Пример скрипта (добавьте в конец Twig-шаблона страницы):
<script>
document.querySelector('form[data-table="form_callback"]')
.addEventListener('submit', async function(e) {
e.preventDefault();
var btn = this.querySelector('button[type="submit"]');
var orig = btn.textContent;
btn.disabled = true;
btn.textContent = 'Отправка...';
var resp = await fetch('/form-handler', {
method: 'POST',
body: new FormData(this),
headers: {'X-Requested-With': 'XMLHttpRequest'}
});
var data = await resp.json();
if (data.success) {
this.innerHTML = '<div style="color:green">' + data.message + '</div>';
} else {
btn.disabled = false;
btn.textContent = orig;
alert(data.message);
}
});
</script>
Из чего состоит форма (внутреннее устройство)
Пользователь заполняет форму
│
▼
POST /form-handler
│
▼
FormRenderer::processSubmission()
├─ Проверка honeypot (скрытое поле _hp_email)
├─ Проверка времени (форма открыта >3 сек)
├─ Валидация CSRF-токена
├─ Валидация полей (required, email-формат)
├─ Сохранение в таблицу (source_table)
├─ Отправка email-уведомлений
└─ Ответ: JSON (AJAX) или редирект (обычный POST)
Последнее обновление: 22 июля 2026 (v1.3.14)