В прошлой статье была описана теория CMG (Content Management Generator). Основная идея — генерация кода сайта на основе настроек заданных кодом. Т.е. фактически кэширование всех настроек в коде при генерации, а не при развертывании на хостинге.
В данной статье описан процесс установки и генерации тестового сайта. Итоговый сайт и код примера прилагается. Также сайт содержит страницу с технической информаций (картинка именно оттуда).
Установка
Для запуска достаточно наличие скрипта s-cmg-generate.php. Скрипт имеет следующий набор параметров:
php s-cmg-generate.php -param1=value -param2=value ...
- packageSite — пакет сайта (обязательный параметр);
- classSite — класс настроек сайта (обязательный параметр);
- pathSite — директория для сгенерированного кода (обязательный параметр);
-
mode — режим работы (если не указан, то = dev):
- prod — создать дистрибутив для развертывания на хостинге;
- test — сборка для тестирования;
- dev — сборка для разработки.
- env — файл с параметрами окружения;
- repositories — директория с локальными пакетами (можно указывать несколько раз).
Запуск
Для запуска необходимо указать обязательные параметры: packageSite, classSite и pathSite. В результате скрипт через composer установит указанный пакет packageSite, создаст объект класса classSite и сгенерирует в указанной директории pathSite/<режим работы> код для указанного режима. Для режима prod будет создана папка dist с файлами install.php и install.zip. Для разворачивания на хостинге необходимо эти файлы закачать на хостинг в нужную папку и запустить скрипт install.php. Дальше скрипт всё сам развернёт. Если на хостинге была установлена более ранняя версия, то она будет удалена и установится новая версия. ВАЖНО: удалены будут только файлы и директории, которые были сгенерированы, все другие файлы останутся в неизменном виде.
Локальные пакеты
При разработке удобно использовать локальные пакеты. Однако, так как код генерируется, то разработчик не имеет возможности устанавливать дополнительные локальные пакеты в сгенерированный код. Именно для этого существует параметр repositories для указания локальных пакетов. Достаточно в указанной папке разместить свой пакет и он будет автоматически добавлен в сгенерированный код. В режиме разработки код будет добавлен через ссылку, что позволяет изменять пакет и тут же проверять результат. В режиме продуктива локальные пакеты добавляются в файл install.zip для дальнейшего разворачивания. В режиме test пакеты также упаковываются в файлы, как для режима prod, но при этом не создаётся дистрибутив. Т.е. данный режим служит для тестирования, но непригоден для разработки.
Параметры окружения
Полезно указывать разные параметры для разных режимов в отдельном файле .env. Формат аналогичен формату подобного файла в Laravel. Однако его использование отличается. Во-первых доступ к параметрам осуществляется через функцию s_env. Во-вторых (ВАЖНО!) значения доступны только во время генерации. Т.е. при вызове функции на сгенерированном сайте вы не сможете получить значения.
Пример
Рассмотрим подробно пример. Для этого скачаем его в любую папку и распакуем. Для запуска можно использовать demo.bat, в этом случае подключается локальная папка с пакетами composer-local-repositories и пример создаётся в текущей папке в директории @s-demo.
Файлы настроек .env.prod, .env.test, .env.dev служат для установки глобальных параметров. А именно:
- domain — Домен генерируемого сайта.
- serverPath — Директория для привязки сгенерированного www сервера. т.е. тут указывается директория, которая после установки будет ссылаться на созданный нами сайт.
Так как я использую при разработке Open Server, то для режима dev и test устанавливается директория в папке domains Open Server с соответствующим доменом
domain=samoyed-cmg.ru
serverPath=${HOME}/domains/${domain}
HOME — это переменная окружения с корневой папкой Open Server.
domain — это домен из первой строки.
При генерации в режиме prod
domain=samoyed-cmg-demo.shasoft.com
serverPath=./public_html
указываю домен сайта samoyed-cmg-demo.shasoft.com И директорию public_html, которая находится в той же папке (именно её мой хостинг использует в качестве входной точки).
<?php
namespace Shasoft\SDemo;
use Shasoft\STwig\ServiceGeneratorTwig;
use Shasoft\SDemo\Controller\HomeController;
use Shasoft\SamoyedCMG\Generator\PathGenerator;
use Shasoft\SamoyedCMG\Generator\SiteGenerator;
use Shasoft\SamoyedCMG\Generator\RouteGenerator;
use Shasoft\SamoyedCMG\Generator\DomainGenerator;
use Shasoft\SDemo\Controller\ShowImageController;
use Shasoft\SDemo\Middleware\ModifyHeaderMiddleware;
use Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorLink;
use Shasoft\SamoyedCMG\Generator\Service\ServiceGeneratorPath;
use Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorPhpScript;
use Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorController;
// Пример настройки сайта
class SiteDemo extends SiteGenerator
{
// Конструктор
public function __construct()
{
parent::__construct();
// Установить внешнюю директорию www сервера
$this->setServerPath(s_env('serverPath'));
// Добавить домен
$this->addDomain(s_env('domain'), function (DomainGenerator $domain) {
// Добавить тестовые пути
$this->addRoutes($domain);
// Добавить путь для маршрутов с посредником
$domain->addPath('middleware', 'middleware', function (PathGenerator $path) {
// Добавить посредник
$path->addMiddleware(ModifyHeaderMiddleware::class, ['name' => 'SamoyedCMG']);
// Добавить тестовые пути
self::addRoutes($path);
});
// Добавить маршрут со ссылкой на дистрибутив
$domain->addRoute(new RouteGeneratorLink(__DIR__ . '/../@assets/samoyed-cmg-demo.zip', true), function (RouteGenerator $route) {
// Установить маршрут
$route->setRoute('samoyed-cmg-demo.zip');
// Установить имя маршрута
$route->setName('dist');
});
// Добавить маршрут с технической информацией
$domain->addRoute(new RouteGeneratorLink(__DIR__ . '/../@assets/debug'), function (RouteGenerator $route) {
// Установить маршрут
$route->setRoute('debug');
// Установить имя маршрута
$route->setName('debug');
});
});
}
// Добавить тестовые пути
static private function addRoutes(PathGenerator $path)
{
//-- Добавить маршрут на основе КОНТРОЛЛЕРА
$path->addRoute(new RouteGeneratorController(HomeController::class), self::getFunctionConfigRoute());
//-- Маршруты на основе ССЫЛКИ
$path->addPath('link', 'link', function (PathGenerator $path) {
// Маршрут на основе ссылки на файл
$path->addPath('file.ico', 'file', function (PathGenerator $path) {
$path->addRoute(new RouteGeneratorLink(__DIR__ . '/../@assets/favicon.ico'));
});
// Маршрут на основе ссылки на директорию
$path->addPath('folder', 'folder', function (PathGenerator $path) {
$path->addRoute(new RouteGeneratorLink(__DIR__ . '/../@assets/images'));
});
});
//-- Маршруты на основе ССЫЛКИ
$path->addPath('phpScript.php', 'script', function (PathGenerator $path) {
//-- Добавить маршрут на основе PHP скрипта
$path->addRoute(new RouteGeneratorPhpScript(__DIR__ . '/../@assets/phpScript.php'));
});
// Галерея картинок для демонстрации маршрута на основе ссылки на папку + параметры маршрута
$path->addPath('show-images/$width', 'images', function (PathGenerator $path) {
//-- Добавить маршрут на основе контролллера с параметрами маршрута
$path->addRoute(new RouteGeneratorController(ShowImageController::class), self::getFunctionConfigRoute());
});
}
// Добавить параметры маршрута
static private function getFunctionConfigRoute(): \Closure
{
return function (RouteGenerator $route) {
$route
//-- Добавить генератор сервиса работы с путями
->addGenerator(new ServiceGeneratorPath('demo'))
//-- Добавить генератор сервиса работы с шаблонами
->addGenerator(new ServiceGeneratorTwig())
//-- Добавить шаблоны
->tune(function (ServiceGeneratorTwig $twig) {
// Добавить пространство имён main И папку с шаблонами
$twig->addNamespace('main', __DIR__ . '/../@twig');
});
};
}
}
Данный код содержит маршруты всех поддерживаемых (на текущий момент) классов:
- Ссылка на файл (класс Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorLink)
- Ссылка на директорию (класс Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorLink)
- Контроллер (класс Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorController)
- PHP скрипт (класс Shasoft\SamoyedCMG\Generator\Route\RouteGeneratorPhpScript)
Также имеется маршрут с параметром для вывода картинок в зависимости от указанного максимального размера по горизонтали.
Все эти маршруты вызываются как напрямую, так и через посредник Shasoft\SDemo\Middleware\ModifyHeaderMiddleware, который добавляет в список заголовков ответа сервера заголовок с именем, указанным в параметрах (SamoyedCMG) и значением ModifyHeaderMiddleware.
Для каждого маршрута указано имя маршрута, поэтому можно получить ссылку по имени через сгенерированный класс UrlBuilder.
Всю подробную информация о сгенерированном сайте можно поглядеть на этой странице. Страница содержит список всех доменов и сгенерированных маршрутов. Два вида для дерева настроек. При нажатии на узел дерева настроек внизу страницы показывается в двух вариантах подробная информация по узлу. Для узла выводится следующая информация:
- Список генераторов (те что генерируют код) + параметры которые были переданы в эти классы. В примере используется два генератора: Shasoft\SamoyedCMG\Generator\Service\ServiceGeneratorPath и Shasoft\STwig\Twig
- Информация о маршруте (класс + параметры класса) (только для узлов маршрутов).
- Данные файла .htaccess (только для узлов маршрутов).
- Список сгенерированных скриптов. В частности тут можно поглядеть файл который вызывается из .htaccess — это файл класса Shasoft\SamoyedCMG\AppRoute + файл для генерации содержимого страницы для указанного класса маршрута — файл Shasoft\SamoyedCMG\AppRouteOnRequest.
- Список сервисов. Если сервис является сгенерированным то имеется ссылка на сгенерированный скрипт. Если ссылки нет — значит данный класс не является результатом кодогенерации.
- Список посредников.
Если информация для узла отсутствует, то соответствующая вкладка не выводится.
Подробная информация выводится для текущего узла и для текущего узла с учетом всех вышестоящих узлов. Отличие в том, что во втором случае будет информация которая устанавливается не только в этом узле, но во всех вышестоящих узлах. Т.е. по второму варианту маршрут будет содержать вообще всю информацию, на основе которой этот маршрут генерировался.
Страница с технической информацией генерируется и сохраняется в директории debug соответствующего режима. Доступна для просмотра в локальном режиме. Для этого необходимо открыть в браузере файл debug/index.html.