Skip to content

Commit cdd6e82

Browse files
authored
Merge pull request #783 from phpDocumentor/feature/menu-depth
[FEATURE] Handle Global Menu depth independently from toc
2 parents e4f5c47 + 4e99702 commit cdd6e82

File tree

44 files changed

+939
-35
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+939
-35
lines changed

packages/guides-cli/resources/schema/guides.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<xsd:attribute name="theme" type="xsd:string"/>
2929
<xsd:attribute name="default-code-language" type="xsd:string"/>
3030
<xsd:attribute name="links-are-relative" type="xsd:string"/>
31+
<xsd:attribute name="max-menu-depth" type="xsd:int"/>
3132

3233
</xsd:complexType>
3334

packages/guides/src/Compiler/Passes/GlobalMenuPass.php

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@
77
use phpDocumentor\Guides\Compiler\CompilerContext;
88
use phpDocumentor\Guides\Compiler\CompilerPass;
99
use phpDocumentor\Guides\Nodes\DocumentNode;
10+
use phpDocumentor\Guides\Nodes\DocumentTree\DocumentEntryNode;
11+
use phpDocumentor\Guides\Nodes\Menu\MenuEntryNode;
1012
use phpDocumentor\Guides\Nodes\Menu\NavMenuNode;
13+
use phpDocumentor\Guides\Nodes\Menu\TocNode;
14+
use phpDocumentor\Guides\Settings\SettingsManager;
1115
use Throwable;
1216

17+
use function array_map;
18+
use function assert;
19+
20+
use const PHP_INT_MAX;
21+
1322
class GlobalMenuPass implements CompilerPass
1423
{
24+
public function __construct(
25+
private readonly SettingsManager $settingsManager,
26+
) {
27+
}
28+
1529
public function getPriority(): int
1630
{
1731
return 20; // must be run very late
@@ -29,7 +43,7 @@ public function run(array $documents, CompilerContext $compilerContext): array
2943
$rootDocumentEntry = $projectNode->getRootDocumentEntry();
3044
} catch (Throwable) {
3145
// Todo: Functional tests have not root document entry
32-
return [];
46+
return $documents;
3347
}
3448

3549
$rootDocument = null;
@@ -46,12 +60,70 @@ public function run(array $documents, CompilerContext $compilerContext): array
4660

4761
$menuNodes = [];
4862
foreach ($rootDocument->getTocNodes() as $tocNode) {
49-
$menuNode = NavMenuNode::fromTocNode($tocNode);
63+
$menuNode = $this->getNavMenuNodefromTocNode($compilerContext, $tocNode);
5064
$menuNodes[] = $menuNode->withCaption($tocNode->getCaption());
5165
}
5266

5367
$projectNode->setGlobalMenues($menuNodes);
5468

5569
return $documents;
5670
}
71+
72+
private function getNavMenuNodefromTocNode(CompilerContext $compilerContext, TocNode $tocNode, string|null $menuType = null): NavMenuNode
73+
{
74+
$node = new NavMenuNode($tocNode->getFiles());
75+
$self = $this;
76+
$menuEntries = array_map(static function (MenuEntryNode $tocEntry) use ($compilerContext, $self) {
77+
return $self->getMenuEntryWithChildren($compilerContext, $tocEntry);
78+
}, $tocNode->getMenuEntries());
79+
$node = $node->withMenuEntries($menuEntries);
80+
$options = $tocNode->getOptions();
81+
unset($options['hidden']);
82+
unset($options['titlesonly']);
83+
unset($options['maxdepth']);
84+
if ($menuType !== null) {
85+
$options['menu'] = $menuType;
86+
}
87+
88+
$node = $node->withOptions($options);
89+
assert($node instanceof NavMenuNode);
90+
91+
return $node;
92+
}
93+
94+
private function getMenuEntryWithChildren(CompilerContext $compilerContext, MenuEntryNode $menuEntry): MenuEntryNode
95+
{
96+
$maxdepth = $this->settingsManager->getProjectSettings()->getMaxMenuDepth();
97+
$maxdepth = $maxdepth < 1 ? PHP_INT_MAX : $maxdepth + 1;
98+
$documentEntryOfMenuEntry = $compilerContext->getProjectNode()->getDocumentEntry($menuEntry->getUrl());
99+
$newMenuEntry = new MenuEntryNode($menuEntry->getUrl(), $menuEntry->getValue(), [], false, 2);
100+
$this->addSubEntries($compilerContext, $newMenuEntry, $documentEntryOfMenuEntry, 3, $maxdepth);
101+
102+
return $newMenuEntry;
103+
}
104+
105+
private function addSubEntries(
106+
CompilerContext $compilerContext,
107+
MenuEntryNode $sectionMenuEntry,
108+
DocumentEntryNode $documentEntry,
109+
int $currentLevel,
110+
int $maxDepth,
111+
): void {
112+
if ($maxDepth < $currentLevel) {
113+
return;
114+
}
115+
116+
foreach ($documentEntry->getChildren() as $subDocumentEntryNode) {
117+
$subMenuEntry = new MenuEntryNode(
118+
$subDocumentEntryNode->getFile(),
119+
$subDocumentEntryNode->getTitle(),
120+
[],
121+
false,
122+
$currentLevel,
123+
'',
124+
);
125+
$sectionMenuEntry->addMenuEntry($subMenuEntry);
126+
$this->addSubEntries($compilerContext, $subMenuEntry, $subDocumentEntryNode, $currentLevel + 1, $maxDepth);
127+
}
128+
}
57129
}

packages/guides/src/DependencyInjection/GuidesExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function getConfigTreeBuilder(): TreeBuilder
8282
->scalarNode('fail_on_log')->end()
8383
->scalarNode('show_progress')->end()
8484
->scalarNode('links_are_relative')->end()
85+
->scalarNode('max_menu_depth')->end()
8586
->arrayNode('base_template_paths')
8687
->defaultValue([])
8788
->scalarPrototype()->end()
@@ -201,6 +202,10 @@ public function load(array $configs, ContainerBuilder $container): void
201202
$projectSettings->setFailOnError((bool) $config['show_progress']);
202203
}
203204

205+
if (isset($config['max_menu_depth'])) {
206+
$projectSettings->setMaxMenuDepth((int) $config['max_menu_depth']);
207+
}
208+
204209
if (isset($config['default_code_language'])) {
205210
$projectSettings->setDefaultCodeLanguage((string) $config['default_code_language']);
206211
}

packages/guides/src/Nodes/Menu/NavMenuNode.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
namespace phpDocumentor\Guides\Nodes\Menu;
1515

16-
use function assert;
1716
use function is_scalar;
1817

1918
class NavMenuNode extends MenuNode
@@ -40,24 +39,6 @@ public function isPageLevelOnly(): bool
4039
return true;
4140
}
4241

43-
public static function fromTocNode(TocNode $tocNode, string|null $menuType = null): NavMenuNode
44-
{
45-
$node = new NavMenuNode($tocNode->getFiles());
46-
$node = $node->withMenuEntries($tocNode->getMenuEntries());
47-
$options = $tocNode->getOptions();
48-
unset($options['hidden']);
49-
unset($options['titlesonly']);
50-
unset($options['maxdepth']);
51-
if ($menuType !== null) {
52-
$options['menu'] = $menuType;
53-
}
54-
55-
$node = $node->withOptions($options);
56-
assert($node instanceof NavMenuNode);
57-
58-
return $node;
59-
}
60-
6142
public function withCurrentPath(string|null $currentPath): NavMenuNode
6243
{
6344
$that = clone $this;

packages/guides/src/Settings/ProjectSettings.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ProjectSettings
2424
private bool $showProgressBar = true;
2525
private bool $linksRelative = false;
2626
private string $defaultCodeLanguage = '';
27+
private int $maxMenuDepth = 0;
2728

2829
public function getTitle(): string
2930
{
@@ -188,4 +189,16 @@ public function setCopyright(string $copyright): void
188189
{
189190
$this->copyright = $copyright;
190191
}
192+
193+
public function getMaxMenuDepth(): int
194+
{
195+
return $this->maxMenuDepth;
196+
}
197+
198+
public function setMaxMenuDepth(int $maxMenuDepth): ProjectSettings
199+
{
200+
$this->maxMenuDepth = $maxMenuDepth;
201+
202+
return $this;
203+
}
191204
}

tests/Integration/tests-full/bootstrap/bootstrap-default-menu-several/expected/anotherPage.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h2>Main Menu</h2>
7979
class="nav-link">
8080
Subpages
8181
</a>
82-
<ul class="level-1">
82+
<ul class="level-2">
8383
<li><a href="subpages/subpage1.html"
8484
class="nav-link">
8585
Subpages 1
@@ -119,7 +119,7 @@ <h2>Additional Menu</h2>
119119

120120

121121
<div class="section" id="another-page">
122-
<h1>Another Page</h1>
122+
<h1>Another Page</h1>
123123

124124
<p>Lorem Ipsum Dolor.</p>
125125
</div>

tests/Integration/tests-full/bootstrap/bootstrap-default-menu-several/expected/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h2>Main Menu</h2>
7979
class="nav-link">
8080
Subpages
8181
</a>
82-
<ul class="level-1">
82+
<ul class="level-2">
8383
<li><a href="subpages/subpage1.html"
8484
class="nav-link">
8585
Subpages 1
@@ -118,7 +118,7 @@ <h2>Additional Menu</h2>
118118

119119

120120
<div class="section" id="document-title">
121-
<h1>Document Title</h1>
121+
<h1>Document Title</h1>
122122

123123
<p>Lorem Ipsum Dolor.</p>
124124
<div class="toc">

tests/Integration/tests-full/bootstrap/bootstrap-default-menu-several/expected/somePage.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h2>Main Menu</h2>
7979
class="nav-link">
8080
Subpages
8181
</a>
82-
<ul class="level-1">
82+
<ul class="level-2">
8383
<li><a href="subpages/subpage1.html"
8484
class="nav-link">
8585
Subpages 1
@@ -119,7 +119,7 @@ <h2>Additional Menu</h2>
119119

120120

121121
<div class="section" id="some-page">
122-
<h1>Some Page</h1>
122+
<h1>Some Page</h1>
123123

124124
<p>Lorem Ipsum <span class="custom">Dolor</span>.</p>
125125
</div>

tests/Integration/tests-full/bootstrap/bootstrap-default-menu-several/expected/subpages/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h2>Main Menu</h2>
7979
class="nav-link current active" aria-current="page" >
8080
Subpages
8181
</a>
82-
<ul class="level-1">
82+
<ul class="level-2">
8383
<li><a href="subpage1.html"
8484
class="nav-link">
8585
Subpages 1
@@ -117,7 +117,7 @@ <h2>Additional Menu</h2>
117117

118118
<!-- content start -->
119119
<div class="section" id="subpages">
120-
<h1>Subpages</h1>
120+
<h1>Subpages</h1>
121121

122122
<div class="toc">
123123
<ul class="menu-level">

tests/Integration/tests-full/bootstrap/bootstrap-default-menu-several/expected/subpages/subpage1.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h2>Main Menu</h2>
7979
class="nav-link active">
8080
Subpages
8181
</a>
82-
<ul class="level-1">
82+
<ul class="level-2">
8383
<li><a href="#"
8484
class="nav-link current active" aria-current="page">
8585
Subpages 1
@@ -118,7 +118,7 @@ <h2>Additional Menu</h2>
118118

119119
<!-- content start -->
120120
<div class="section" id="subpages-1">
121-
<h1>Subpages 1</h1>
121+
<h1>Subpages 1</h1>
122122

123123
</div>
124124

0 commit comments

Comments
 (0)