Ajax загрузка контент ной области в yii проекте

Сама задача звучит следующим образом: в существующем проекте на yii 1 сделать ajax загрузку контентной области. Т.е. при переходе по внутренним ссылкам не перезагружать всю страницу, а только контент.

Как только я прочитал данный пункт тз, я сразу вспомнил turbolinks из мира ruby. А т.к. в корне репозитория есть файлик package.json, а я умею работать с node зависимостями в php проекте, то решил попробовать подружить этот проект с php. У меня даже получилось. Но появился ряд критичных минусов:

  • Заработало только на абсолютных ссылках и внешние ресусры тоже обрабатывались
  • Движок прогружал весь контент новой страницы и профита по количеству передаваемых данных не было
  • Если на странице подключались дополнительные стили или срипты, то это приводило к неожиданным последствиям, например стили одно страницы отображались на другой.

Почитав документацию  к библиотеке turbolinks, я не нашел способа как заставить ее работать корректно в php проекте и решил писать свое решение.

Решение работает на yii1, с небольшими доработками можно завести на yii2 и в целом на любом другом фрэймворке, если понять основную логику работы.

Работать все будет слудующим образом:

  1. Создаем js, который будет перехватывать переход по всем внутренним ссылкам, добавлять определнный заголовк и отправлять get запрос на сервер.
  2. Сервер будет возвращать контент секции head, контентную область страницы и дополнительные скрипты
  3. При получении ответа менять контентную область, содержимое head а так же скрипты, подключаемые в конце страницы.
  4. Используюя histry api менять url в браузере
  5. Выполнять функцию обратного вызова

Для облегчения реализации я решил обернуть контентную область в шаблоне в div

<div id="turbo-area">
<?= $content; ?>
</div>

Теперь нужно обернуть дополнительные скрипты в аналогичный div. Для этого нужны функции для работы с DOM на сервере. Я выбрал пакет didom. Поставим его:

composer require imangazaliev/didom

Контроллеры, которые должны поддерживать функционал турбо загрузки, должны наследоваться от базового контроллера, в котором нужно переопределить метод render. Вот необходимые функции:

public function render($view, $data = null, $return = false)
{