WordPress направи една идея позната на всеки, който поддържа сайт: сайтът върши основното, а приставките и темите добавят останалото, инсталират се от zip и се включват и изключват от администрацията. Разработчиците на Laravel обикновено получават обратното: чиста рамка и много свобода, но всяка функция, която клиентът поиска, става промяна в самото приложение. PN Scripts Press е нашата CMS с отворен код, която пренася модела на WordPress в Laravel: страници от блокове, блог, менюта, медия, SEO полета и версии в администрация на Filament, разширявани с приставки и теми, които са папки с манифест. Тук я инсталираме, пишем малка приставка и тема и обясняваме докъде стига моделът.
#Инсталиране
Трябват ви PHP 8.4, Composer, Node.js и npm. Пакетът е в Packagist, така че една команда създава нов сайт, копира примерния файл със средата, задава ключа на приложението, създава база SQLite и пуска миграциите:
composer create-project pnscripts/pn-press my-site
cd my-site
php artisan db:seed
npm ci
npm run build
php artisan serve
Seeder-ът добавя демонстрационен сайт: начална страница, страници „За нас“ и „Контакти“, две менюта, темата Folio и двете примерни приставки, Contact Form и SEO Sitemap. Пропуснете го за празен сайт. Изграждането на интерфейса е нужно, защото пакетът не носи компилирани стилове. Отворете http://127.0.0.1:8000 за сайта и /admin за администрацията; създаденият администраторски профил е описан в README, а имейлът и паролата му трябва да се сменят веднага.
Преди сайтът да стане публичен, сменете две настройки в .env. Новият проект е проект за разработка: APP_ENV=local и APP_DEBUG=true показват подробни грешки и лента за отстраняване на грешки на всяка страница. Задайте APP_ENV=production и APP_DEBUG=false и ползвайте MySQL или PostgreSQL, ако няколко редактори ще работят едновременно.
#Какво е приставка
Приставката е папка в plugins/ с файл plugin.json. Манифестът дава името на приставката, версията ѝ, версията на Press, която ѝ трябва, пространство от имена, което Press зарежда автоматично от собствената папка на приставката (без стъпка с Composer), и доставчик на услуги (service provider) на Laravel, в който приставката върши работата си. Незадължителни са миграции, изгледи, файл с маршрути и екрани в администрацията. Приставката минава през пет състояния: инсталирана (разархивирана, нищо не работи), активна (доставчикът и миграциите ѝ се пускат), обновена (нова версия заменя папката и новите миграции се пускат веднъж), деактивирана (спира да се зарежда, данните ѝ остават) и деинсталирана (миграциите ѝ се връщат назад, а папката и настройките ѝ се изтриват).
Приставките променят сайта чрез действия и филтри, както в WordPress: add_action и do_action, за да изпълнят код в определена точка, и add_filter и apply_filters, за да променят стойност по пътя ѝ към страницата. Press дава точки за заглавната част и тялото на страницата, блоковете на страниците, съдържанието на публикациите, менютата, шаблоните на страници, екрана с настройки и картата на сайта.
#Да напишем приставка: списък на разделите
Дългите публикации се четат по-лесно с кратък списък на разделите им най-отгоре. Press няма такъв, затова е добра първа приставка. Трябват ѝ два файла. Манифестът:
{
"slug": "contents",
"name": "Contents",
"version": "1.0.0",
"description": "A list of a post's sections above its text, with links to each heading.",
"author": "You",
"requires": { "press": ">=1.0" },
"provider": "Acme\\Contents\\ContentsServiceProvider",
"autoload": { "psr-4": { "Acme\\Contents\\": "src/" } }
}
И доставчикът на услуги в src/ContentsServiceProvider.php:
<?php
namespace Acme\Contents;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class ContentsServiceProvider extends ServiceProvider
{
public function boot(): void
{
add_filter('post.content', function (string $html): string {
$items = [];
$html = preg_replace_callback('#<h2>(.*?)</h2>#s', function (array $m) use (&$items): string {
$text = html_entity_decode(trim(strip_tags($m[1])), ENT_QUOTES | ENT_HTML5, 'UTF-8');
$id = (Str::slug($text) ?: 'section').'-'.(count($items) + 1);
$items[] = '<li><a href="#'.e($id).'">'.e($text).'</a></li>';
return '<h2 id="'.e($id).'">'.$m[1].'</h2>';
}, $html);
// The post body is printed as HTML: escape everything you add to it.
if (count($items) < (int) press_setting('plugin.contents.min_sections', 3)) {
return $html;
}
return '<nav aria-label="Contents"><p class="press-eyebrow">Contents</p><ol>'
.implode('', $items).'</ol></nav>'.$html;
});
add_filter('settings.sections', function (array $sections): array {
$sections[] = Section::make('Contents')->schema([
TextInput::make('plugin.contents.min_sections')
->label('Show the list from this many sections')->numeric()->minValue(1)->default(3),
]);
return $sections;
});
}
}
Филтърът post.content получава HTML на публикацията. Приставката дава id на всяко заглавие от второ ниво, събира заглавията в списък с връзки и слага списъка над текста, когато разделите са поне три. Вторият филтър добавя раздел в екрана Settings на администрацията, за да може редакторът да промени това число, без да пипа код; press_setting() го чете. Две подробности си струва да се копират във всяка приставка. Тялото на публикацията се отпечатва като HTML, затова всичко, което приставката добавя, се екранира с e(). А знаци като & се декодират преди екранирането, иначе „Q&A“ ще се покаже с видимо &, както стана в първата ни версия.
Архивирайте папката и я инсталирайте от командния ред в папката на сайта или качете zip файла от Extend, Plugins в администрацията (тя е на английски):
zip -r contents.zip contents
php artisan press:plugin install contents.zip
php artisan press:plugin activate contents
В публикация със заглавия „Как да планирате седмицата“, „Q&A“ и „Done“ приставката добавя този списък и тези id; Laravel превръща заглавието на кирилица в id с латиница:
<nav aria-label="Contents"><p class="press-eyebrow">Contents</p><ol><li><a href="#kak-da-planirate-sedmicata-1">Как да планирате седмицата</a></li><li><a href="#qa-2">Q&A</a></li><li><a href="#done-3">Done</a></li></ol></nav>
<h2 id="kak-da-planirate-sedmicata-1">
<h2 id="qa-2">
<h2 id="done-3">
За да промените приставката по-късно, вдигнете версията ѝ, архивирайте я отново и я инсталирайте с --replace; тя остава активна, а ако има нови миграции, те се пускат при следващата заявка.
#Повече от филтри
Същият доставчик може да регистрира блокове, които редакторите добавят в редактора на страници, файл с маршрути за публични страници (зарежда се с маршрутите на сайта, така че php artisan route:cache работи, а маршрутите на деактивирана приставка отговарят с 404 дори от стар кеш) и клас-приставка на Filament, който добавя екрани в администрацията. Примерът Contact Form показва всичко това: блок, маршрут с ограничение на заявките и капан за ботове, собствена таблица, раздел в настройките и входяща кутия за съобщенията с експорт в CSV.
#Тема с настройки
Темата е папка в themes/ с файл theme.json. Всеки Blade изглед в папката ѝ views/ заменя изгледа по подразбиране със същия път, а изгледите, които не копирате, продължават да работят. Настройките, описани в манифеста, се появяват под Customize в екрана Themes, проверяват се според типа си и стигат до страницата като CSS променливи (цвят с име accent става --press-accent) и атрибути на страницата. Минимална тема с цвят за акцент, бележка във футъра и собствен файл със стилове:
{
"slug": "plain-ink",
"name": "Plain Ink",
"version": "1.0.0",
"description": "Black on white with one accent colour.",
"author": "You",
"requires": { "press": ">=1.0" },
"stylesheet": "assets/theme.css",
"settings": [
{ "key": "accent", "label": "Accent colour", "type": "color", "default": "#b4232a" },
{ "key": "footer_note", "label": "Footer note", "type": "text", "default": "Printed on the web." }
]
}
Копирайте resources/views/press/partials/footer.blade.php на същия път в папката views/ на темата и сменете реда с авторските права, за да отпечатва настройката:
<p>© {{ now()->year }} {{ $siteName }}. {{ app(\App\Press\Themes\ThemeManager::class)->setting('footer_note') }}</p>
Инсталирайте я и я активирайте с php artisan press:theme или я качете от Appearance, Themes, където Preview показва сайта с новата тема само на вас, преди Activate да я включи за всички. Едно ограничение е важно тук: тема, качена на работещ сайт, не минава през изграждането на интерфейса, затова стиловете ѝ трябва да са в собствения ѝ файл или да ползва класовете, които ядрото вече компилира.
#Сигурност: приставката е код
Приставката работи като PHP с пълен достъп до сайта и базата му, точно като приставка за WordPress, затова инсталирайте само код, на който вярвате, и оставете правото да се инсталират приставки и теми на администраторите. Press проверява всяко качване, преди да запише каквото и да е: размер на архива, брой файлове, размер след разархивиране и степен на компресия; без абсолютни пътища, .., обратни наклонени черти, символни връзки или скрити файлове като .env и .htaccess; само позволени типове файлове. Темата може да съдържа PHP само като Blade изгледи; когато добавихме обикновен .php файл в тема, инсталирането беше отказано. На сайтове, на които никой не бива да качва код от браузъра, задайте PRESS_PACKAGE_UPLOADS=false и инсталирайте през SSH.
#Докъде стига моделът
Press няма каталог с приставки и теми, автоматични обновления и отдалечено инсталиране, и това е нарочно: код стига до сайта само когато някой го сложи там. Няма коментари, многоезично съдържание и поддръжка на много сайтове. Приставките се пишат на PHP за Laravel и Filament, така че авторът трябва да познава и двете; приставки за WordPress не работят в нея.
#Откъде да я вземете
PN Scripts Press е безплатна и с отворен код под лиценз MIT, в GitHub и Packagist. Изградена е с Laravel 13, Filament 5, Livewire 4, Spatie Permission и Tailwind CSS 4 и идва с темите Folio и Nocturne, двете примерни приставки и ръководства за писане на приставки и теми.
#Често задавани въпроси
Работят ли приставки за WordPress в PN Scripts Press?
Не. Моделът е същият, папки с манифест, действия и филтри, активиране от администрацията, но приставките се пишат за Laravel и Filament.
Как да инсталирам приставка без администрацията?
Пуснете php artisan press:plugin install със zip файла или папката, после php artisan press:plugin activate с краткото име на приставката.
Безопасно ли е да се качват приставки от браузъра?
Качванията се проверяват за размер, пътища, скрити файлове и типове файлове, но приставката пак е PHP с пълен достъп до сайта. Инсталирайте само код, на който вярвате, или изключете качването с PRESS_PACKAGE_UPLOADS=false.
Какво трябва да сменя, преди сайтът да стане публичен?
Имейла и паролата на създадения администратор, APP_ENV=production и APP_DEBUG=false в .env и обикновено MySQL или PostgreSQL вместо SQLite.
Коментари
Коментари
Напишете първия коментар.
Оставете коментар