Laravel · Движок презентаций
1 / 1

Движок презентаций

Демо-дека: каждый компонент из design/AUTHORING.md на одном экране. Вывод терминала и снимки браузера — настоящие захваты из captures/demo/, id начинаются с demo-. Код в примерах — иллюстративный.

10 слайдов офлайн, без CDN тема void-theme

1листайте
Компонент 1 · Текст

Обычный Markdown

Абзацы, жирный, курсив, код в строке, Ctrl + K, ссылки и списки работают как обычно. Классы добавляются через {: .класс} на отдельной строке.

Параграф с классом .lead — вводный текст крупнее основного.

Что есть на слайде

  • заголовки ### и #### внутри слайда;
  • списки и вложенные списки;
  • таблицы в стиле темы;
  • бейджи успех ошибка инфо.
Компонент Блок в markdown Захват
Терминал ```term cap=… captures/*/manifest.jsonl
Снимок ```shot cap=… captures/browser/*.png
Код ```php hl=2 подсветка Pygments
Дерево ```tree без захвата
2листайте
Компонент 2 · Терминал

Терминал из реального захвата

Команда «набирается», вывод печатается построчно. Клик по окну показывает всё сразу, кнопки в шапке повторяют вывод и копируют команду.

student@mint: ~467 мс
student@mint:~$
Проверяем версию PHP — CLI и модули стоят — можно работать
Разбор команды

Первая команда шага: убеждаемся, что интерпретатор стоит и стенд отвечает той версией, на которой построен урок.

php -v
ТокенЗачем он и что меняет
phpисполняемый файл интерпретатора; в Ubuntu/Mint ставится пакетом php8.3-cli
-vфлаг версии: печатает версию PHP и Zend Engine и выходит

Что произойдёт

Команда ничего не меняет на диске: печатает четыре строки версии и завершается с кодом 0.

На что смотреть

Первая строка: PHP 8.3.6 (cli) — это версия CLI. Стенд урока 8.3; подставьте свою версию, если она другая.

Частые ошибки

  • php: command not found — не установлен пакет php8.3-cli или команда выполняется не в той оболочке.

Строки классифицируются эвристикой: служебные — приглушённые, успех — зелёные, ошибки — красные. Явные номера строк в манифесте (ok_lines, err_lines) важнее эвристики.

3листайте
Компонент 2 · Терминал

Ошибка, exit code и длинный вывод

student@mint: ~exit code 1559 мс
student@mint:~$
Artisan до установки Laravel — Команда падает: проекта ещё нет. Движок рисует exit code и красную строку
Разбор команды

Показываем типичную ошибку до установки Laravel: artisan ещё нет, и команда падает. Это нормальное состояние шага.

php artisan --version
ТокенЗачем он и что меняет
phpинтерпретатор выполняет файл, указанный следующим аргументом
artisanотносительный путь к скрипту проекта; в домашнем каталоге такого файла нет
--versionфлаг artisan: напечатать версию Laravel — до неё дело не доходит

Что произойдёт

PHP не находит файл artisan в текущем каталоге, печатает одну строку ошибки и завершается с кодом 1.

На что смотреть

Строка Could not open input file: artisan и код выхода 1: проблема в текущем каталоге, а не в PHP.

Частые ошибки

  • Команда запущена вне корня проекта: artisan лежит в корне Laravel, рядом с composer.json.
  • После установки Laravel та же команда в корне проекта печатает версию фреймворка.
Ненулевой код выхода

Движок рисует бейдж exit code 1 в шапке окна. Это не сбой сборки: команда действительно так завершилась на коробке захвата.

student@mint: ~567 мс
student@mint:~$
phpinfo()PHP Version => 8.3.6System => Linux mint 6.18.46 #1-NixOS SMP PREEMPT_DYNAMIC Sun Aug 23 12:27:10 UTC 2026 x86_64Build Date => Sep  2 2026 12:56:02Build System => LinuxServer API => Command Line InterfaceVirtual Directory Support => disabledConfiguration File (php.ini) Path => /etc/php/8.3/cliLoaded Configuration File => /etc/php/8.3/cli/php.iniScan this dir for additional .ini files => /etc/php/8.3/cli/conf.dAdditional .ini files parsed => /etc/php/8.3/cli/conf.d/10-mysqlnd.ini,/etc/php/8.3/cli/conf.d/10-opcache.ini,/etc/php/8.3/cli/conf.d/10-pdo.ini,/etc/php/8.3/cli/conf.d/15-xml.ini,/etc/php/8.3/cli/conf.d/20-bcmath.ini,/etc/php/8.3/cli/conf.d/20-calendar.ini,/etc/php/8.3/cli/conf.d/20-ctype.ini,/etc/php/8.3/cli/conf.d/20-curl.ini,/etc/php/8.3/cli/conf.d/20-dom.ini,/etc/php/8.3/cli/conf.d/20-exif.ini,/etc/php/8.3/cli/conf.d/20-ffi.ini,/etc/php/8.3/cli/conf.d/20-fileinfo.ini,/etc/php/8.3/cli/conf.d/20-ftp.ini,/etc/php/8.3/cli/conf.d/20-gd.ini,/etc/php/8.3/cli/conf.d/20-gettext.ini,/etc/php/8.3/cli/conf.d/20-iconv.ini,/etc/php/8.3/cli/conf.d/20-intl.ini,/etc/php/8.3/cli/conf.d/20-mbstring.ini,/etc/php/8.3/cli/conf.d/20-mysqli.ini,/etc/php/8.3/cli/conf.d/20-pdo_mysql.ini,/etc/php/8.3/cli/conf.d/20-pdo_sqlite.ini,/etc/php/8.3/cli/conf.d/20-phar.ini,/etc/php/8.3/cli/conf.d/20-posix.ini,/etc/php/8.3/cli/conf.d/20-readline.ini,/etc/php/8.3/cli/conf.d/20-shmop.ini,/etc/php/8.3/cli/conf.d/20-simplexml.ini,/etc/php/8.3/cli/conf.d/20-sockets.ini,/etc/php/8.3/cli/conf.d/20-sqlite3.ini,/etc/php/8.3/cli/conf.d/20-sysvmsg.ini,/etc/php/8.3/cli/conf.d/20-sysvsem.ini,/etc/php/8.3/cli/conf.d/20-sysvshm.ini,/etc/php/8.3/cli/conf.d/20-tokenizer.ini,/etc/php/8.3/cli/conf.d/20-xmlreader.ini,/etc/php/8.3/cli/conf.d/20-xmlwriter.ini,/etc/php/8.3/cli/conf.d/20-xsl.ini,/etc/php/8.3/cli/conf.d/20-zip.iniPHP API => 20230831PHP Extension => 20230831Zend Extension => 420230831Zend Extension Build => API420230831,NTSPHP Extension Build => API20230831,NTSDebug Build => noThread Safety => disabledZend Signal Handling => enabledZend Memory Manager => enabledZend Multibyte Support => provided by mbstringZend Max Execution Timers => disabledIPv6 Support => enabledDTrace Support => disabledRegistered PHP Streams => https, ftps, compress.zlib, php, file, glob, data, http, ftp, phar, zipRegistered Stream Socket Transports => tcp, udp, unix, udg, ssl, tls, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3Registered Stream Filters => zlib.*, string.rot13, string.toupper, string.tolower, convert.*, consumed, dechunk, convert.iconv.*This program makes use of the Zend Scripting Language Engine:Zend Engine v4.3.6, Copyright (c) Zend Technologies    with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies _______________________________________________________________________
Длинный вывод — Больше 60 строк: движок ограничивает высоту и даёт внутреннюю прокрутку, fold=16 сворачивает хвост
Разбор команды

Смотрим, какой конфигурационный файл реально читает CLI: от него зависят включённые модули и пределы.

php -i | head -72
ТокенЗачем он и что меняет
phpинтерпретатор
-iнапечатать phpinfo() в терминал: всю эффективную конфигурацию
|pipe: stdout левой команды становится stdin правой
headоставляет начало потока
-72аргумент head: ровно 72 строки, чтобы не листать сотни

Что произойдёт

phpinfo() печатает эффективную конфигурацию CLI, head обрезает вывод до 72 строк; код выхода 0.

На что смотреть

Строка Loaded Configuration File: какой php.ini читает CLI. У fpm свой php.ini — не путайте их.

Частые ошибки

  • Правите не тот php.ini: cli и fpm читают разные файлы, изменения для сайта проверяйте через php-fpm.

Больше 60 строк — окно ограничивается по высоте с внутренней прокруткой, fold=16 прячет хвост за кнопку «показать ещё».

4листайте
Компонент 3 · Код

Код: подсветка и hl=

Подсветка — Pygments, но цвета токенов заданы из переменных темы, поэтому палитра меняется вместе с гаммой и светлым/тёмным режимом.

routes/web.phpphp
1<?php23use App\Http\Controllers\UserController;4use Illuminate\Support\Facades\Route;56Route::get('/users', [UserController::class, 'index'])7 ->name('users.index');89Route::post('/users', [UserController::class, 'store'])10 ->middleware('auth')11 ->name('users.store');

hl=4,6-8 подсвечивает строки полосой и отметкой на полях, номера строк появляются вместе с hl= или с флагом lines.

5листайте
Компонент 3 · Код

Разные языки и diff

resources/views/users/index.blade.phpblade
@extends('layouts.app')@section('content') {{-- список пользователей --}} @foreach ($users as $user) <tr> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> </tr> @endforeach@endsection
diff
--- a/app/Models/User.php+++ b/app/Models/User.php@@ -8,6 +8,8 @@ class User extends Authenticatable protected $fillable = [ 'name', 'email',+ 'role',+ 'blocked_at', ]; }
/etc/nginx/nginx.confnginx
1user student;2worker_processes auto;3pid /run/nginx.pid;4error_log /var/log/nginx/error.log;5include /etc/nginx/modules-enabled/*.conf;67events {8 worker_connections 768;9 # multi_accept on;10}1112http {1314 ##15 # Basic Settings16 ##1718 sendfile on;19 tcp_nopush on;20 types_hash_max_size 2048;21 # server_tokens off;2223 # server_names_hash_bucket_size 64;24 # server_name_in_redirect off;2526 include /etc/nginx/mime.types;27 default_type application/octet-stream;2829 ##30 # SSL Settings31 ##3233 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE34 ssl_prefer_server_ciphers on;3536 ##37 # Logging Settings38 ##3940 access_log /var/log/nginx/access.log;4142 ##43 # Gzip Settings44 ##4546 gzip on;4748 # gzip_vary on;49 # gzip_proxied any;50 # gzip_comp_level 6;51 # gzip_buffers 16 8k;52 # gzip_http_version 1.1;53 # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;5455 ##56 # Virtual Host Configs57 ##5859 include /etc/nginx/conf.d/*.conf;60 include /etc/nginx/sites-enabled/*;61}626364#mail {65# # See sample authentication script at:66# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript67#68# # auth_http localhost/auth.php;69# # pop3_capabilities "TOP" "USER";70# # imap_capabilities "IMAP4rev1" "UIDPLUS";71#72# server {73# listen localhost:110;74# protocol pop3;75# proxy on;76# }77#78# server {79# listen localhost:143;80# protocol imap;81# proxy on;82# }83#}

Длинный файл из захвата kind:"file": fold=18 прячет хвост за кнопку «показать ещё», hl=26-27 подсвечивает строки ЗА границей свёртки — они видны после раскрытия. Кнопка копирования отдаёт файл целиком, в режиме чтения и в печати блок раскрыт.

6листайте
Компонент 4 · Файлы

Карточка файла и дерево

app/Http/Controllers/UserController.php
<?phpnamespace App\Http\Controllers;use App\Models\User;class UserController extends Controller{ public function index() { return view('users.index', [ 'users' => User::orderBy('name')->get(), ]); }}
users/├── app/ # наш код: модели, контроллеры│   ├── Http/│   │   └── Controllers/│   │       └── UserController.php│   └── Models/│       └── User.php├── routes/│   └── web.php # таблица маршрутов└── public/ # единственная папка, которую видит nginx    └── index.php

Дерево моноширинное: линии сохраняются, комментарии после # приглушены, каталоги выделены цветом.

7листайте
Компонент 5 · Инфоблоки

Инфоблоки и шаги

Заметка

Шесть тонов: note, info, tip, warn, danger, success.

Справка

Иконка и тон берутся из темы, фон — color-mix без альфа-модификаторов.

Совет

Заголовок блока необязателен: тогда текст идёт сразу под иконкой.

Осторожно

Команда из захвата не переписывается: что напечатала машина, то и на слайде.

Ошибка

Тон danger — для того, что действительно ломает работу.

Готово

Тон success — для проверенного результата.

1
Открыть макет

Слайд пишется в src/parts/part-NN.md, блоки — по design/AUTHORING.md.

2
Собрать

bin/build.py превращает markdown в html/part-NN.html.

3
Посмотреть

Скриншоты headless-браузером и глаза: числа и кадры, а не прилагательные.

8листайте
Компонент 6 · Скриншоты

Скриншот браузера

Рамка браузера с адресной строкой из захвата. Клик по снимку открывает лайтбокс: зум, Esc — закрыть, стрелки листают снимки слайда.

http://project-laravel.rs/
nginx отдал index.php, Laravel ответил стартовой страницей
nginx отдал index.php, Laravel ответил стартовой страницей
9листайте
Компонент 6 · Скриншоты

Сравнение «до» и «после»

cap2= ставит два снимка рядом с подписями: слева прежнее состояние, справа результат правки.

http://project-laravel.rs/usersдо
Форма не прошла валидацию: поле email обязательно
Форма не прошла валидацию: поле email обязательно
http://project-laravel.rs/usersпосле
После исправления ошибка ушла, шестая запись в таблице
После исправления ошибка ушла, шестая запись в таблице
10листайте
Компонент 7 · Флоу

Векторная инфографика: жизненный цикл запроса

:::flow — граф в YAML-подобном теле: rows задают ряды, nodes — карточки с иконкой tabler, edges — рёбра с подписями и видом (forward, data, back). По прямому пути бежит пакет, по обратному — свой навстречу.

Браузер — Chrome студентаБраузерChrome студентаDNS зоны .rs — dnsmasq: address=/rs/127.0.0.1DNS зоны .rsdnsmasq:address=/rs/127.0.0.1nginx — server_name project-laravel.rsnginxserver_nameproject-laravel.rsPHP-FPM — unix-сокет php8.3-fpm.sockPHP-FPMunix-сокетphp8.3-fpm.sockpublic/index.php — точка входаpublic/index.phpточка входаРоутер — routes/web.phpРоутерroutes/web.phpКонтроллер — app/Http/ControllersКонтроллерapp/Http/ControllersМодель — EloquentМодельEloquentMariaDB — база project_laravel, PDOMariaDBбаза project_laravel,PDOBlade — компиляция в storage/framework/viewsBladeкомпиляция вstorage/framework/viewsБуфер вывода — echo даёт тело ответаБуфер выводаecho даёт тело ответаGET project-laravel.rs127.0.0.1fastcgiисполняетbootstrapURL совпалUser::…SELECT …строкиHTMLтело ответа200 OKGET project-laravel.rs127.0.0.1fastcgiисполняетbootstrapURL совпалUser::…SELECT …строкиHTMLтело ответа200 OKБраузер — Chrome студентаБраузерDNS зоны .rs — dnsmasq: address=/rs/127.0.0.1DNS зоны .rsnginx — server_name project-laravel.rsnginxPHP-FPM — unix-сокет php8.3-fpm.sockPHP-FPMpublic/index.php — точка входаpublic/index.phpРоутер — routes/web.phpРоутерКонтроллер — app/Http/ControllersКонтроллерМодель — EloquentМодельMariaDB — база project_laravel, PDOMariaDBBlade — компиляция в storage/framework/viewsBladeБуфер вывода — echo даёт тело ответаБуфер вывода
Прямой путь запроса и обратный путь ответа
11листайте
Компонент 7 · Флоу

Флоу с рёбрами kind: data

Тот же компонент, другая форма графа: два ряда и вертикальные рёбра данных соединяют пары «файл до — файл после». Пакет бежит по каждому ребру данных.

public/index.php — точка входаpublic/index.phpточка входаusers.php — HTML прямо в кодеusers.phpHTML прямо в кодеlogin.php — HTML прямо в кодеlogin.phpHTML прямо в кодеlayouts/app.blade.php — общий каркасlayouts/app.blade.phpобщий каркасusers/index.blade.php — только разметкаusers/index.blade.phpтолько разметкаlogin.blade.php — только разметкаlogin.blade.phpтолько разметкакаркас одинразметка ушла в шаблонто же самоекаркас одинразметка ушла в шаблонто же самоеpublic/index.php — точка входаpublic/index.phpusers.php — HTML прямо в кодеusers.phplogin.php — HTML прямо в кодеlogin.phplayouts/app.blade.php — общий каркасlayouts/app.blade.phpusers/index.blade.php — только разметкаusers/index.blade.phplogin.blade.php — только разметкаlogin.blade.php
Чистый PHP и Blade: разметка уезжает в шаблоны
12листайте
Компонент 7 · Флоу

Компактный флоу с бейджами кэша

compact — для схем на 6–8 узлов: карточки меньше, без подподписей, подписи рёбер спрятаны в tooltip линии. align=left не растягивает узкую схему на весь слайд, бейджи-пилюли висят над узлами.

index.php — точка входаindex.phpКонфигКонфигРоутерРоутерКонтроллерКонтроллерBladeBladeОтвет — HTML в буферОтветне читается с дискаconfig:cacheне читается с дискаroute:cacheне читается с дискаview:cacheindex.php — точка входаindex.phpКонфигКонфигРоутерРоутерКонтроллерКонтроллерBladeBladeОтвет — HTML в буферОтветне читается с дискаconfig:cacheне читается с дискаroute:cacheне читается с дискаview:cache
Кэш: что перестаёт читаться с диска на каждом запросе
13листайте

Управление

← → Space — листать · O — обзор · T — тема · R — чтение

Гамма переключается кнопкой в шапке: blocks, adwaita, monokai. Позиция и тема запоминаются в localStorage, ссылка #s4 ведёт сразу на четвёртый слайд.

Демо-дека движка. Контент урока пишется отдельно в src/parts/part-*.md.

14листайте