Skip to content

Commit

Permalink
add rootCallback to extend root navigation (#16145)
Browse files Browse the repository at this point in the history
* add rootCallback to easily extend navigation

* add an example to the documentation
update upgrade notes
update phpdocs

* use existing class and link generator in example
merge rootCallback example to the existing pageCallback example
rename twig function
  • Loading branch information
hethehe committed Nov 27, 2023
1 parent 6a03ffe commit b2c5423
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
31 changes: 25 additions & 6 deletions doc/03_Documents/03_Navigation.md
Expand Up @@ -270,15 +270,19 @@ For example, generate bootstrap 4.0 style navigation:
```

## Adding Custom Items to the Navigation

In the following example we're adding news items (objects) to the navigation using Twig Extension.

In the following example we're adding
- news items (objects) to an existing navigation with the "pageCallback" attribute
- category items (objects) to the root Navigation with the "rootCallback" attribute
using Twig Extension.

```php
<?php

namespace App\Twig\Extension;

use App\Website\LinkGenerator\NewsLinkGenerator;
use App\Website\LinkGenerator\CategoryLinkGenerator;
use Pimcore\Model\Document;
use Pimcore\Navigation\Container;
use Pimcore\Twig\Extension\Templating\Navigation;
Expand All @@ -289,11 +293,13 @@ class NavigationExtension extends AbstractExtension
{
protected Navigation $navigationHelper;
protected NewsLinkGenerator $newsLinkGenerator;
protected CategoryLinkGenerator $categoryLinkGenerator;

public function __construct(Navigation $navigationHelper, NewsLinkGenerator $newsLinkGenerator)
public function __construct(Navigation $navigationHelper, NewsLinkGenerator $newsLinkGenerator, CategoryLinkGenerator $categoryLinkGenerator)
{
$this->navigationHelper = $navigationHelper;
$this->$newsLinkGenerator = $newsLinkGenerator;
$this->newsLinkGenerator = $newsLinkGenerator;
$this->categoryLinkGenerator = $categoryLinkGenerator;
}

/**
Expand All @@ -302,14 +308,14 @@ class NavigationExtension extends AbstractExtension
public function getFunctions(): array
{
return [
new TwigFunction('app_navigation_news_links', [$this, 'getDataLinks'])
new TwigFunction('app_navigation_links', [$this, 'getNavigationLinks'])
];
}

/**
* @throws \Exception
*/
public function getNewsLinks(Document $document, Document $startNode): Container
public function getNavigationLinks(Document $document, Document $startNode): Container
{
$navigation = $this->navigationHelper->build([
'active' => $document,
Expand All @@ -330,6 +336,19 @@ class NavigationExtension extends AbstractExtension
$page->addPage($uri);
}
}
},
'rootCallback' => function(Container $navigation) {
$list = new \Pimcore\Model\DataObject\Category\Listing;
$list->load();
foreach($list as $category) {
$detailLink = $this->categoryLinkGenerator->generate($category);
$categoryDocument = new \Pimcore\Navigation\Page\Document([
"label" => $category->getTitle(),
"id" => "object-" . $category->getId(),
"uri" => $detailLink,
]);
$navigation->addPage($categoryDocument);
}
}
]);

Expand Down
2 changes: 2 additions & 0 deletions doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md
Expand Up @@ -6,6 +6,8 @@
- Using `outputFormat` config for `Pimcore\Model\Document\Editable\Date` editable is deprecated, use `outputIsoFormat` config instead.
#### [Data Objects]:
- Methods `getAsIntegerCast()` and `getAsFloatCast()` of the `Pimcore\Model\DataObject\Data` class are deprecated now.
#### [Navigation]
- Add rootCallback option to `Pimcore\Navigation\Builder::getNavigation()`

## Pimcore 11.1.0
### Elements
Expand Down
8 changes: 8 additions & 0 deletions lib/Navigation/Builder.php
Expand Up @@ -66,6 +66,7 @@ protected function configureOptions(OptionsResolver $options): void
'root' => null,
'htmlMenuPrefix' => null,
'pageCallback' => null,
'rootCallback' => null,
'cache' => true,
'cacheLifetime' => null,
'maxDepth' => null,
Expand All @@ -76,6 +77,7 @@ protected function configureOptions(OptionsResolver $options): void
$options->setAllowedTypes('root', [Document::class, 'null']);
$options->setAllowedTypes('htmlMenuPrefix', ['string', 'null']);
$options->setAllowedTypes('pageCallback', ['callable', 'null']);
$options->setAllowedTypes('rootCallback', ['callable', 'null']);
$options->setAllowedTypes('cache', ['string', 'bool']);
$options->setAllowedTypes('cacheLifetime', ['int', 'null']);
$options->setAllowedTypes('maxDepth', ['int', 'null']);
Expand All @@ -93,6 +95,7 @@ protected function resolveOptions(array $options): array
* root?: ?Document,
* htmlMenuPrefix?: ?string,
* pageCallback?: ?callable,
* rootCallback?: ?callable,
* cache?: string|bool,
* cacheLifetime?: ?int,
* maxDepth?: ?int,
Expand All @@ -108,6 +111,7 @@ public function getNavigation(array $params): Container
'root' => $navigationRootDocument,
'htmlMenuPrefix' => $htmlMenuIdPrefix,
'pageCallback' => $pageCallback,
'rootCallback' => $rootCallback,
'cache' => $cache,
'cacheLifetime' => $cacheLifetime,
'maxDepth' => $maxDepth,
Expand Down Expand Up @@ -160,6 +164,10 @@ public function getNavigation(array $params): Container
$navigation->addPages($rootPage);
}

if ($rootCallback instanceof \Closure) {
$rootCallback($navigation);
}

// we need to force caching here, otherwise the active classes and other settings will be set and later
// also written into cache (pass-by-reference) ... when serializing the data directly here, we don't have this problem
if ($cacheEnabled) {
Expand Down

0 comments on commit b2c5423

Please sign in to comment.