Wie überschreibe ich ein RenderElement?

7

Es gibt ein Drupal 8-RenderElement namens HtmlTag, das steuert, wie HtmlTags gerendert werden. Ich möchte dies überschreiben, damit ich das Standardverhalten ändern kann.

Ich könnte eine Klasse schreiben, die HtmlTag erweitert und überschreibt, was ich brauche, aber wie würden dann Drupal Core und das Themensystem wissen, wie ich meine neue Klasse verwenden kann?

Alternativ sollte ich vielleicht hook_theme_registry_alter()Drupal 8 anweisen, meine neue Klasse zu verwenden?

Ich bin mir nicht sicher, wie ich das am besten erreichen kann, und es scheint keine Beispiele dafür zu geben.

Chris Cohen
quelle
Warum versuchen Sie, das HTML_tag-Element zu überschreiben?
Eyal
Könnte sein, die Standard-Leere-Elemente zu überschreiben @Eyal
Clive
Konvertieren aller Skript-Tags in einfache Pfade zur Verwendung in einem JSON-Array. Dies ist für die Verwendung in einem Javascript-basierten Skriptlader vorgesehen.
Lomax

Antworten:

6

Die Verwendung hook_element_info_alter()wäre eine Option, nicht sicher, ob es die beste ist.

Die vorhandene Klasse enthält 2 Pre-Render-Rückrufe, die Sie in Ihrer eigenen Klasse überschreiben können:

function MYMODULE_element_info_alter(array &$types) {
  $types['html_tag']['#pre_render'] = [
    [\Drupal\mymodule\HtmlTag::class, 'preRenderConditionalComments'],
    [\Drupal\mymodule\HtmlTag::class, 'preRenderHtmlTag'],
  ];
}

...

namespace Drupal\mymodule;

use Drupal\Core\Render\Element\HtmlTag as CoreHtmlTag;

class HtmlTag extends CoreHtmlTag {

  public function preRenderHtmlTag($element) {
    // ...
  }

  public function preRenderConditionalComments($element) {
    // ...
  }

}
Clive
quelle
Das ist interessant. Wird dies zu Problemen führen, wenn mehrere Contrib-Module dies tun?
Kevin
Es wird ein Rennen @Kevin geben, yep - aber nicht mehr als Hooks in früheren Versionen. Es ist auch vorhersehbar, und wir haben immer noch gute Möglichkeiten hook_module_implements_alter, den Hook-Implementierungen einen Befehl aufzuzwingen, wenn dies passiert
Clive
Ich sollte hinzufügen, dass dies aus anderen Gründen nicht richtig ist. @Kevin - es gibt eine eindeutige Möglichkeit, DRY zu verletzen, wenn das OP beispielsweise nur die statische Variable überschreiben möchte $voidElements- weil die übergeordnete Klasse das Ganze verwendet, selfanstatt darauf staticzu verweisen von preRenderHtmlTagmüsste kopiert werden
Clive
@Clive, ist es möglich, den Inhalt von zu überschreiben $voidElements, weil er nur geschützt und nicht privat ist und dann aufruft $element = parent::preRenderHtmlTag($element);?
4k4
Leider nicht @ 4k4 - wenn die übergeordnete Klasse mit dem staticSchlüsselwort darauf self::$voidElementsverweisen würde, würde es funktionieren, aber wenn es verwendet wird , wird immer auf die Variable im HtmlTag des Kerns verwiesen, nicht auf die erweiterte Klasse
Clive
0

Wenn hook_element_info_alter () für Sie nicht weit genug geht, gibt es ein Kernproblem beim Hinzufügen eines hook_element_plugin_alter (), um die Plugin-Klasse für ein Element (von dem RenderElements eine Teilmenge sind) direkt zu ändern: https://www.drupal.org / project / drupal / issue / 2987208

Der Kern-Patch ist eine einzeilige Ergänzung von $this->alterInfo('element_plugin');in ElementInfoManager, die diesen neuen Alter-Hook spezifiziert.

Dann in Ihrem benutzerdefinierten Modul:

function hook_element_plugin_alter(array &$definitions) {
 // Use a custom class for the HtmlTag element.
 $definitions['html_tag']['class'] = '\Drupal\mymodule\RenderElement\MyHtmlTagElement';
}
Akalata
quelle