Skip to content

Commit a40f514

Browse files
authored
[TASK] Allow filtering in ViewHelper directive (#918)
only display a certain part of a viewhelper, like description or arguments.
1 parent 8939791 commit a40f514

File tree

13 files changed

+650
-92
lines changed

13 files changed

+650
-92
lines changed
Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,61 @@
1-
{% if node.docTags %}
2-
{% for key, docTag in node.docTags %}
3-
{% if key == '@deprecated' %}
4-
<div class="versionchange deprecated">
5-
<p class="versionmodified">
6-
<span class="versionicon"><i class="fa-solid fa-ban"></i></span> Deprecated </p>
7-
<article>
8-
{{ docTag }}
9-
</article>
10-
</div>
11-
{% elseif key == '@internal' %}
12-
<div class="admonition warning" role="alert">
13-
<p class="admonition-title">Internal</p>
14-
<p>This ViewHelper is marked as internal. It is subject to be
15-
changed without notice. Use at your own risk.</p>
16-
</div>
17-
{% elseif key == '@api' or key == '@todo' %}
18-
{% else %}
19-
<p>{{ key }}: {{ docTag }}</p>
20-
{% endif %}
21-
{% endfor %}
22-
{% endif %}
1+
{% for display in node.display %}
2+
{% if display=='tags' and node.docTags %}
3+
{% for key, docTag in node.docTags %}
4+
{% if key == '@deprecated' %}
5+
<div class="versionchange deprecated">
6+
<p class="versionmodified">
7+
<span class="versionicon"><i class="fa-solid fa-ban"></i></span> Deprecated </p>
8+
<article>
9+
{{ docTag }}
10+
</article>
11+
</div>
12+
{% elseif key == '@internal' %}
13+
<div class="admonition warning" role="alert">
14+
<p class="admonition-title">Internal</p>
15+
<p>This ViewHelper is marked as internal. It is subject to be
16+
changed without notice. Use at your own risk.</p>
17+
</div>
18+
{% elseif key == '@api' or key == '@todo' %}
19+
{% else %}
20+
<p>{{ key }}: {{ docTag }}</p>
21+
{% endif %}
22+
{% endfor %}
23+
{% endif %}
2324

24-
{{ renderNode(node.documentation) }}
25+
{% if display=='description' %}
26+
{{ renderNode(node.description) }}
27+
{% endif %}
28+
{% if display=='sections' %}
29+
{{ renderNode(node.sections) }}
30+
{% endif %}
31+
{% if display=='examples' %}
32+
{{ renderNode(node.examples) }}
33+
{% endif %}
2534

26-
{% if node.gitHubLink %}
27-
{% include "body/directive/viewhelper/viewhelper-source.html.twig" %}
28-
{% endif %}
35+
{% if display=='documentation' %}
36+
{{ renderNode(node.documentation) }}
37+
{% endif %}
38+
39+
{% if display=='gitHubLink' and node.gitHubLink %}
40+
{% include "body/directive/viewhelper/viewhelper-source.html.twig" %}
41+
{% endif %}
2942

30-
{% if node.arguments or node.allowsArbitraryArguments %}
31-
<h2>Arguments</h2>
43+
{% if (display=='arguments' or display=='arguments-only') and (node.arguments or node.allowsArbitraryArguments) %}
44+
{% if display=='arguments' %}
45+
<h2>Arguments</h2>
3246

33-
{% if node.allowsArbitraryArguments %}
34-
<div class="admonition info" role="alert">
35-
<p class="admonition-title">Allows arbitrary arguments</p>
36-
<p>This ViewHelper allows you to pass arbitrary arguments not defined below directly
37-
to the HTML tag created. This includes custom
38-
<code class="code-inline" translate="no">data-</code> arguments.</p>
39-
</div>
47+
{% if node.allowsArbitraryArguments %}
48+
<div class="admonition info" role="alert">
49+
<p class="admonition-title">Allows arbitrary arguments</p>
50+
<p>This ViewHelper allows you to pass arbitrary arguments not defined below directly
51+
to the HTML tag created. This includes custom
52+
<code class="code-inline" translate="no">data-</code> arguments.</p>
53+
</div>
54+
{% endif %}
55+
<p>The following arguments are available for the {{ node.tagName }} ViewHelper: </p>
56+
{% endif %}
57+
{% for argument in node.arguments %}
58+
{% include "body/directive/viewhelper/viewhelper-argument.html.twig" %}
59+
{% endfor %}
4060
{% endif %}
41-
<p>The following arguments are available for the {{ node.tagName }} ViewHelper: </p>
42-
{% for argument in node.arguments %}
43-
{% include "body/directive/viewhelper/viewhelper-argument.html.twig" %}
44-
{% endfor %}
45-
{% endif %}
61+
{% endfor %}

packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
1818
use phpDocumentor\Guides\Nodes\Node;
1919
use phpDocumentor\Guides\Nodes\ParagraphNode;
20+
use phpDocumentor\Guides\Nodes\SectionNode;
2021
use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer;
2122
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective;
2223
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
@@ -91,7 +92,7 @@ public function processNode(
9192
$noindex = $directive->getOptionBool('noindex');
9293

9394
$data = $json['viewHelpers'][$directive->getData()];
94-
$viewHelperNode = $this->getViewHelperNode($data, $json['sourceEdit'] ?? [], $blockContext, $noindex);
95+
$viewHelperNode = $this->getViewHelperNode($directive, $data, $json['sourceEdit'] ?? [], $blockContext, $noindex);
9596
$arguments = [];
9697
foreach ($json['viewHelpers'][$directive->getData()]['argumentDefinitions'] ?? [] as $argumentDefinition) {
9798
if (is_array($argumentDefinition)) {
@@ -147,11 +148,29 @@ public function getArgument(array $argumentDefinition, ViewHelperNode $viewHelpe
147148
* @param array<string, mixed> $data
148149
* @param array<string, array{'sourcePrefix': string, 'editPrefix': string}> $sourceEdit
149150
*/
150-
private function getViewHelperNode(array $data, array $sourceEdit, BlockContext $blockContext, bool $noindex): ViewHelperNode
151+
private function getViewHelperNode(Directive $directive, array $data, array $sourceEdit, BlockContext $blockContext, bool $noindex): ViewHelperNode
151152
{
152153
$rstContent = $this->getString($data, 'documentation');
153154
$rstContentBlockContext = new BlockContext($blockContext->getDocumentParserContext(), $rstContent, false);
154155
$collectionNode = $this->startingRule->apply($rstContentBlockContext);
156+
$description = [];
157+
foreach ($collectionNode->getValue() as $node) {
158+
if (!$node instanceof SectionNode) {
159+
$description[] = $node;
160+
}
161+
}
162+
$sections = [];
163+
$examples = [];
164+
foreach ($collectionNode->getValue() as $node) {
165+
if ($node instanceof SectionNode) {
166+
$title = $node->getTitle()->toString();
167+
if (stripos($title, 'example') !== false) { // Case-insensitive check for 'example'
168+
$examples[] = $node;
169+
} else {
170+
$sections[] = $node;
171+
}
172+
}
173+
}
155174
$shortClassName = $this->getString($data, 'name');
156175
$className = $this->getString($data, 'className');
157176
$nameSpace = $this->getString($data, 'namespace');
@@ -160,20 +179,28 @@ private function getViewHelperNode(array $data, array $sourceEdit, BlockContext
160179
if ($gitHubLink !== '') {
161180
$gitHubLink .= sprintf('%s.php', str_replace('\\', '/', $shortClassName));
162181
}
182+
$display = ['tags', 'documentation', 'gitHubLink', 'arguments'];
183+
if ($directive->hasOption('display')) {
184+
$display = array_map('trim', explode(',', $directive->getOptionString('display')));
185+
}
163186
$viewHelperId = $this->anchorNormalizer->reduceAnchor($className);
164187
$viewHelperNode = new ViewHelperNode(
165-
$viewHelperId,
166-
$this->getString($data, 'tagName'),
167-
$shortClassName,
168-
$nameSpace,
169-
$className,
170-
$collectionNode?->getValue() ?? [],
171-
$xmlNamespace,
172-
($data['allowsArbitraryArguments'] ?? false) === true,
173-
$data['docTags'] ?? [],
174-
$gitHubLink,
175-
$noindex,
176-
[],
188+
id: $viewHelperId,
189+
tagName: $this->getString($data, 'tagName'),
190+
shortClassName: $shortClassName,
191+
namespace: $nameSpace,
192+
className: $className,
193+
documentation: $collectionNode?->getValue() ?? [],
194+
description: $description,
195+
sections: $sections,
196+
examples: $examples,
197+
xmlNamespace: $xmlNamespace,
198+
allowsArbitraryArguments: ($data['allowsArbitraryArguments'] ?? false) === true,
199+
docTags: $data['docTags'] ?? [],
200+
gitHubLink: $gitHubLink,
201+
noindex: $noindex,
202+
display: $display,
203+
arguments: [],
177204
);
178205
return $viewHelperNode;
179206
}

packages/typo3-docs-theme/src/Nodes/ViewHelperNode.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ final class ViewHelperNode extends GeneralDirectiveNode implements LinkTargetNod
1616
public const LINK_PREFIX = 'viewhelper-';
1717
/**
1818
* @param Node[] $documentation
19+
* @param Node[] $description
20+
* @param Node[] $sections
21+
* @param Node[] $examples
1922
* @param array<string, string> $docTags
23+
* @param string[] $display
2024
* @param array<string, ViewHelperArgumentNode> $arguments
2125
*/
2226
public function __construct(
@@ -26,16 +30,52 @@ public function __construct(
2630
private readonly string $namespace,
2731
private readonly string $className,
2832
private readonly array $documentation,
33+
private readonly array $description,
34+
private readonly array $sections,
35+
private readonly array $examples,
2936
private readonly string $xmlNamespace,
3037
private readonly bool $allowsArbitraryArguments,
3138
private readonly array $docTags,
3239
private readonly string $gitHubLink = '',
3340
private readonly bool $noindex = false,
41+
private readonly array $display = [],
3442
private array $arguments = [],
3543
) {
3644
parent::__construct('viewhelper', $tagName, new InlineCompoundNode([new PlainTextInlineNode($tagName)]), $documentation);
3745
}
3846

47+
/**
48+
* @return Node[]
49+
*/
50+
public function getSections(): array
51+
{
52+
return $this->sections;
53+
}
54+
55+
/**
56+
* @return Node[]
57+
*/
58+
public function getExamples(): array
59+
{
60+
return $this->examples;
61+
}
62+
63+
/**
64+
* @return string[]
65+
*/
66+
public function getDisplay(): array
67+
{
68+
return $this->display;
69+
}
70+
71+
/**
72+
* @return Node[]
73+
*/
74+
public function getDescription(): array
75+
{
76+
return $this->description;
77+
}
78+
3979
public function getTagName(): string
4080
{
4181
return $this->tagName;

phpstan-baseline.neon

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
parameters:
22
ignoreErrors:
33
-
4-
message: "#^Parameter \\#6 \\$documentation of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\>, mixed given\\.$#"
4+
message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#"
5+
count: 2
6+
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
7+
8+
-
9+
message: "#^Cannot call method getValue\\(\\) on phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\|null\\.$#"
10+
count: 2
11+
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
12+
13+
-
14+
message: "#^Parameter \\$description of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\>, array\\<int\\<0, max\\>, mixed\\> given\\.$#"
15+
count: 1
16+
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
17+
18+
-
19+
message: "#^Parameter \\$docTags of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<string, string\\>, mixed given\\.$#"
520
count: 1
621
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
722

823
-
9-
message: "#^Parameter \\#9 \\$docTags of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<string, string\\>, mixed given\\.$#"
24+
message: "#^Parameter \\$documentation of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\>, mixed given\\.$#"
1025
count: 1
1126
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
1227

0 commit comments

Comments
 (0)