+7 988 353-52-54 kompman1@yandex.ru

г. Краснодар

Модуль за 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.

Статья помогла?