Модуль за 15 минут
Пошаговый пример: модуль «Объявление» с полем в настройках, полосой на сайте и экраном в админке.
Сделаем модуль «Объявление»: полоса с текстом над шапкой сайта и экран в админке, где этот текст меняют.
1. Папка и манифест
modules/notice/module.json:
{
"id": "notice",
"name": "Notice bar",
"version": "1.0.0",
"description": "A notice bar above the header",
"category": "marketing",
"icon": "megaphone",
"license": {"type": "open"},
"requires": {"core": "^1.3.29"},
"autoload": {"psr-4": {"Acme\\Notice\\": "src"}},
"class": "Acme\\Notice\\NoticeModule"
}
src/NoticeModule.php:
namespace Acme\Notice;
use NewCMS\Core\Module\Module;
final class NoticeModule extends Module
{
}
config/services.yaml:
services:
_defaults: {autowire: true, autoconfigure: true}
Acme\Notice\:
resource: '../src/'
exclude: ['../src/NoticeModule.php']
2. Полоса на сайте
src/NoticeHook.php:
namespace Acme\Notice;
use NewCMS\Core\Site\SiteContext;
use NewCMS\Core\Theme\Hook\HookProviderInterface;
final class NoticeHook implements HookProviderInterface
{
public function __construct(private readonly SiteContext $site) {}
public function supports(string $hook): bool { return $hook === 'body_top'; }
public function priority(): int { return 0; }
public function render(string $hook, array $context): string
{
$text = (string) ($this->site->storedSettings()['notice']['text'] ?? '');
return $text === '' ? '' : '<div class="notice-bar">' . htmlspecialchars($text) . '</div>';
}
}
assets/storefront.css:
.notice-bar { padding: .5rem 1rem; background: #111827; color: #fff; text-align: center; }
3. API для админки
src/Controller/NoticeController.php:
#[Route('/api/admin/v1/notice', name: 'notice.save', methods: ['PUT'])]
public function save(Request $request): JsonResponse
{
$this->authorization->checkOrFail($this->currentUser->require(), 'system.settings.manage');
$text = mb_substr(trim((string) ($request->toArray()['text'] ?? '')), 0, 200);
$this->site->saveSetting('notice', ['text' => $text]);
return $this->json(['data' => ['text' => $text]]);
}
4. Экран в админке
admin/index.ts регистрирует маршрут /notice и пункт меню, admin/views/NoticeView.vue — поле и кнопка «Сохранить», которая вызывает apiFetch('/notice', { method: 'PUT', body: { text } }).
5. Включить
php bin/console cms:module:install notice
Откройте сайт — над шапкой появилась полоса. Готово: модуль можно упаковать и поставить на любой сайт с 100300 CMS.