Skip to content

Commit de2dd77

Browse files
CybotTMlinawolf
andauthored
[BUGFIX] Exclude orphan pages from next/prev navigation (#1138)
## Summary This PR fixes the issue where orphan pages (marked with `:orphan:` directive) are incorrectly included in the next/previous navigation chain, causing broken navigation links. Resolves: #1137 ## Changes ### Core Fix (`TwigExtension.php`) - Added `isOrphanDocument()` helper method to detect if a document entry corresponds to an orphan page - Modified `getPagerLinks()` to: - Return only the "top" link for orphan pages (no prev/next) - Exclude orphan targets from prev/next links - Modified `getPrevNextLinks()` to: - Return empty array for orphan pages - Exclude orphan targets from the navigation links ### Test Updates Updated expected output files to reflect the corrected behavior: - `next-prev-by-toctree/expected/i.html` - orphan page no longer has prev/next links - `next-prev-by-toctree/expected/three/pi.html` - orphan page no longer has prev/next links - `next-prev-by-toctree/expected/four.html` - no longer links to orphan `i.html` - `changelog/expected/Index.html` - no longer links to orphan `Changelog-12.html` - `changelog/expected/Changelog/12.0/Index.html` - no longer has prev link to orphan - `main-menu-json/expected/index.html` - no longer links to orphan `mainMenu.json.html` ## Test Plan - [x] `vendor/bin/phpunit --filter next-prev-by-toctree` passes - [x] `vendor/bin/phpunit tests/Integration/IntegrationTest.php` passes (108 tests, all assertions pass) - [x] PHP syntax check passes ## Before/After **Before:** Clicking "Next" on docs.typo3.org/Home/Overview.html leads to WikiLanding.html → mainMenu.json.html (404) **After:** Orphan pages are excluded from navigation chain, preventing broken links Co-authored-by: Lina Wolf <48202465+linawolf@users.noreply.github.com>
1 parent 5a47b33 commit de2dd77

File tree

7 files changed

+85
-75
lines changed

7 files changed

+85
-75
lines changed

packages/typo3-docs-theme/src/Twig/TwigExtension.php

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -648,12 +648,40 @@ public function getTYPO3Version(): string
648648
public function getPagerLinks(array $context): array
649649
{
650650
$renderContext = $this->getRenderContext($context);
651+
652+
// Check if current page is orphan - orphans should not have navigation meta links
651653
try {
652-
$documentEntries = [
653-
'prev' => $this->getPrevDocumentEntry($renderContext),
654-
'next' => $this->getNextDocumentEntry($renderContext),
655-
'top' => $this->getTopDocumentEntry($renderContext),
656-
];
654+
$currentEntry = $renderContext->getCurrentDocumentEntry();
655+
if ($this->isOrphanDocument($renderContext, $currentEntry)) {
656+
// Only return top link for orphan pages
657+
$documentEntries = [
658+
'top' => $this->getTopDocumentEntry($renderContext),
659+
];
660+
return $this->getPageLinks($documentEntries, $renderContext);
661+
}
662+
} catch (\Exception) {
663+
// Continue with normal flow
664+
}
665+
666+
try {
667+
$prevEntry = $this->getPrevDocumentEntry($renderContext);
668+
$nextEntry = $this->getNextDocumentEntry($renderContext);
669+
670+
// Maintain original order: prev, next, top
671+
$documentEntries = [];
672+
673+
// Only include prev link if target is not an orphan
674+
if ($prevEntry !== null && !$this->isOrphanDocument($renderContext, $prevEntry)) {
675+
$documentEntries['prev'] = $prevEntry;
676+
}
677+
678+
// Only include next link if target is not an orphan
679+
if ($nextEntry !== null && !$this->isOrphanDocument($renderContext, $nextEntry)) {
680+
$documentEntries['next'] = $nextEntry;
681+
}
682+
683+
$documentEntries['top'] = $this->getTopDocumentEntry($renderContext);
684+
657685
return $this->getPageLinks($documentEntries, $renderContext);
658686
} catch (\Exception) {
659687
$documentEntries = [
@@ -727,11 +755,33 @@ public function getTopPageLink(array $context): ?PageLinkNode
727755
public function getPrevNextLinks(array $context): array
728756
{
729757
$renderContext = $this->getRenderContext($context);
758+
759+
// Orphan pages should not display prev/next navigation links
730760
try {
731-
$documentEntries = [
732-
'prev' => $this->getPrevDocumentEntry($renderContext),
733-
'next' => $this->getNextDocumentEntry($renderContext),
734-
];
761+
$currentEntry = $renderContext->getCurrentDocumentEntry();
762+
if ($this->isOrphanDocument($renderContext, $currentEntry)) {
763+
return [];
764+
}
765+
} catch (\Exception) {
766+
// If we can't determine current document, continue with normal flow
767+
}
768+
769+
try {
770+
$prevEntry = $this->getPrevDocumentEntry($renderContext);
771+
$nextEntry = $this->getNextDocumentEntry($renderContext);
772+
773+
$documentEntries = [];
774+
775+
// Only include prev link if target is not an orphan
776+
if ($prevEntry !== null && !$this->isOrphanDocument($renderContext, $prevEntry)) {
777+
$documentEntries['prev'] = $prevEntry;
778+
}
779+
780+
// Only include next link if target is not an orphan
781+
if ($nextEntry !== null && !$this->isOrphanDocument($renderContext, $nextEntry)) {
782+
$documentEntries['next'] = $nextEntry;
783+
}
784+
735785
return $this->getPageLinks($documentEntries, $renderContext);
736786
} catch (\Exception) {
737787
return [];
@@ -753,6 +803,31 @@ private function getTopDocumentEntry(RenderContext $renderContext): DocumentEntr
753803
return $renderContext->getProjectNode()->getRootDocumentEntry();
754804
}
755805

806+
/**
807+
* Check if a document entry corresponds to an orphan page.
808+
* Orphan pages are marked with the :orphan: directive and should not
809+
* appear in navigation links (prev/next).
810+
*/
811+
private function isOrphanDocument(RenderContext $renderContext, ?DocumentEntryNode $documentEntry): bool
812+
{
813+
if ($documentEntry === null) {
814+
return false;
815+
}
816+
817+
try {
818+
$document = $renderContext->getDocumentNodeForEntry($documentEntry);
819+
foreach ($document->getHeaderNodes() as $headerNode) {
820+
if ($headerNode instanceof OrphanNode) {
821+
return true;
822+
}
823+
}
824+
} catch (\Exception) {
825+
return false;
826+
}
827+
828+
return false;
829+
}
830+
756831
/** @param array{env: RenderContext} $context */
757832
private function getRenderContext(array $context): RenderContext
758833
{

tests/Integration/tests-full/changelog/expected/Changelog/12.0/Index.html

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2323
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
24-
<link href="../../Changelog-12.html" rel="prev" title="ChangeLog v12"/>
2524
<link href="Breaking-87616-RemovedHookForAlteringPageLinks.html" rel="next" title="Breaking: #87616 - Removed hook for altering page links"/>
2625
<link href="../../Index.html" rel="top" title="TYPO3 Core"/>
2726
</head>
@@ -278,15 +277,9 @@ <h2>Important<a class="headerlink" href="#important" data-bs-toggle="modal" data
278277
<!-- content end -->
279278
</div>
280279
</article>
281-
280+
282281
<nav aria-label="Page navigation">
283282
<ul class="pagination justify-content-center"><li class="page-item">
284-
<a class="page-link" href="../../Changelog-12.html"
285-
title="Accesskey Alt(+Shift)+p">
286-
<i class="fa-solid fa-chevron-left"></i> Previous
287-
</a>
288-
</li>
289-
<li class="page-item">
290283
<a class="page-link" href="Breaking-87616-RemovedHookForAlteringPageLinks.html"
291284
title="Accesskey Alt(+Shift)+n">
292285
Next <i class="fa-solid fa-chevron-right"></i>

tests/Integration/tests-full/changelog/expected/Index.html

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
2121
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
23-
<link href="Changelog-12.html" rel="next" title="ChangeLog v12"/>
2423
<link href="#" rel="top" title="TYPO3 Core"/>
2524
</head>
2625
<body>
@@ -242,16 +241,6 @@ <h1>TYPO3 Core<a class="headerlink" href="#typo3-core" data-bs-toggle="modal" da
242241
<!-- content end -->
243242
</div>
244243
</article>
245-
246-
<nav aria-label="Page navigation">
247-
<ul class="pagination justify-content-center"><li class="page-item">
248-
<a class="page-link" href="Changelog-12.html"
249-
title="Accesskey Alt(+Shift)+n">
250-
Next <i class="fa-solid fa-chevron-right"></i>
251-
</a>
252-
</li>
253-
</ul>
254-
</nav>
255244
</div>
256245
</div>
257246
</div>

tests/Integration/tests-full/main-menu-json/expected/index.html

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
2121
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
23-
<link href="mainMenu.json.html" rel="next" title="&lt;Unknown&gt;"/>
2423
<link href="#" rel="top" title="Some page"/>
2524
</head>
2625
<body>
@@ -178,16 +177,6 @@ <h1>Some page<a class="headerlink" href="#some-page" data-bs-toggle="modal" data
178177
<!-- content end -->
179178
</div>
180179
</article>
181-
182-
<nav aria-label="Page navigation">
183-
<ul class="pagination justify-content-center"><li class="page-item">
184-
<a class="page-link" href="mainMenu.json.html"
185-
title="Accesskey Alt(+Shift)+n">
186-
Next <i class="fa-solid fa-chevron-right"></i>
187-
</a>
188-
</li>
189-
</ul>
190-
</nav>
191180
</div>
192181
</div>
193182
</div>

tests/Integration/tests-full/next-prev-by-toctree/expected/four.html

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
2323
<link href="three/threepointfive.html" rel="prev" title="3.5"/>
24-
<link href="i.html" rel="next" title="i (sqrt(-1))"/>
2524
<link href="index.html" rel="top" title="Root index"/>
2625
</head>
2726
<body>
@@ -165,12 +164,6 @@ <h1>Four<a class="headerlink" href="#four" data-bs-toggle="modal" data-bs-target
165164
<i class="fa-solid fa-chevron-left"></i> Previous
166165
</a>
167166
</li>
168-
<li class="page-item">
169-
<a class="page-link" href="i.html"
170-
title="Accesskey Alt(+Shift)+n">
171-
Next <i class="fa-solid fa-chevron-right"></i>
172-
</a>
173-
</li>
174167
</ul>
175168
</nav>
176169
</div>

tests/Integration/tests-full/next-prev-by-toctree/expected/i.html

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2323
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
24-
<link href="four.html" rel="prev" title="Four"/>
25-
<link href="three/pi.html" rel="next" title="Pi"/>
2624
<link href="index.html" rel="top" title="Root index"/>
2725
</head>
2826
<body>
@@ -158,22 +156,6 @@ <h1>i (sqrt(-1))<a class="headerlink" href="#i-sqrt-1" data-bs-toggle="modal" da
158156
<!-- content end -->
159157
</div>
160158
</article>
161-
162-
<nav aria-label="Page navigation">
163-
<ul class="pagination justify-content-center"><li class="page-item">
164-
<a class="page-link" href="four.html"
165-
title="Accesskey Alt(+Shift)+p">
166-
<i class="fa-solid fa-chevron-left"></i> Previous
167-
</a>
168-
</li>
169-
<li class="page-item">
170-
<a class="page-link" href="three/pi.html"
171-
title="Accesskey Alt(+Shift)+n">
172-
Next <i class="fa-solid fa-chevron-right"></i>
173-
</a>
174-
</li>
175-
</ul>
176-
</nav>
177159
</div>
178160
</div>
179161
</div>

tests/Integration/tests-full/next-prev-by-toctree/expected/three/pi.html

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
2222
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
2323
<script src="https://cdn.typo3.com/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
24-
<link href="../i.html" rel="prev" title="i (sqrt(-1))"/>
2524
<link href="../index.html" rel="top" title="Root index"/>
2625
</head>
2726
<body>
@@ -157,16 +156,6 @@ <h1>Pi<a class="headerlink" href="#pi" data-bs-toggle="modal" data-bs-target="#l
157156
<!-- content end -->
158157
</div>
159158
</article>
160-
161-
<nav aria-label="Page navigation">
162-
<ul class="pagination justify-content-center"><li class="page-item">
163-
<a class="page-link" href="../i.html"
164-
title="Accesskey Alt(+Shift)+p">
165-
<i class="fa-solid fa-chevron-left"></i> Previous
166-
</a>
167-
</li>
168-
</ul>
169-
</nav>
170159
</div>
171160
</div>
172161
</div>

0 commit comments

Comments
 (0)