Внимательный читатель заметил, что в нашем фреймворке жестко прописан способ, которым выполняется код шаблонов. Для простых страниц, как те, которые мы создавали ранее, — это не проблема. Но если вы планируете добавить больше логики, вам придется внедрить её в сам шаблон.

Что, естественно, не очень хорошая идея, особенно если вы хотели разделить систему на отдельные функциональные структуры.
Давайте отделим код шаблона от логики, добавив новый слой — контроллер: «Задача контроллера заключается в создании Ответа на основе информации, переданной по Запросу клиента.»
Изменим часть шаблона, отвечающую за рендеринг, следующим образом:

Поскольку рендеринг теперь выполнен внешней функцией render_template(), мы должны передать ей атрибуты извлеченные из URL. Мы могли бы передать их в качестве дополнительного аргумента в render_template(), но вместо этого мы используем еще одну особенность класса Request – атрибуты. Атрибуты Request позволяют включать дополнительную информацию о Request, которая непосредственно не связана с данными HTTP-запроса.
Теперь напишем функцию render_template(), общий контроллер, который рендерит шаблон, без особой логики. Чтобы сохранить прежнюю структуру шаблона, атрибуты запроса извлекаются до рендера шаблона:

Так как render_template используется как аргумент для PHP call_user_func(), мы можем заменить его любой допустимой PHP callback-функцией. Это позволит использовать функцию, анонимную функцию или метод класса контроллера… на ваш выбор.
Для стандартизации определения любого пути, связанный контроллер сконфигурирован через атрибут маршрута _controller:

Маршрут теперь может быть связан с любым контроллером и, конечно, в контроллере, вы можете использовать render_template(), чтобы рендерить шаблон:

Это подход гибче, так как вы можете менять объект Response, и вы даже можете передать дополнительные аргументы в шаблон:

Вот обновленная и улучшенная версия нашей системы:

Чтобы отпраздновать рождение нашего нового фреймворка, давайте создадим новое приложение с простейшей логикой. Наше приложение состоит из одной страницы, которая определяет: является ли данный год високосным или нет. При вызове /is_leap_year, вы получите ответ для текущего года, но вы также можете указать год, в виде /is_leap_year/2009. Будучи универсальным, фреймворк не нуждается в изменениях, просто создадим новый файл app.php: (здесь переводчик, взял на себя неслыханную смелость и решил оставить старый функционал, объединив его с новым, да простит меня Fabien за это):

is_leap_year () возвращает true, если данный год является високосным, false в противном случае. Если год null, то проверяется текущий год. Контроллер прост: он получает год из атрибутов запроса, передает его в is_leap_year(), и в соответствии с возвращаемым значением, он создает новый объект Response.
Как всегда, вы можете решить остановиться на достигнутом и использовать фреймворк как есть. Этого, пожалуй, хватит для создания простых одностраничных сайтов и даже возможно с двумя страницами и больше.