Skip to content

Commit

Permalink
Merge pull request #1128 from phpDocumentor/task/automenu2
Browse files Browse the repository at this point in the history
[FEATURE] Support automatically created multi-level menus
  • Loading branch information
jaapio authored Oct 11, 2024
2 parents 5ad233a + f030169 commit 0adfe93
Show file tree
Hide file tree
Showing 24 changed files with 711 additions and 69 deletions.
55 changes: 52 additions & 3 deletions packages/guides/src/Compiler/Passes/AutomaticMenuPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) {
}

Expand All @@ -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
Expand All @@ -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;
Expand Down
15 changes: 12 additions & 3 deletions packages/guides/src/Compiler/Passes/GlobalMenuPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
<li>
<a href="someDirectory/anotherDirectory/index.html"
class="nav-link">Another Page</a>
<ul class="level-2">
<ul class="level-1">
<li>
<a href="someDirectory/anotherDirectory/yetAnotherDirectory/index.html"
class="nav-link">Yet Another Page</a>
<ul class="level-3">
<ul class="level-1">
<li>
<a href="someDirectory/anotherDirectory/yetAnotherDirectory/andYetAnotherDirectory/index.html"
class="nav-link">And Yet Another Page</a>
Expand Down Expand Up @@ -88,33 +88,6 @@ <h1>Document Title</h1>

<p>Lorem Ipsum Dolor.</p>

<div class="toc">
<ul class="menu-level">
<li class="toc-item">
<a href="someDirectory/index.html#some-page">Some Page</a>
<ul class="menu-level-1">
<li class="toc-item">
<a href="someDirectory/anotherDirectory/index.html#another-page">Another Page</a>
<ul class="menu-level-2">
<li class="toc-item">
<a href="someDirectory/anotherDirectory/yetAnotherDirectory/index.html#yet-another-page">Yet Another Page</a>
<ul class="menu-level-3">
<li class="toc-item">
<a href="someDirectory/anotherDirectory/yetAnotherDirectory/andYetAnotherDirectory/index.html#and-yet-another-page">And Yet Another Page</a>


</li>
</ul>

</li>
</ul>

</li>
</ul>

</li>
</ul>
</div>
</div>
<!-- content end -->
</div>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<title>Dir 2 Title</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<header class="">

<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">

<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a href="../anotherPage.html" class="nav-link">
Another Page
</a>
</li><li class="nav-item">
<a href="../dir1/index.html" class="nav-link">
Dir 1 Title
</a>
</li><li class="nav-item">
<a href="#" class="nav-link current active" aria-current="page">
Dir 2 Title
</a>
</li>
<ul class="level-">
<li class="nav-item">
<a href="../anotherPage.html"
class="nav-link">Another Page</a>
</li>
<li class="nav-item">
<a href="../dir1/index.html"
class="nav-link">Dir 1 Title</a>
</li>
<li class="nav-item">
<a href="#"
class="nav-link current active" aria-current="page">Dir 2 Title</a>
</li>
<li class="nav-item">
<a href="../somePage.html"
class="nav-link">Some Page</a>
</li>
<li class="nav-item">
<a href="../yetAnotherPage.html"
class="nav-link">Yet Another Page</a>
</li>
</ul>
<li class="nav-item">
<a href="../somePage.html" class="nav-link">
Some Page
</a>
</li><li class="nav-item">
<a href="../yetAnotherPage.html" class="nav-link">
Yet Another Page
</a>
</li></ul>

</div>
</div>
</nav>
</header>
<main id="main-content">
<div class="container">
<div class="container">
<div class="row">
<div class="col-lg-3">
<nav class="nav flex-column">
<ul class="menu-level-main">
<li>
<a href="../anotherPage.html"
class="nav-link">Another Page</a>
</li>
<li>
<a href="../dir1/index.html"
class="nav-link">Dir 1 Title</a>
</li>
<li>
<a href="#"
class="nav-link current active" aria-current="page">Dir 2 Title</a>
<ul class="level-1">
<li>
<a href="somePage.html"
class="nav-link">Some Page in dir 2</a>
</li>
<li>
<a href="subdir1/index.html"
class="nav-link">Subdir 1 Title</a>
</li>
<li>
<a href="subdir2/index.html"
class="nav-link">Subdir 2 Title</a>
<ul class="level-1">
<li>
<a href="subdir2/somePage.html"
class="nav-link">Some Page in dir 2</a>
</li>
<li>
<a href="subdir2/subsubdir1/index.html"
class="nav-link">Subsubdir 1 Title</a>
</li>
</ul>

</li>
<li>
<a href="yetAnotherPage.html"
class="nav-link">Yet Another Page</a>
</li>
</ul>

</li>
<li>
<a href="../somePage.html"
class="nav-link">Some Page</a>
</li>
<li>
<a href="../yetAnotherPage.html"
class="nav-link">Yet Another Page</a>
</li>
</ul>
</nav>

</div>
<div class="col-lg-9">

<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="../index.html">Document Title</a></li>
<li class="breadcrumb-item"><a href="#">Dir 2 Title</a></li>
</ol>
</nav>
<!-- content start -->
<div class="section" id="dir-2-title">
<h1>Dir 2 Title</h1>

<p>Lorem Ipsum Dolor.</p>

</div>
<!-- content end -->
</div>
</div>
</div>
</div>
</main>

<!-- Optional JavaScript; choose one of the two! -->

<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
-->
</body>
</html>
Loading

0 comments on commit 0adfe93

Please sign in to comment.