Продвинутое управление meta тегами в Laravel
Как говорится, Hello world.
За все время что я работаю с Laravel я повидал множество способов управления meta тегами, подключения стилей, скриптов и т.д.
Люблю примеры, поэтому приведу пример из реальной жизни того, как это обычно делают
Этот пример я взял отсюда https://github.com/bagisto/bagisto/blob/master/packages/Webkul/Admin/src/Resources/views/layouts/master.blade.php
Что мы здесь видим? Очевидно title указывается непосредственно в каждом шаблоне, если нужно подключить дополнительные скрипты и т.д., то также придется это делать через шаблоны. Также в самом низу head видно, что можно использовать события для добавления в этот блок своих тегов. Причем, я правда до конца не изучал код, но смею предположить, что используя это событие мы добавим данные сразу на все страницы.
В чем проблема такого способа? В том, что появляется куча мусора в шаблонах, если мы захотим добавить несколько скриптов на определенные страницы, то что мы сделаем? Скопипастим или придумаем новый шаблончик, который добавим в нужное место? А что если система сложная? А что если куча условий? А что если SEO-шники хотят добавить OpenGraph или TwitterCard или кучу других тегов, которые должны изменяться в зависимости от условий? Короче штатными средствами получится решить простые задачи или будет куча кастылей.
На помощь приходят composer пакеты, которые помогают решить эти задачи. Пакетов очень много (даже у меня есть один пакет, который по счастливому стечению обстоятельств набрал 71к скачиваний!), большинство из них однотипные и решают простейшие задачи и позволяют, в основном, управлять стандартным набором meta тегов и имеют сложности с их расширением и я захотел свой новый пакет с блекджеком и теми, кто к нему приллагается. Уделить внимание его документации и сделать его расширяемым, универсальным как для упавления meta тегами так и стилями, скриптами и т.д.
Как я себе это представлял
- Указываем значения по умолчанию с помощью конфига, если значения есть, то выводим тег.
2. Добавляем в шаблон места вывода данных. Как мы помним, мест вывода несколько, в основном это head. В общем как то так:
<html lang="en">
<head>
@meta_tags
</head>
</html>
Этого уже достаточно, чтобы пакет начал работать.
3. Дальше мы можем в каждом контроллере изменять или добавлять новые теги. (Список всех методов с описание можно посмотреть здесь https://github.com/butschster/LaravelMetaTags#meta)
Это только начало…
Если мы хотим добавлять на страницы стили и скрипты, то по одному их добавлять не очень, это долго (а вдург версию потом нужно поменять?), много дублирования кода и т.д. и я решил, что нужны пакеты, что-то вроде:
Где каждому пакету мы могли бы дать имя, внутри пакета сформировать набор стилей, скрпитов и других тегов (если они нужны), указать зависимости между пакетами, например, при подключении календаря нужен jquery и в конфиге указать загружаемые пакеты по умолчанию. (Ифнормацию по пакетам можно посмотреть здесь https://github.com/butschster/LaravelMetaTags#package)
// config/meta_tags.php/*
* Default packages
*
* Packages, that should be included everywhere
*/
'packages' => [
'bootstrap'
],
Либо непосредственно в контроллере
Meta::includePackages('bootstrap')
Назревает вопрос, а скрипты должны быть в самом низу body, как с этим быть? И здесь мы знакомимся с placements. Все теги могут иметь свое месторасположение, по умолчанию все что должно быть только в <head>, попадает в head (placement по умолчанию), все скрипты попадают в placement footer. Но при желании мы можем указать его месторасположение. (И таких placements может быть сколько угодно)
<body>
@meta_tags('my_custom_awesome_place') ... @meta_tags('footer')
</body>
Meta::addScript('calendar.js', 'https://site.com/calendar.js', [], 'head')Meta::addScript('calendar.js', 'https://site.com/calendar.js', [], 'my_custom_awesome_place')
Хотите добавить что-то своё?
Здесь все просто, есть множество способов расширения возможностей пакета.
Например используя Macroable
Можно создавать свои собственные meta теги
Можно создать свой собственный тег, просто реализуя интерфейс \Butschster\Head\Contracts\MetaTags\Entities\TagInterface
Недавно мне задали вопрос, а можешь такое?
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16" /><link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32" /><link rel="icon" type="image/png" href="/favicon-64x64.png" sizes="64x64" /><!--[if IE gt 6]>
<link rel="icon" type="image/png" href="/favicon-ie.png" />
<![endif]-->
Я ответил да!
В общем я изучил множество различных пакетов, выявил их сильные и слабые стороны, изучил какие теги бывают, какие нюансы их использования существуют и постарался собрать все в одном месте и сделать удобным для использования, а самое главное, я оставил возможность для расширения всего этого с помощью простых интерфейсов!
Полную документацию, в которой я постарался собрать все возможности, можно почитать на странице репозитория. https://github.com/butschster/LaravelMetaTags
Для вашего и моего спокойствия весь код полностью покрыт unit тестами.
Если есть вопросы по использованию, предложения по развитию и т.д., пишите, создавайте issue и присылйте pull requests.
Enjoy!
P.s. Недавно я подумал, а почему бы и JS variables не выводить? :) И написал простенький класс