Support Wire Drupal
Fund development, features & content
Rendering Components
How to render components in templates
The Basics
To render a Wire component on a page use the wire()
Twig function:
<div>
...
{{ wire('related_articles') }}
...
</div>
Or, if you're in the context of a renderable array (e.g. Form, Controller), you can use the wire
render element:
$build['related_articles'] = [
'#type' => 'wire',
'#id' => 'related_articles',
];
Note: Ensure that the module in which the component has been generated is enabled
Parameters
Passing Parameters
You can pass data into a component by passing additional parameters into the wire()
function.
For example, let's say we have a "related_articles" component we want to include via Node's node.html.twig
template. Here's how you would pass in the ID of the Node entity object:
{{ wire('related_articles', {'nodeId': node.id}) }}
When using wire
render element you would do:
$build['related_articles'] = [
'#type' => 'wire',
'#id' => 'related_articles',
'#context' => ['nodeId' => 999],
];
Receiving Parameters
Wire will automatically assign parameters to matching public properties.
Make sure to read the Properties section to align your expectations.
For example, in the case of wire('related_nodes', {'nodeId': node.id})
, if the respective component has a public property named $nodeId
, it will be automatically assigned and persist between Wire updates:
use Drupal\wire\Plugin\Attribute\WireComponent;
use Drupal\wire\WireComponentBase;
#[WireComponent(id: 'related_articles')]
class RelatedArticles extends WireComponentBase {
public ?int $nodeId;
...
}
If for whatever reason, this automatic behavior doesn't work, you can intercept parameters using the mount()
method:
use Drupal\node\Entity\Node;
use Drupal\wire\Plugin\Attribute\WireComponent;
use Drupal\wire\WireComponentBase;
#[WireComponent(id: 'related_articles')]
class RelatedArticles extends WireComponentBase {
public ?int $nodeId;
public string $label;
public function mount($nodeId) {
$this->label = 'Related articles for: ' . Node::load($nodeId)->label();
}
}
The mount()
method is only called when the component is first mounted and will NOT be called again when the component is refreshed or re-rendered. Think of it as a class __construct()
method.
At this point you might wonder if you can pass in the whole Node entity object.
The answer is yes, but with a caveat. When you pass any unsupported property, it can be intercepted in the mount()
method but it won't persist during Wire updates.
{{ wire('related_articles', {'node': node}) }}
In the PHP class:
use Drupal\wire\Plugin\Attribute\WireComponent;
use Drupal\wire\WireComponentBase;
use Drupal\wire\View;
#[WireComponent(id: 'related_articles')]
class RelatedArticles extends WireComponentBase {
protected ?Node $node;
public string $label;
public function mount(?Node $node) {
$this->node = $node;
}
public function render(): ?View {
// $this->node is available here but only on the initial load.
}
}
The Render Method
A Wire component's render
method gets called on the initial page load and every subsequent component update.
Returning Template
The render()
method is expected to return an instance of Drupal\wire\View
which has a few different ways to get its HTML.
Here is an example using View::fromTpl()
:
Make sure your Twig template only has ONE root element.
public function render(): ?View {
return View::fromTpl('articles', [
'articles' => Node::loadMultiple(),
]);
}
/wiredemo/templates/wire/articles.html.twig
<div>
{% for article in articles %}
<h2>{{ article.label }}</h2>
{% endfor %}
</div>
The ::fromTpl()
method expects the filename without its extension part, which must be located in a templates/wire/
directory of a module or theme. The priority of loading the template is: active theme → parent/base theme(s) → module.
Returning String
If you don't want to use a Twig file at all, you can return a template string directly from render()
method:
public function render(): ?View {
$twig = <<<'TWIG'
<div>
{% for article in articles %}
<h2>{{ article.label }}</h2>
{% endfor %}
</div>
TWIG;
return View::fromString($twig);
}
Returning anything Renderable
You might want to render using Theme Implementations (hook_theme
), Render elements, etc.
This can be achieved with the render_var function.
Example:
public function render(): ?View {
$rendarableEl = [
'#type' => 'theme',
'#theme' => 'my_theme_accepting_dynamic_value',
'#my_dynamic_value' => $this->dynamicValue,
];
$twig = <<<'TWIG'
<div>
{{ render_var(rendarableEl) }}
<hr />
<p>{{ my_dynamic_value }}</p>
</div>
TWIG;
return View::fromString($twig, [
'my_dynamic_value' => $this->count,
'rendarableEl' => $rendarableEl,
]);
}