Skip to content

Commit

Permalink
[TASK] Allow filtering in ViewHelper directive (#918)
Browse files Browse the repository at this point in the history
only display a certain part of a viewhelper, like description or
arguments.
  • Loading branch information
linawolf authored Mar 6, 2025
1 parent 8939791 commit a40f514
Show file tree
Hide file tree
Showing 13 changed files with 650 additions and 92 deletions.
Original file line number Diff line number Diff line change
@@ -1,45 +1,61 @@
{% if node.docTags %}
{% for key, docTag in node.docTags %}
{% if key == '@deprecated' %}
<div class="versionchange deprecated">
<p class="versionmodified">
<span class="versionicon"><i class="fa-solid fa-ban"></i></span> Deprecated </p>
<article>
{{ docTag }}
</article>
</div>
{% elseif key == '@internal' %}
<div class="admonition warning" role="alert">
<p class="admonition-title">Internal</p>
<p>This ViewHelper is marked as internal. It is subject to be
changed without notice. Use at your own risk.</p>
</div>
{% elseif key == '@api' or key == '@todo' %}
{% else %}
<p>{{ key }}: {{ docTag }}</p>
{% endif %}
{% endfor %}
{% endif %}
{% for display in node.display %}
{% if display=='tags' and node.docTags %}
{% for key, docTag in node.docTags %}
{% if key == '@deprecated' %}
<div class="versionchange deprecated">
<p class="versionmodified">
<span class="versionicon"><i class="fa-solid fa-ban"></i></span> Deprecated </p>
<article>
{{ docTag }}
</article>
</div>
{% elseif key == '@internal' %}
<div class="admonition warning" role="alert">
<p class="admonition-title">Internal</p>
<p>This ViewHelper is marked as internal. It is subject to be
changed without notice. Use at your own risk.</p>
</div>
{% elseif key == '@api' or key == '@todo' %}
{% else %}
<p>{{ key }}: {{ docTag }}</p>
{% endif %}
{% endfor %}
{% endif %}

{{ renderNode(node.documentation) }}
{% if display=='description' %}
{{ renderNode(node.description) }}
{% endif %}
{% if display=='sections' %}
{{ renderNode(node.sections) }}
{% endif %}
{% if display=='examples' %}
{{ renderNode(node.examples) }}
{% endif %}

{% if node.gitHubLink %}
{% include "body/directive/viewhelper/viewhelper-source.html.twig" %}
{% endif %}
{% if display=='documentation' %}
{{ renderNode(node.documentation) }}
{% endif %}

{% if display=='gitHubLink' and node.gitHubLink %}
{% include "body/directive/viewhelper/viewhelper-source.html.twig" %}
{% endif %}

{% if node.arguments or node.allowsArbitraryArguments %}
<h2>Arguments</h2>
{% if (display=='arguments' or display=='arguments-only') and (node.arguments or node.allowsArbitraryArguments) %}
{% if display=='arguments' %}
<h2>Arguments</h2>

{% if node.allowsArbitraryArguments %}
<div class="admonition info" role="alert">
<p class="admonition-title">Allows arbitrary arguments</p>
<p>This ViewHelper allows you to pass arbitrary arguments not defined below directly
to the HTML tag created. This includes custom
<code class="code-inline" translate="no">data-</code> arguments.</p>
</div>
{% if node.allowsArbitraryArguments %}
<div class="admonition info" role="alert">
<p class="admonition-title">Allows arbitrary arguments</p>
<p>This ViewHelper allows you to pass arbitrary arguments not defined below directly
to the HTML tag created. This includes custom
<code class="code-inline" translate="no">data-</code> arguments.</p>
</div>
{% endif %}
<p>The following arguments are available for the {{ node.tagName }} ViewHelper: </p>
{% endif %}
{% for argument in node.arguments %}
{% include "body/directive/viewhelper/viewhelper-argument.html.twig" %}
{% endfor %}
{% endif %}
<p>The following arguments are available for the {{ node.tagName }} ViewHelper: </p>
{% for argument in node.arguments %}
{% include "body/directive/viewhelper/viewhelper-argument.html.twig" %}
{% endfor %}
{% endif %}
{% endfor %}
55 changes: 41 additions & 14 deletions packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\Nodes\ParagraphNode;
use phpDocumentor\Guides\Nodes\SectionNode;
use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer;
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
Expand Down Expand Up @@ -91,7 +92,7 @@ public function processNode(
$noindex = $directive->getOptionBool('noindex');

$data = $json['viewHelpers'][$directive->getData()];
$viewHelperNode = $this->getViewHelperNode($data, $json['sourceEdit'] ?? [], $blockContext, $noindex);
$viewHelperNode = $this->getViewHelperNode($directive, $data, $json['sourceEdit'] ?? [], $blockContext, $noindex);
$arguments = [];
foreach ($json['viewHelpers'][$directive->getData()]['argumentDefinitions'] ?? [] as $argumentDefinition) {
if (is_array($argumentDefinition)) {
Expand Down Expand Up @@ -147,11 +148,29 @@ public function getArgument(array $argumentDefinition, ViewHelperNode $viewHelpe
* @param array<string, mixed> $data
* @param array<string, array{'sourcePrefix': string, 'editPrefix': string}> $sourceEdit
*/
private function getViewHelperNode(array $data, array $sourceEdit, BlockContext $blockContext, bool $noindex): ViewHelperNode
private function getViewHelperNode(Directive $directive, array $data, array $sourceEdit, BlockContext $blockContext, bool $noindex): ViewHelperNode
{
$rstContent = $this->getString($data, 'documentation');
$rstContentBlockContext = new BlockContext($blockContext->getDocumentParserContext(), $rstContent, false);
$collectionNode = $this->startingRule->apply($rstContentBlockContext);
$description = [];
foreach ($collectionNode->getValue() as $node) {
if (!$node instanceof SectionNode) {
$description[] = $node;
}
}
$sections = [];
$examples = [];
foreach ($collectionNode->getValue() as $node) {
if ($node instanceof SectionNode) {
$title = $node->getTitle()->toString();
if (stripos($title, 'example') !== false) { // Case-insensitive check for 'example'
$examples[] = $node;
} else {
$sections[] = $node;
}
}
}
$shortClassName = $this->getString($data, 'name');
$className = $this->getString($data, 'className');
$nameSpace = $this->getString($data, 'namespace');
Expand All @@ -160,20 +179,28 @@ private function getViewHelperNode(array $data, array $sourceEdit, BlockContext
if ($gitHubLink !== '') {
$gitHubLink .= sprintf('%s.php', str_replace('\\', '/', $shortClassName));
}
$display = ['tags', 'documentation', 'gitHubLink', 'arguments'];
if ($directive->hasOption('display')) {
$display = array_map('trim', explode(',', $directive->getOptionString('display')));
}
$viewHelperId = $this->anchorNormalizer->reduceAnchor($className);
$viewHelperNode = new ViewHelperNode(
$viewHelperId,
$this->getString($data, 'tagName'),
$shortClassName,
$nameSpace,
$className,
$collectionNode?->getValue() ?? [],
$xmlNamespace,
($data['allowsArbitraryArguments'] ?? false) === true,
$data['docTags'] ?? [],
$gitHubLink,
$noindex,
[],
id: $viewHelperId,
tagName: $this->getString($data, 'tagName'),
shortClassName: $shortClassName,
namespace: $nameSpace,
className: $className,
documentation: $collectionNode?->getValue() ?? [],
description: $description,
sections: $sections,
examples: $examples,
xmlNamespace: $xmlNamespace,
allowsArbitraryArguments: ($data['allowsArbitraryArguments'] ?? false) === true,
docTags: $data['docTags'] ?? [],
gitHubLink: $gitHubLink,
noindex: $noindex,
display: $display,
arguments: [],
);
return $viewHelperNode;
}
Expand Down
40 changes: 40 additions & 0 deletions packages/typo3-docs-theme/src/Nodes/ViewHelperNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ final class ViewHelperNode extends GeneralDirectiveNode implements LinkTargetNod
public const LINK_PREFIX = 'viewhelper-';
/**
* @param Node[] $documentation
* @param Node[] $description
* @param Node[] $sections
* @param Node[] $examples
* @param array<string, string> $docTags
* @param string[] $display
* @param array<string, ViewHelperArgumentNode> $arguments
*/
public function __construct(
Expand All @@ -26,16 +30,52 @@ public function __construct(
private readonly string $namespace,
private readonly string $className,
private readonly array $documentation,
private readonly array $description,
private readonly array $sections,
private readonly array $examples,
private readonly string $xmlNamespace,
private readonly bool $allowsArbitraryArguments,
private readonly array $docTags,
private readonly string $gitHubLink = '',
private readonly bool $noindex = false,
private readonly array $display = [],
private array $arguments = [],
) {
parent::__construct('viewhelper', $tagName, new InlineCompoundNode([new PlainTextInlineNode($tagName)]), $documentation);
}

/**
* @return Node[]
*/
public function getSections(): array
{
return $this->sections;
}

/**
* @return Node[]
*/
public function getExamples(): array
{
return $this->examples;
}

/**
* @return string[]
*/
public function getDisplay(): array
{
return $this->display;
}

/**
* @return Node[]
*/
public function getDescription(): array
{
return $this->description;
}

public function getTagName(): string
{
return $this->tagName;
Expand Down
19 changes: 17 additions & 2 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#6 \\$documentation of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\>, mixed given\\.$#"
message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#"
count: 2
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php

-
message: "#^Cannot call method getValue\\(\\) on phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\|null\\.$#"
count: 2
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php

-
message: "#^Parameter \\$description of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<phpDocumentor\\\\Guides\\\\Nodes\\\\Node\\>, array\\<int\\<0, max\\>, mixed\\> given\\.$#"
count: 1
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php

-
message: "#^Parameter \\$docTags of class T3Docs\\\\Typo3DocsTheme\\\\Nodes\\\\ViewHelperNode constructor expects array\\<string, string\\>, mixed given\\.$#"
count: 1
path: packages/typo3-docs-theme/src/Directives/ViewHelperDirective.php

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

Expand Down
Loading

0 comments on commit a40f514

Please sign in to comment.