In a previous article, we looked at what the Drupal render system does, and the basic structure of a render array. To understand the capabilities of this system better, here we'll dive into the render array properties supported by nearly every render element.
HTML attributes
One of the most common modifications we want to make to the HTML that the render system outputs is to inject or change HTML attributes such as IDs, classes, or ARIA declarations. Nearly every render element has broad support for this using the standard #attributes property.
[
'#type' => 'html_tag',
'#tag' => 'h1',
'#value' => 'Standard properties',
'#attributes' => [
'id' => 'standard-properties',
'title' => 'Standard properties right here!',
'class' => ['foo', 'bar'],
],
]
The value of #attributes is expected to be an associative array, where each key is the name of an HTML attribute, and its value is a string containing the corresponding HTML attribute value. The exception is class, which instead of a string takes an array of individual class names.
The above example produces:
<h1 id="standard-properties" title="Standard properties right here!" class="foo bar">Standard properties</h1>
We can see that the class names have been placed together with a space separating them.
Why are classes specified in an array? This goes back to one of the reasons the render array system exists in the first place. We want other modules and themes to be able to reach in and tweak the contents later as needed. If classes were specified as a space-separated string, then we'd need to do a lot of text searching and handle special cases whenever we wanted to add or remove a class from something. But since this is already an array, we can do:
$render['#attributes']['class'][] = 'baz';
This sticks an extra class into the element without worrying about what's already there.
Weights
Render array elements can also have weights assigned to them, just like the weights you see on things like taxonomy terms in the Drupal UI. These will influence the output ordering.
public function page() {
return [
'#type' => 'container',
'header' => [
'#type' => 'html_tag',
'#tag' => 'h1',
'#value' => 'Standard properties',
'#attributes' => [
'id' => 'standard-properties',
'title' => 'Standard properties right here!',
'class' => ['foo', 'bar'],
],
],
'content' => [
[
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => 'This one is second',
'#weight' => 52,
],
[
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => 'This one, on the other hand, is first.',
'#weight' => -10,
],
],
];
}
This example has two paragraph tags defined, one with a weight of 52 and the other of -10. The heading tag has no weight listed, so it gets the default of 0. Weighted items are ordered from low to high: the heaviest items sink to the bottom of the page.