В прошлой статье был описан процесс установки и запуска Samoyed CMG (Content Management Generator). Основная идея — генерация кода сайта на основе настроек заданных кодом. Т.е. фактически кэширование всех настроек в коде при генерации, а не при развертывании на хостинге.  В ней упоминались генераторы для генерации кода, которые служат для расширения базового функционала сайта. В примере представлены два из них: Рассмотрим генераторы более подробно для понимания их работы. Сервис в понятии Samoyed CMG состоит из двух компонентов: В настройках генерации сайта происходит привязка интерфейса к конкретному сервису с помощью функции: Такой подход позволяет устанавливать различные реализации сервиса не меняя при этом логику использования сервиса. В простейшем случае класс реализации статический и его можно привязать непосредственно в настройках генерации. Однако я не ищу легкий путей если класс реализации генерируется по шаблону, то для этого необходимо использовать генератор. Генератор представляет собой обычный класс, который необходимо наследовать от класса CodeGenerator Метод getHtml возвращает html данные для страницы с технической информацией. При генерации сайта выполняется проход по всему узлам дерева настроек и для каждого генератора вызывается метод onGenerate. Объект $api содержит функции для генерации кода. Основная функция для генерации кода: Необходимо указать файл шаблона и его параметры и в текущий узел настроек будет добавлен сгенерированный скрипт. Вы можете указать замыкание в которое в качестве параметра передаётся объект Twig\Environment и есть возможность добавить свои функции и фильтры к шаблонизатору Twig. ВАЖНО(!): все добавленные функции и фильтры будут доступны только в указанном шаблоне. Идея работы сервиса очень простая. Определяем интерфейс с функциями: Функции site, vendor и package будут общими для всех маршрутов (Потому что кодовая база одна на все маршруты). Функция wwwServer зависит от домена маршрута. Функции temp и storage должны зависеть от входного параметра генератора. Это необходимо чтобы иметь возможность на разных доменах получать доступ к одним и тем же данным. Мы не можем привязываться к домену, так как при его изменении уже не сможем получить доступ к соответствующей папке.  Посмотреть техническую страницу
 Результат генерации класса на станице с технической информацией. Сгенерированный сервис использует стандартный сервис IRoute который генерируется системой и содержит всю информацию по текущему маршруту. Для получения сервиса указываем его в конструкторе сервиса. ВАЖНО(!): в $api генератора имеется функция setService для привязки сервиса. Эта функция возвращает TRUE если произошло изменение привязки. Т.е. если такой привязки не было или была привязка к другому классу. И только если было изменение, то генерируется код класса. Связано это с тем, что в случае если один из генераторов изменил состояние дерева настроек, то происходит перезапуск всех генераторов так как какой-то генератор может использовать результат работы другого генератора. Поэтому если изменения привязки не было, значит скрипт класса уже был сгенерирован ранее и нет смысла его ещё раз добавлять. Сначала определим общий сервис шаблонизатора Затем определим сервис работы с Twig просто унаследовав общий сервис шаблонизатора Такие сложности нужны чтобы в случае необходимости можно было добавить в сервис уникальные для Twig функции не ломая при этом общий сервис шаблонов. Генератор шаблонизатора работает аналогично генератору путей, но есть отличие. Оно заключается в наличии методов настройки. С помощью этих методов в генератор добавляются пространства имен с шаблонами через функцию дерева настроек tune. Функция в качестве параметра принимает замыкание с параметром настраиваемого генератора: ВАЖНО(!): в функциях настройки требуется обязательно вызывать функцию setModify для сообщения системе об изменениях. Как следствие: проверяйте, а было ли реальное изменение настроек или это просто повторный вызов функции с теми же параметрами.