Среди некоторого количества шаблонизаторов для php есть один, который мы долгое время активно использовали и используем в своих проектах. Это Blitz, который являясь расширением, во-первых достаточно быстрый, во-вторых реализует давнюю мечту - максимальное отделение представления от логики.
Пока наши старые проекты были написаны на нативном php, пачке самописного кода и всякого «исторического наследия» проблем особых и не было. Но пришел момент когда некоторые старые куски мы решили переписать «жестко отрефакторить» и заодно влиться во вселенную Laravel. Но для ускорения процесса, перспектива переделать быстро десятки существующих шаблонов на Blade мне показалась такой себе идеей, поэтому надо было как-то прикрутить Blitz к Laravel, желательно в стиле самого Laravel. Ну типа там инсталяция в пару команд и все такое.
С другой стороны, в Blade есть некоторые фичи, которых нет в Blitz, как-то наследование шаблонов через @section/@yeld и внедрение хелперов. И было бы неплохо их добавить, для упрощения дальнейшего перехода на Blade, если будет надо. Сказано – сделано. На коленке за пару-тройку вечеров получился некий адаптер, с которым и хочу ознакомить. Собственно нижележащий текст это вольная попытка озвучить по-русски README.md, где я вообще был лаконичен как никогда
Инсталяция
Тут все просто
$ composer require nickyx3/blitz
$ php artisan vendor:publish --provider="NickyX3\Blitz\Providers\BlitzServiceProvider"
Конфиг (app/config/blitz.php)
'templates_folder' => 'blitz_view',
'cache_type' => 'file',
'cache_enabled' => false,
'compiled_folder' => 'blitz_compiled',
'scope_lookup_limit' => 8,
'php_callbacks_first' => 1,
'namespace_finder' => [
'App\Helpers',
'Illuminate\Support',
'Illuminate\Support\Facades'
]
Конфигурация
Значения по-умолчанию вполне рабочие, объясню что есть что
templates_folder – папка в которую кладем исходные шаблоны, относительно app/resources
cache_type –
file
илиredis
, каким образом будут храниться «скомпилированные» шаблоны.cache_enabled – соответственно включать кеш или нет, по-умолчанию выключено
compiled_folder – папка для «скомпилированных» шаблонов, относительно
app/storage
. В случае кеширования в Redis - ключи будут совпадать с путем в файловой системе. Настроки соединения берутся глобальные из самого Laravelscope_lookup_limit и php_callbacks_first – настройки самого расширения Blitz
namespace_finder – массив с пространствами имён, в которых пытаться искать внедренные коллбеки без полного пространства имён. Например, если в шаблоне встретится что-то типа
Lang::get('DefaultTitle')
, то он заменится на первое найденое полное пространство имёнIlluminate\Support\Facades\Lang::get('DefaultTitle')
Как использовать
Пример использования где-то в контроллере
use NickyX3\Blitz\Facade\BlitzView;
Route::get('/', function () {
return BlitzView::apply('example.blitz-extend',['title'=>'Blitz Title']);
});
Методapply
вернетIlluminate\Http\Response
, а дальше можете делать с ним что угодно.
Команды
Команд всего одна, зачистка кеша «скомпилированных» шаблонов
$ php artisan blitz:clear
Ошибки и исключения
Если расширение Blitz генерит ошибку, бросается кастомное исключение BlitzException, имеющее свой собственный рендер (не использующий никакой шаблонизатор, нативный php во всей красе). Исключение будет отрендерено только если ваше приложение в режиме отладки, выставленном через APP_DEBUG=true
в .env
, в противном случае просто бросится нативный Laravel abort(500)
, выглядит это как-то так:
Синтаксис шаблонов и фичи из Blade
Как уже упомянуто – я хотел добавить некоторые фичи из шаблонизатора Blade, а конкретно наследование шаблонов «вверх» (в отличие от include, которое «вниз»). Поддерживаются Blade директивы @yield
, @extends
, @section
and @endsection
, а также @csrf
, которые надо обрамить в html-коментарий. Ничего сложного.
Примеры
Шаблон "example/master.tpl"
<!DOCTYPE html>
<html lang="en">
<body>
<!-- @yield('content') -->
</body>
</html>
Шаблон "example/blitz-extend.tpl"
<!-- @extends('example.master') -->
<!-- @section('content') -->
<div class="child-template">this is template extends example/master.tpl</div>
<!-- @endsection -->
Как работают коллбеки?
Некоторые директивы Blitz, к примеру инлайн условия с коллбеками будут трансформированы в полный вариант, ибо коллбеки в инлайн не поддерживаются
Например это
{{ if($title,$title,Lang::get('DefaultTitle')) }}
Трансформируется в это
{{ IF $title }}
{{ $title }}
{{ ELSE }}
{{ Illuminate\Support\Facades\Lang::get('DefaultTitle') }}
{{ END if-title }}
Полные Blitz условные блоки с коллбеками типа этого
{{ IF App::currentLocale()=='en' }}
currentLocale: {{ App::currentLocale() }}
{{ ELSE }}
currentLocale not 'en'
{{ END }}
Будут трансформированы во что-то подобное в «компилированном» шаблоне
{{ IF Illuminate\Support\Facades\App::currentLocale()=='en' }}
currentLocale: {{ Illuminate\Support\Facades\App::currentLocale() }}
{{ ELSE }}
currentLocale not 'en'
{{ END }}
Но! Во время рендеринга такие коллбеки и им подобные будут заменены на соответствующие переменные с результатом работы коллбеков
{{ IF $callback_83e69f8a22cc276d050d93f63c89a290=='en' }}
currentLocale: {{ $callback_83e69f8a22cc276d050d93f63c89a290 }}
{{ ELSE }}
currentLocale not 'en'
{{ END }}
Где переменна $callback_83e69f8a22cc276d050d93f63c89a290
будет содержать результат выполнения Illuminate\Support\Facades\App::currentLocale()
. Все одинаковые вызовы будут заменены на одну и туже переменную, чтоб не выполнять код несколько раз. Э – экономия!
Исходники
https://github.com/NickyX3/laravel-blitz-view
P.S. & Disclaimer
Код писался прямо перед очередным отпуском, поэтому вполне возможно не соответствует стилю, плохо документирован и вообще может вызвать безвозвратные изменения психики. Заглядывание в него вы осуществляете на свой страх и риск
Тем не менее, идеи, мысли и отзывы приветствуются.