Генерация карточек докладчиков в Laravel на основе HTML кода, написанного с помощью Tailwind.
Я организатор конференции Full Stack Europe. Как и на многих других конференциях, мы хотели бы предоставить нашим докладчикам и преподавателям небольшое изображение, которое они могли бы расшарить в Twitter или использовать в своих слайдах. На этой карточке должно быть фото и имя докладчика, плюс информация о конференции.
Я мог бы открыть редактор изображений и вручную изготовить пару десятков таких изображений. Но вместо этого я использовал свои знания PHP и фронтэнда для создания этих карточек.
Я сделал новое Laravel-приложение, установил Tailwind и приступил к работе. Сначала я создал шаблон для отображения все карточек спикеров:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Cards</title>
<link href="{{ mix('css/main.css') }}" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous">
</head>
<body class="m-8 font-noway">
@foreach($cards as $card)
<div id="card-{{ \Illuminate\Support\Str::slug("{$card['type']} {$card['speaker_name']}") }}"
class="m-8 inline-flex bg-repeat border-8 content-between"
style="background-image: url('/images/pattern.png')">
<img class="h-64" src="{{ $card['speaker_photo'] }}" alt="avatar"/>
<div class="m-4 flex flex-col justify-between ">
<div class="flex flex-col">
<div class="text-4xl font-bold">
{{ $card['title'] }}
</div>
<div class="text-2xl">
by {{ $card['speaker_name'] }} - {{ $card['speaker_title'] }}
</div>
</div>
<div class="text-2xl">
Full Stack Europe<br />
@if ($card['type'] === 'Workshop')
October 23, 2019<br />
@else
October 24 & 25, 2019<br />
@endif
fullstackeurope.com
</div>
</div>
</div>
@endforeach
</body>
</html>
Каждую карточку на этой странице нужно преобразовать в изображение. Некоторое время назад я сделал пакет под названием Browsershot, который может конвертировать любую веб-страницу в изображение. Для достижения этого, под капотом, он использует Headless Chrome. Browsershot также может отрендерить в изображение определенный DOM-узел.
Код, который используется для создания карточек докладчиков:
Browsershot::url('http://cards-generator.test/')
->select($elementId)
->deviceScaleFactor(2)
->windowSize(2000, 2000)
->save(storage_path("app/cards/{$slug}.jpg"));
В приложении я разместил этот кусок кода в удобную artisan-команду:
namespace App\Console\Commands;
use App\Services\Cards;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Spatie\Browsershot\Browsershot;
class GenerateCardsCommand extends Command
{
protected $signature = 'generate-cards';
public function handle()
{
collect(Cards::getAll())->each(function(array $card) {
$this->comment("Generating card for {$card['speaker_name']}...");
$slug = Str::slug("{$card['type']} {$card['speaker_name']}");
$elementId = "#card-{$slug}";
Browsershot::url('http://cards-generator.test/')
->select($elementId)
->deviceScaleFactor(2)
->windowSize(2000, 2000)
->save(storage_path("app/cards/{$slug}.jpg"));
});
$this->info('All done!');
}
}
Вот некоторые из сгенерированных карточек:
Несмотря на то, что я, в основном, идентифицирую себя как бэкэнд-разработчика, но мои базовые навыки фронтенда пригодились.
Автор: Freek Van der Herten
Перевод: Demiurge Ash