Админка на файлах. Урок 3. Шаблонизатор Twig
В предыдущем уроке админки мы разобрались с конфигами и значениями параметров. Сегодня научимся выводить настройки в браузере. А чтобы не было скучно просто писать html, подключим к проекту шаблонизатор Twig. Ему и будет посвящена основная часть статьи.
У Twiga отличный функционал и простой синтаксис. В дебри лезть не будем, нам хватит и малой части его возможностей. Начинаем.
Подключаем Twig и рендерим первый шаблон.
Хотел скачать последнюю версию twig-a 2.x, но обломался. Он ставится через composer, а я в нем не шарю. Подозреваю, что composer мало чем отличается от фронтовых npm или bower, но погружаться сейчас не будем. Кто в теме, сделают composer require "twig/twig:^2.0" и без меня, а я как нормальный php-шник скачиваю версию 1.x через Download zip и не парюсь. Качать отсюда https://github.com/twigphp/Twig/tree/1.x
Ищем твигу местечко в проекте. Создадим папку admin/lib/Twig и закинем туда библиотеку. Идеально, смогли и без composer-a.
Идем дальше. Твигу нужна папка cache, куда он может свободно записывать отрендеренные шаблоны. Дискуссионный вопрос, куда определяют папку кэша нормальные пацаны? Я без фантазии создал прямо в admin - admin/cache. Ну и бог с ней. Главное, убедитесь, что в нее разрешена запись юзеру www-data. Если сидите на винде, то пофиг. А если нет, то смените владельца и дайте права на запись в cache
$ sudo chown -R www-data:www-data ./cache $ sudo chmod -R 755 ./cache/
Последнее, что нужно твигу - знать, где брать шаблоны. Для этого сделаем папку admin/templates и закинем в нее index.html c содержимым Hello, {{name}}. Ага, уже постигаем магию. Значение name будет передаваться в шаблон извне, из php-файла.
Давайте в admin/index.php подключим twig и отрендерим шаблон. Испокон веков автор фигачил разметку в index.php, а сейчас нет. Повзрослел. php-файл займется тем, чем и должен - логикой приложения. Даже звучит приятно, значит, пора реализовывать.
// Подключаем шаблонизатор require_once './lib/Twig/Autoloader.php'; // Инициализируем Twig Twig_Autoloader::register(); $loader = new Twig_Loader_Filesystem('./templates'); $twig = new Twig_Environment($loader, array( 'cache' => './cache', 'debug' => true )); // Рендерим шаблон echo $twig->render('index.html', array( 'name' => 'Twig' ));
В первой строке подключаем сам твиг. Дальше инициализация.
В документации я прочитал, если возникнет Непредвиденный Случай и почему-то НЕ СРАБОТАЕТ, то напишите Twig_Autoloader::register();
Я человек-удача и тот самый случай поймал. Написал, что велено, и все стало хорошо. Надеюсь, Вам повезет больше и вместо 10 строк уложитесь в 9.
Дальше в $loader и $twig загружаем среду или что-то такое нужное для шаблонизатора. Указываем в параметрах путь к папкам шаблонов и кеша и важный параметр debug=true. На боевом сайте debug убирайте, но пока оставьте. Иначе при изменении шаблона в templates/index.html твигу будет наплевать и он сразу возьмет срендеренный из кэша. И будем удивляться, чо это шаблон правим, а в браузере не меняется.
Итак, обновим страницу и видим текст Hello, Twig. Поздравляю, наш первый шаблон отработал. Но прежде чем наполнять его полезным содержимым, немного изменим index.php. А точнее подключим класс админки и в шаблон отдадим не name=Twig, а настройки. Получится вот так.
// Подключаем шаблонизатор и класс админки
require_once './lib/Twig/Autoloader.php';
require_once './admin.class.php';
// Инициализируем Twig
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('./templates');
$twig = new Twig_Environment($loader, array(
'cache' => './cache',
'debug' => true
));
// Создаем объект админки
$admin = new Admin();
// Рендерим шаблон
echo $twig->render('index.html', array(
'settings' => $admin->getSettings()
));
Редактируем шаблон.
В предыдущей статье засветился прототип.
На него и ориентируемся. Нам понадобится заготовка html-документа и простая форма с названиями параметров и значениями.
Конечно, форма будет на bootstrap. Однажды я раздуплюсь и покажу какой-нибудь другой css-фреймворк, но пока лень. Оправдываю себя тем, что мы же с вами не css-ы верстаем, а ПРИЛОЖЕНИЯ ПРОГРАММИРУЕМ. Пока отмазка работает, возвращаемся к шаблону.
Заготовку беру с сайта bootstrap. В head скопипастим такое
Админка на файлах
А body придется писать самим.
Админка на файлах
Выглядит как обычная бутстраповская форма, но с твиговскими вставками.
Разберем по очереди.
{% for item in settings %}
Перебираем в цикле настройки и для каждой выводим label и input в форме.
item.key используется и как айди, и как название name инпута, и как значение for в label. Такой важный нужный key.
item.title - заголовок настройки.
А это текстовое поле со значением.
Теперь обновляем страницу и видим список настроек с нужными значениями. Красота! Поменяйте значения полей в config/values.json. Работает, опять красота.
На этом позитивном предложении автор закончил бы статью, но нельзя. Потому что внимательный читатель скажет: стоп, а картиночка-то не та! С прототипом не сходится. А любознательный читатель еще и спросит: а зачем в первом уроке столько мутили с конфигами и разными типами данных? Чтобы сейчас выводить их тупо в инпуты? Конечно, читатель прав. Поэтому автор сходит выпить чаю и напишет еще пару абзацев.
Итак, продолжаем. Мы хотим выводить разные инпуты-селекты в зависимости от типа найстройки. В этом помогут условия twig и поле type из конфига настроек. В наличии 4 типа настроек: text, number, checkbox и select. Под каждую из них делаем условие. Вместо
пишем так
{% if item.type == 'text' %} {% endif %} {% if item.type == 'number' %} {% endif %} {% if item.type == 'checkbox' %}{% endif %} {% if item.type == 'select' %} {% endif %}
Вроде прям много и развесисто, но посмотрим ближе и станет яснее.
- текстовый инпут просто обернули в условие item.type == 'text'
- number - тот же инпут, только с type="number"
-
для checkbox отдельная верстка. Логично, чекбокс же, не просто инпут.
Не забываем про атрибут checked, который ставится в зависимости от item.value (true или false).
Интересно, что у самого чекбокса нет атрибута name со значением item.key. Зато name есть у скрытого инпута рядом с чекбоксом.
Спойлер: так удобнее для отправки формы на бекенд, в следующей статье убедимся. - у select-а есть цикл, потому что выводим список возможных значений из поля item.list
Теперь еще раз обновим страницу. У меня получилось так
Вот теперь все. Можно поиграть с настройками и значениями в json-файлах и посмотреть, как оно успешно раскидывается по формочке.
Если прониклись твигом и хотите узнать больше, то вот документация на русском. https://x-twig.ru/intro/
Следующий урок будет заключительным по теме "админка на файлах". Мы напишем js-код, который отправит данные на бекенд, и php-код, который эти данные сохранит. Бонусом внедрим уведомления, чтобы пользователь видел, не забыл ли он нажать кнопочку сохранить.
Небольшой опрос напоследок и до встречи!
Истории из жизни айти и обсуждение кода.