Skip to content

Commit

Permalink
Merge pull request #916 from phpDocumentor/backport/1.x/pr-910
Browse files Browse the repository at this point in the history
[1.x] Merge pull request #910 from phpDocumentor/speed-improvement
  • Loading branch information
phpdoc-bot authored Mar 9, 2024
2 parents 01c5711 + c158f48 commit 4b10c80
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 20 deletions.
6 changes: 6 additions & 0 deletions packages/guides/resources/config/guides.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
use phpDocumentor\Guides\TemplateRenderer;
use phpDocumentor\Guides\Twig\AssetsExtension;
use phpDocumentor\Guides\Twig\EnvironmentBuilder;
use phpDocumentor\Guides\Twig\GlobalMenuExtension;
use phpDocumentor\Guides\Twig\Theme\ThemeManager;
use phpDocumentor\Guides\Twig\TwigTemplateRenderer;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
Expand Down Expand Up @@ -207,6 +208,11 @@
->tag('twig.extension')
->autowire()

->set(GlobalMenuExtension::class)
->arg('$nodeRenderer', service('phpdoc.guides.output_node_renderer'))
->tag('twig.extension')
->autowire()

->set(ThemeManager::class)
->arg('$filesystemLoader', service(FilesystemLoader::class))
->arg(
Expand Down
2 changes: 1 addition & 1 deletion packages/guides/src/RenderContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public function getDirName(): string

return $dirname;
}

public function hasCurrentFileName(): bool
{
return $this->currentFileName !== null;
Expand Down
24 changes: 5 additions & 19 deletions packages/guides/src/Twig/AssetsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@
use phpDocumentor\Guides\Meta\Target;
use phpDocumentor\Guides\NodeRenderers\NodeRenderer;
use phpDocumentor\Guides\Nodes\BreadCrumbNode;
use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\ReferenceResolvers\DocumentNameResolverInterface;
use phpDocumentor\Guides\RenderContext;
use phpDocumentor\Guides\Renderer\UrlGenerator\UrlGeneratorInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Stringable;
use Throwable;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Twig\TwigTest;
Expand All @@ -39,13 +37,16 @@

final class AssetsExtension extends AbstractExtension
{
private GlobalMenuExtension $menuExtension;

/** @param NodeRenderer<Node> $nodeRenderer */
public function __construct(
private readonly LoggerInterface $logger,
private readonly NodeRenderer $nodeRenderer,
private readonly DocumentNameResolverInterface $documentNameResolver,
private readonly UrlGeneratorInterface $urlGenerator,
) {
$this->menuExtension = new GlobalMenuExtension($this->nodeRenderer);
}

/** @return TwigFunction[] */
Expand All @@ -56,7 +57,7 @@ public function getFunctions(): array
new TwigFunction('renderNode', $this->renderNode(...), ['is_safe' => ['html'], 'needs_context' => true]),
new TwigFunction('renderLink', $this->renderLink(...), ['is_safe' => ['html'], 'needs_context' => true]),
new TwigFunction('renderBreadcrumb', $this->renderBreadcrumb(...), ['is_safe' => ['html'], 'needs_context' => true]),
new TwigFunction('renderMenu', $this->renderMenu(...), ['is_safe' => ['html'], 'needs_context' => true]),
new TwigFunction('renderMenu', $this->renderMenu(...), ['is_safe' => ['html'], 'needs_context' => true, 'deprecated' => true]),
new TwigFunction('renderTarget', $this->renderTarget(...), ['is_safe' => ['html'], 'needs_context' => true]),
];
}
Expand Down Expand Up @@ -136,22 +137,7 @@ public function renderBreadcrumb(array $context): string
/** @param array{env: RenderContext} $context */
public function renderMenu(array $context, string $menuType, int $maxMenuCount = 0): string
{
$renderContext = $this->getRenderContext($context);
$globalMenues = $renderContext->getProjectNode()->getGlobalMenues();
$menues = [];
foreach ($globalMenues as $menu) {
$menu = $menu->withOptions(['menu' => $menuType]);
try {
$menu = $menu->withCurrentPath($renderContext->getCurrentFileName());
$menu = $menu->withRootlinePaths($renderContext->getCurrentFileRootline());
} catch (Throwable) {
// do nothing, we are in a context without active menu like single page or functional test
}

$menues[] = $menu;
}

return $this->nodeRenderer->render(new CollectionNode($menues), $renderContext);
return $this->menuExtension->renderMenu($context, $menuType);
}

/** @param array{env: RenderContext} $context */
Expand Down
83 changes: 83 additions & 0 deletions packages/guides/src/Twig/GlobalMenuExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Twig;

use phpDocumentor\Guides\NodeRenderers\NodeRenderer;
use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RenderContext;
use RuntimeException;
use Throwable;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

final class GlobalMenuExtension extends AbstractExtension
{
/**
* Contains cached menu html for each render context to prevent multiple rendering of the same menu.
*
* @var array<string, string>
*/
private array $menuCache = [];

/** @param NodeRenderer<Node> $nodeRenderer */
public function __construct(
private readonly NodeRenderer $nodeRenderer,
) {
}

/** @return TwigFunction[] */
public function getFunctions(): array
{
return [
new TwigFunction('renderMenu', $this->renderMenu(...), ['is_safe' => ['html'], 'needs_context' => true]),
];
}

/** @param array{env: RenderContext} $context */
public function renderMenu(array $context, string $menuType): string
{
$renderContext = $this->getRenderContext($context);
$globalMenues = $renderContext->getProjectNode()->getGlobalMenues();
if (isset($this->menuCache[$renderContext->getCurrentFileName() . '::' . $menuType])) {
return $this->menuCache[$renderContext->getCurrentFileName() . '::' . $menuType];
}

$menues = [];
foreach ($globalMenues as $menu) {
$menu = $menu->withOptions(['menu' => $menuType]);
try {
$menu = $menu->withCurrentPath($renderContext->getCurrentFileName());
$menu = $menu->withRootlinePaths($renderContext->getCurrentFileRootline());
} catch (Throwable) {
// do nothing, we are in a context without active menu like single page or functional test
}

$menues[] = $menu;
}

return $this->menuCache[$renderContext->getCurrentFileName() . '::' . $menuType] = $this->nodeRenderer->render(new CollectionNode($menues), $renderContext);
}

/** @param array{env: RenderContext} $context */
private function getRenderContext(array $context): RenderContext
{
$renderContext = $context['env'] ?? null;
if (!$renderContext instanceof RenderContext) {
throw new RuntimeException('Render context must be set in the twig global state to render nodes');
}

return $renderContext;
}
}

0 comments on commit 4b10c80

Please sign in to comment.