Skip to content
Snippets Groups Projects
Verified Commit a6aabb7f authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #3375843 by lussoluca, e0ipso, smustgrave, DieterHolvoet: Allow other...

Issue #3375843 by lussoluca, e0ipso, smustgrave, DieterHolvoet: Allow other Twig node visitors to modify 'display_start' and 'display_end'
parent 8e33624c
No related branches found
No related tags found
44 merge requests!8528Issue #3456871 by Tim Bozeman: Support NULL services,!8323Fix source code editing and in place front page site studio editing.,!6278Issue #3187770 by godotislate, smustgrave, catch, quietone: Views Rendered...,!54479.5.x SF update,!5022Issue #3394406: FileUploadHandler::handleExtensionValidation does not have fallback for sites still using file_validate_extensions,!5014Issue #3071143: Table Render Array Example Is Incorrect,!3878Removed unused condition head title for views,!38582585169-10.1.x,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3668Resolve #3347842 "Deprecate the trusted",!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3546refactored dialog.pcss file,!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3502Issue #3335308: Confusing behavior with FormState::setFormState and FormState::setMethod,!3452Issue #3332701: Refactor Claro's tablesort-indicator stylesheet,!3451Issue #2410579: Allows setting the current language programmatically.,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3147Issue #3328457: Replace most substr($a, $i) where $i is negative with str_ends_with(),!3146Issue #3328456: Replace substr($a, 0, $i) with str_starts_with(),!3133core/modules/system/css/components/hidden.module.css,!31312878513-10.1.x,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2614Issue #2981326: Replace non-test usages of \Drupal::logger() with IoC injection,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!877Issue #2708101: Default value for link text is not saved,!844Resolve #3036010 "Updaters",!673Issue #3214208: FinishResponseSubscriber could create duplicate headers,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.
Pipeline #29738 failed
Showing with 221 additions and 8 deletions
......@@ -71,15 +71,25 @@ public function leaveNode(Node $node, Environment $env): ?Node {
new Node([new ConstantExpression($component_id, $line)]),
$line
), $line);
foreach ($print_nodes as $index => $print_node) {
$node->getNode('display_start')->setNode((string) $index, $print_node);
}
// Append the print nodes to the display_start node.
$node->setNode(
'display_start',
new Node([
$node->getNode('display_start'),
...$print_nodes,
]),
);
if ($env->isDebug()) {
$node->getNode('display_end')
->setNode(
'0',
new PrintNode(new ConstantExpression(sprintf('<!-- %s Component end: %s -->', $emoji, $component_id), $line), $line)
);
// Append the closing comment to the display_end node.
$node->setNode(
'display_end',
new Node([
new PrintNode(new ConstantExpression(sprintf('<!-- %s Component end: %s -->', $emoji, $component_id), $line), $line),
$node->getNode('display_end'),
])
);
}
// Slots can be validated at compile time, we don't need to add nodes to
// execute functions during display with the actual data.
......
name: 'Add another node visitor'
type: module
dependencies:
- sdc:sdc
package: Testing
services:
sdc_other_node_visitor.twig.extension.profiler:
class: Drupal\sdc_other_node_visitor\Twig\Extension\TestProfilerExtension
tags:
- { name: twig.extension, priority: 100 }
<?php
namespace Drupal\sdc_other_node_visitor\Twig\Extension;
use Drupal\sdc_other_node_visitor\Twig\NodeVisitor\TestNodeVisitor;
use Twig\Extension\AbstractExtension;
/**
* Twig extension to add a test node visitor.
*/
class TestProfilerExtension extends AbstractExtension {
/**
* {@inheritdoc}
*/
public function getNodeVisitors(): array {
return [new TestNodeVisitor(static::class)];
}
/**
* Dummy function called when a Twig template is entered.
*/
public function enter() {
// NOOP.
}
/**
* Dummy function called when a Twig template is left.
*/
public function leave() {
// NOOP.
}
}
<?php
namespace Drupal\sdc_other_node_visitor\Twig\NodeVisitor;
use Drupal\sdc_other_node_visitor\Twig\Profiler\EnterProfileNode;
use Drupal\sdc_other_node_visitor\Twig\Profiler\LeaveProfileNode;
use Twig\Environment;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\NodeVisitor\NodeVisitorInterface;
/**
* A node visitor that adds nodes to the Twig template.
*
* Most of this code is copied from
* Twig\Profiler\NodeVisitor\ProfilerNodeVisitor.
*/
final class TestNodeVisitor implements NodeVisitorInterface {
private string $extensionName;
private string $varName;
/**
* TestNodeVisitor constructor.
*
* @param string $extensionName
* The name of the extension.
*/
public function __construct(string $extensionName) {
$this->extensionName = $extensionName;
$this->varName = sprintf('__internal_%s', hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $extensionName));
}
/**
* {@inheritdoc}
*/
public function enterNode(Node $node, Environment $env): Node {
return $node;
}
/**
* {@inheritdoc}
*/
public function leaveNode(Node $node, Environment $env): ?Node {
if ($node instanceof ModuleNode) {
$node->setNode('display_start', new Node([
new EnterProfileNode($this->extensionName, $this->varName),
$node->getNode('display_start'),
]));
$node->setNode('display_end', new Node([
new LeaveProfileNode($this->varName),
$node->getNode('display_end'),
]));
}
return $node;
}
/**
* {@inheritdoc}
*/
public function getPriority(): int {
return 0;
}
}
<?php
namespace Drupal\sdc_other_node_visitor\Twig\Profiler;
use Twig\Compiler;
use Twig\Node\Node;
/**
* Represents a profile enter node.
*/
class EnterProfileNode extends Node {
public function __construct(string $extensionName, string $varName) {
parent::__construct([], [
'extension_name' => $extensionName,
'var_name' => $varName,
]);
}
public function compile(Compiler $compiler): void {
$compiler
->write(sprintf('$%s = $this->extensions[', $this->getAttribute('var_name')))
/* cspell:disable-next-line */
->repr($this->getAttribute('extension_name'))
->raw("];\n")
->write(sprintf('$%s->enter();', $this->getAttribute('var_name')))
->raw("\n\n");
}
}
<?php
namespace Drupal\sdc_other_node_visitor\Twig\Profiler;
use Twig\Compiler;
use Twig\Node\Node;
/**
* Represents a profile leave node.
*/
class LeaveProfileNode extends Node {
public function __construct(string $varName) {
parent::__construct([], ['var_name' => $varName]);
}
public function compile(Compiler $compiler): void {
$compiler
->write("\n")
->write(sprintf("\$%s->leave();\n\n", $this->getAttribute('var_name')));
}
}
<?php
namespace Drupal\Tests\sdc\Kernel;
/**
* Tests the node visitor.
*
* @coversDefaultClass \Drupal\sdc\Twig\ComponentNodeVisitor
* @group sdc
*
* @internal
*/
final class ComponentNodeVisitorTest extends ComponentKernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['sdc', 'sdc_other_node_visitor'];
/**
* {@inheritdoc}
*/
protected static $themes = ['sdc_theme_test'];
/**
* Test that other visitors can modify Twig nodes.
*/
public function testOtherVisitorsCanModifyTwigNodes(): void {
$build = [
'#type' => 'inline_template',
'#template' => "{% embed('sdc_theme_test_base:my-card-no-schema') %}{% block card_body %}Foo bar{% endblock %}{% endembed %}",
];
$this->renderComponentRenderArray($build);
// If this is reached, the test passed.
$this->assertTrue(TRUE);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment