Sulu CMS - 导航上下文的页面图标

发布于 2025-01-12 23:41:57 字数 1545 浏览 5 评论 0原文

我想呈现一组可选择的图标,以便为每个页面选择一个图标。选择后,图标应在导航上下文数据中可用,例如通过 Sulu\HeadlessBundle

{
    "_embedded": {
        "items": [
            {
                "id": "ffffffff-ffff-ffff-ffff-fffffffffff",
                "uuid": "ffffffff-ffff-ffff-ffff-fffffffffff",
                "nodeType": 1,
                "changed": "2000-01-01T12:00:00",
                "changer": 1,
                "created": "2022-01-01T12:00:01",
                "publishedState": true,
                "published": "2000-01-01T12:00:01",
                "creator": 1,
                "title": "Foo",
                "locale": "de",
                "webspaceKey": "bar",
                "template": "default",
                "parent": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee",
                "url": "/foo",
                "urls": {
                    "de": "/foo"
                },
                "author": "1",
                "authored": "2000-01-01T12:00:00",
                "order": 20,
                "children": [],
                "nav_icon": {} // Either a Media entity from a system collection, or just a filename to reference the icon with
            }
        ]
    }
}

我知道可以将图标存储为媒体数据,然后通过页面摘录数据,但我不希望我的用户随意上传和选择图标。根据我自己的研究猜测,我也不能将 single_media_selection 限制为系统集合,更不用说摘录选项卡中的图标选择了。

我的任务有方法吗?我尝试添加 UI 选项卡到页面编辑表单,但我似乎无法扩展实际的结构数据,以便序列化图标信息。

I want to present a set of selectable icons to choose one from for each page. When selected, the icon should be available in navigation context data, e.g. via Sulu\HeadlessBundle:

{
    "_embedded": {
        "items": [
            {
                "id": "ffffffff-ffff-ffff-ffff-fffffffffff",
                "uuid": "ffffffff-ffff-ffff-ffff-fffffffffff",
                "nodeType": 1,
                "changed": "2000-01-01T12:00:00",
                "changer": 1,
                "created": "2022-01-01T12:00:01",
                "publishedState": true,
                "published": "2000-01-01T12:00:01",
                "creator": 1,
                "title": "Foo",
                "locale": "de",
                "webspaceKey": "bar",
                "template": "default",
                "parent": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee",
                "url": "/foo",
                "urls": {
                    "de": "/foo"
                },
                "author": "1",
                "authored": "2000-01-01T12:00:00",
                "order": 20,
                "children": [],
                "nav_icon": {} // Either a Media entity from a system collection, or just a filename to reference the icon with
            }
        ]
    }
}

I am aware of the possibility of storing icons as Media data and then applying them via the page excerpt data, but I don't want my users to arbitrarily upload and pick icons. Guessing from my own research I also cannot limit a single_media_selection to a system collection, let alone the icons selection in the excerpt tab.

Is there an approach to my task? I tried adding UI tabs to the page editing form, but I can't seem to extend the actual structure data so that the icon information is serialized.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九歌凝 2025-01-19 23:41:57

我设计了一个利用 Symfony 内核侦听器的解决方案。由于我只需要顶级导航项来显示图标,因此我连接到 kernel.response 并迭代响应内容,获取每个顶级页面的文档信息并提取我已经使用 Sulu Cookbook< 构建的相关扩展数据/a>.

<?php declare(strict_types=1);

namespace App\EventListener;

use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Sulu\Component\DocumentManager\Exception\DocumentManagerException;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

class NavigationListener
{
    public function __construct(private DocumentManagerInterface $documentManager)
    {
    }

    public function onKernelResponse(ResponseEvent $event): void
    {
        $request = $event->getRequest();
        if ($request->attributes->get('_route') !== 'sulu_headless.api.navigation') {
            return;
        }
        $responseObj = json_decode($event->getResponse()->getContent(), true);
        foreach ($responseObj['_embedded']['items'] as &$item) {
            $uuid = $item['uuid'];
            $doc = $this->documentManager->find($uuid);
            $documentExtension = $doc->getExtensionsData()->toArray();
            if (isset($documentExtension['navigation'])) {
                $item['navigationIcon'] = $documentExtension['navigation']['icon'];
            }
        }
        $event->getResponse()->setContent(json_encode($responseObj, JSON_PRETTY_PRINT));
    }
}

从长远来看,将扩展加载信息传递给 HeadlessBundle 会很有趣。

I devised a solution that utilizes the Symfony kernel listeners. Since I only need the top-level navigation items to display an icon, I hooked into the kernel.response of the HeadlessBundle's navigations API route and iterated through the response content, fetching document information for each top-level page and extracting the relevant extension data that I already constructed with the Sulu cookbook.

<?php declare(strict_types=1);

namespace App\EventListener;

use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Sulu\Component\DocumentManager\Exception\DocumentManagerException;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

class NavigationListener
{
    public function __construct(private DocumentManagerInterface $documentManager)
    {
    }

    public function onKernelResponse(ResponseEvent $event): void
    {
        $request = $event->getRequest();
        if ($request->attributes->get('_route') !== 'sulu_headless.api.navigation') {
            return;
        }
        $responseObj = json_decode($event->getResponse()->getContent(), true);
        foreach ($responseObj['_embedded']['items'] as &$item) {
            $uuid = $item['uuid'];
            $doc = $this->documentManager->find($uuid);
            $documentExtension = $doc->getExtensionsData()->toArray();
            if (isset($documentExtension['navigation'])) {
                $item['navigationIcon'] = $documentExtension['navigation']['icon'];
            }
        }
        $event->getResponse()->setContent(json_encode($responseObj, JSON_PRETTY_PRINT));
    }
}

In the long term, it would be interesting to pass extension loading information to the HeadlessBundle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文