Skip to main content

Navigation Enhancement

It's crucial to build a solid cached navigation to prevent performance lags!

Therefor you should always prebuild your navigation within the NavigationPageCallbackEvent! Everything your going to add there will be cached.

Debugging

While building a navigation on backend layer, it can be quite annoying, since every navigation build gets cached imitatively.

To disable caching while developing you need to modify the NavigationHandler class:

// [...]

// line 39
$navigationParams = [];

// add this line to prevent caching
$navigationParams['cache'] = false;

// [...]

Event Listener

<?php

namespace App\EventListener;

use OpenDxp\Bundle\HeadlessBundle\Context\OpenDxpContext;
use OpenDxp\Bundle\HeadlessBundle\Event\NavigationPageCallbackEvent;
use OpenDxp\Bundle\HeadlessBundle\Routing\HeadlessRouterInterface;
use OpenDxp\Navigation\Container;
use OpenDxp\Navigation\Page;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class NavigationPageCallbackListener implements EventSubscriberInterface
{
public function __construct(protected HeadlessRouterInterface $headlessRouter)
{
}

public static function getSubscribedEvents(): array
{
return [
NavigationPageCallbackEvent::class => 'onPageCallback'
];
}

public function onPageCallback(NavigationPageCallbackEvent $event): void
{
$navigationName = $event->getNavigationFilter()?->getNavigationName();
$opendxpContext = $event->getHeadlessContextStack()?->getContext(OpenDxpContext::class);

if (!$opendxpContext instanceof OpenDxpContext) {
return;
}

if ($navigationName === 'my_special_navigation') {
$this->enrichSpecialNavigation($opendxpContext, $event->getPage());
}
}

protected function enrichSpecialNavigation(OpenDxpContext $opendxpContext, Page $page): void
{
$page->set('customProperties', [
'my_additional_property' => 42,
]);

// for example: if the OpenDXP document has a specific class,
// we want to add some more pages to it!
if (str_contains($page->getClass(), 'special_dynamic_nav_starts_here')) {
$this->addAdditionalNodes($opendxpContext, $page);
}
}

protected function addAdditionalNodes(OpenDxpContext $opendxpContext, Page $page): void
{
$objectListing = new Listing();

foreach ($objectListing as $object) {

$customAttributes = [
'my_additional_object_property' => $object->getTitle(),
];

$page->addPage([
'id' => sprintf('my_object_%s', $object->getId()),
'uri' => $this->headlessRouter->generate(
'',
[],
[
'locale' => $opendxpContext->getLocale(),
'site' => $opendxpContext->getSite()
],
$object,
HeadlessRouterInterface::OPENDXP_ROUTE,
UrlGeneratorInterface::ABSOLUTE_PATH
),
'label' => $object->myLabel(),
'customProperties' => $customAttributes,
'documentType' => MyObjectClass::class,
'documentId' => $object->getId(),
]);
}
}
}