Completion of posts, part 2
Дорабатываем новости, часть 2
Работа с формами - одна из самых частых задач встречающихся на пути web-разработчика. Необходимо хорошо знать возможности форм, уметь выстраивать их в нужной последовательности и понимать принципы работы. Тема эта сама по себе большая. Данный курс все же руководствуется шаблоном "быстрый старт", поэтому в данной главе мы разберем именно тот вариант работы с формой, который будет удобен в учебном проекте. Но я настоятельно рекомендую вам познакомиться с этим материалом как можно лучше. Тема в документации
Чтобы начать работать с формами нам нужно подключить соответствующий рецепт, для этого напишем
composer require form
.
Создавать форму будем на основе нашей единственной сущности - Post.
Для ее генерации все так же будем использовать maker'ом.
В консоли пишем php bin/console make:form
и далее имя формы.
В директории src=>Form
теперь находится форма под названием PostType.
Представляет она из себя метод configureOptions
- указывающий на пренадлежность формы к сущности, и метод buildForm
- билдер, в котором будем описывать поля формы, их тип и т.д.
Давайте немного изменим форму под наши нужды. Для начала закоментируем add('likes')
, т.к.
лайки будут ставить пользователи. Ну а поле body
будет представлять из себя textarea, что мы и укажем.
Обратите внимание на Textarea, должен быть указан следующий namespace
use Symfony\Component\Form\Extension\Core\Type\TextareaType
.
Теперь перейдем к контроллеру и создадим в нем метод createPost
,
и разберем что в нем есть.
use Symfony\Component\HttpFoundation\Request;
use App\Form\PostType;
/**
* @Route("/create_post", name="create_post")
*/
public function createPost(Request $request)
{
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
return $this->redirect('/');
}
return $this->render('post/create.html.twig', [
'form' => $form->createView()
]);
}
Первое, на что стоит обратить внимание это аргумент самого метода - Request
.
Напомню, что Symfony представляет из себя HTTP фреймворк, данные он получает из класса Request и отдаёт в виде Response.
Ответ мы принимаем переменной Request $request
, а методом
$form->handleRequest($request)
ниже по коду
его обрабатываем, получая имя формы, метод и т.д.
Что касается isSubmited и isValid думаю, понятно и без пояснений.
После того как форма прошла валидацию:
-
- с помощью
$manager = $this->getDoctrine()->getManager()
мы инициировали менеджер объекта для конкретной сущности, в нашем случае это Post. Он отвечает за сохранение объектов и выборку объектов из базы данных. -
- метод persist() в контексте
$manager->persist($post)
выполняет подготовку запроса. -
- метод flush() в
$manager->flush()
записывает в базу.
Я надеюсь никто из вас меня не возненавидит, в конце концов мы же учимся... Все дело в том, что подключив
maker, мы получили возможность генерации CRUD с помощью
php bin/console make:crud
.
Перед тем как приступить к заключительной части, нам предстоит подключить translator и познакомиться с темами форм.
Назначение "переводчика" надеюсь понятно всем, но в нашем проекте он задействован не будет, резонный вопрос -
"зачем он тогда вообще тут нужен?". И тут мы подходим к темам форм. Если вы до этого работали с какими-либо
фреймворками, то наверняка знаете, что в стандартный виджет форм уже входят такие штуки как label, input, error, hint.
Вот и Symfony не исключение. Стандартной темой отображения формы является шаблон
form_div_layout.html.twig
, который располагается в корне фреймворка.
Если посмотреть на его
исходный код,
можно увидеть все вышеуказанные элементы, а так же конструкцию trans ({})
.
Собственно поэтому мы и подключаем composer require translation
,
иначе неминуемо словим ошибку.
Разумеется можно переопределить стандартный шаблон. Как это сделать, да и вообще познакомиться с формами поближе однозначно стоит. Вот ссылки для чтения ( ссылка 1, ссылка 2 ).
Итак, давайте уже создадим представление. Сейчас предлагаю вывести его как есть, без стилей.
{{ form_start(form) }}
{{ form_widget(form) }}
< button type="submit">Сохранить< /button>
{{ form_end(form) }}
С помощью form_start
и
form_end
мы обозначаем границы формы, а в центр помещаем
form_widget
, который отобразит нам всю форму сразу.
Для того чтобы кастомизировать каждое поле отдельно можно воспользоваться
form_row
, например как здесь:
{{ form_start(form) }}
{{ form_row(form.title) }
{{ form_row(form.body, { 'attr': {
'rows' : '10',
'class' : 'form-control',
'placeholder' : 'Description',
'cols' : '10' }}) }}
< button type="submit">Сохранить< /button>
{{ form_end(form) }}
Ну и наконец проверим работоспособнось формы. Перейдем по маршруту
create_post
, что-нибудь напишем и проверим.
Для тех, кто хочет чуть приукрасить форму, код можно взять здесь