diff --git a/packages/guides/src/Compiler/Passes/AutomaticMenuPass.php b/packages/guides/src/Compiler/Passes/AutomaticMenuPass.php index 8dee004fd..077578628 100644 --- a/packages/guides/src/Compiler/Passes/AutomaticMenuPass.php +++ b/packages/guides/src/Compiler/Passes/AutomaticMenuPass.php @@ -17,11 +17,20 @@ use phpDocumentor\Guides\Compiler\CompilerPass; use phpDocumentor\Guides\Nodes\DocumentNode; use phpDocumentor\Guides\Settings\SettingsManager; +use Psr\Log\LoggerInterface; + +use function array_pop; +use function count; +use function explode; +use function implode; +use function in_array; +use function sprintf; final class AutomaticMenuPass implements CompilerPass { public function __construct( private readonly SettingsManager $settingsManager, + private readonly LoggerInterface|null $logger = null, ) { } @@ -43,6 +52,7 @@ public function run(array $documents, CompilerContextInterface $compilerContext) $projectNode = $compilerContext->getProjectNode(); $rootDocumentEntry = $projectNode->getRootDocumentEntry(); + $indexNames = explode(',', $this->settingsManager->getProjectSettings()->getIndexName()); foreach ($documents as $documentNode) { if ($documentNode->isOrphan()) { // Do not add orphans to the automatic menu @@ -53,9 +63,48 @@ public function run(array $documents, CompilerContextInterface $compilerContext) continue; } - $documentEntry = $projectNode->getDocumentEntry($documentNode->getFilePath()); - $documentEntry->setParent($rootDocumentEntry); - $rootDocumentEntry->addChild($documentEntry); + $filePath = $documentNode->getFilePath(); + $pathParts = explode('/', $filePath); + $documentEntry = $projectNode->getDocumentEntry($filePath); + if (count($pathParts) === 1 || count($pathParts) === 2 && in_array($pathParts[1], $indexNames, true)) { + $documentEntry->setParent($rootDocumentEntry); + $rootDocumentEntry->addChild($documentEntry); + continue; + } + + $fileName = array_pop($pathParts); + $path = implode('/', $pathParts); + if (in_array($fileName, $indexNames, true)) { + array_pop($pathParts); + $path = implode('/', $pathParts); + } + + $parentFound = false; + foreach ($indexNames as $indexName) { + $indexFile = $path . '/' . $indexName; + $parentEntry = $projectNode->findDocumentEntry($indexFile); + if ($parentEntry === null) { + continue; + } + + $documentEntry->setParent($parentEntry); + $parentEntry->addChild($documentEntry); + $parentFound = true; + break; + } + + if ($parentFound) { + continue; + } + + $parentEntry = $projectNode->findDocumentEntry($path); + if ($parentEntry === null) { + $this->logger?->warning(sprintf('No parent found for file "%s/%s" attaching it to the document root instead. ', $path, $fileName)); + continue; + } + + $documentEntry->setParent($parentEntry); + $parentEntry->addChild($documentEntry); } return $documents; diff --git a/packages/guides/src/Compiler/Passes/GlobalMenuPass.php b/packages/guides/src/Compiler/Passes/GlobalMenuPass.php index 13ec50799..bdbabff9a 100644 --- a/packages/guides/src/Compiler/Passes/GlobalMenuPass.php +++ b/packages/guides/src/Compiler/Passes/GlobalMenuPass.php @@ -90,14 +90,23 @@ public function run(array $documents, CompilerContextInterface $compilerContext) private function getNavMenuNodeFromDocumentEntries(CompilerContextInterface $compilerContext): NavMenuNode { - $menuEntries = []; $rootDocumentEntry = $compilerContext->getProjectNode()->getRootDocumentEntry(); + $menuEntries = $this->getMenuEntriesFromDocumentEntries($rootDocumentEntry); + + return new NavMenuNode($menuEntries); + } + + /** @return InternalMenuEntryNode[] */ + public function getMenuEntriesFromDocumentEntries(DocumentEntryNode $rootDocumentEntry): array + { + $menuEntries = []; foreach ($rootDocumentEntry->getChildren() as $documentEntryNode) { - $newMenuEntry = new InternalMenuEntryNode($documentEntryNode->getFile(), $documentEntryNode->getTitle(), [], false, 1); + $children = $this->getMenuEntriesFromDocumentEntries($documentEntryNode); + $newMenuEntry = new InternalMenuEntryNode($documentEntryNode->getFile(), $documentEntryNode->getTitle(), $children, false, 1); $menuEntries[] = $newMenuEntry; } - return new NavMenuNode($menuEntries); + return $menuEntries; } private function getNavMenuNodefromTocNode(CompilerContextInterface $compilerContext, TocNode $tocNode, string|null $menuType = null): NavMenuNode diff --git a/tests/Integration/tests-full/automatic_menu/automatic-multilevel-menu/expected/index.html b/tests/Integration/tests-full/automatic_menu/automatic-multilevel-menu/expected/index.html index 407d880ed..2a663cebf 100644 --- a/tests/Integration/tests-full/automatic_menu/automatic-multilevel-menu/expected/index.html +++ b/tests/Integration/tests-full/automatic_menu/automatic-multilevel-menu/expected/index.html @@ -52,11 +52,11 @@
  • Another Page -