Problem/Motivation
Since Drupal 8 we've done some work to remove 'magic array keys'. But we still have render arrays, which every time you use them cause you to need to look-up the allowed keys. This is really bad DX. It's not clear what the allowed keys are, or where to find them. For backend developers who don't have years of experience with the nuts and bolts of Drupal's rendering system, this is more of a learning cliff than a learning curve, and it's very discouraging.
Proposed resolution
Provide builder classes for each element type to make defining render arrays discoverable from IDEs.
before
$variables['table'] = [
'#type' => 'table',
'#header' => $headers,
'#rows' => $rows,
'#attributes' => [
'id' => $table_id,
],
'#tabledrag' => [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => $weight_class,
],
],
];
after
$variables['table'] = TableElement::create()
->setHeader($headers)
->setRows($rows)
->setAttributes([
'id' => $table_id,
])
->setTableDrag([
[
'action' => 'order',
'relationship' => 'sibling',
'group' => $weight_class,
],
])->toRenderArray();
This sort of interface is a lot clearer, and borrows heavily from both Url helper and FieldDefinition stuff.
In this issue, we should only introduce a base class for these builders, plus one or two concrete implementations that we use in core, to prove they work. Then, in follow-up child issues, we can introduce more builders for the various core elements, piecemeal.
Remaining tasks
Refactor the patch in #106 to modernize it -- i.e., adding type hints -- and remove most of the builders it implements (punt to follow-ups). Keep one or two useful builders, and change core to use them where possible. Add unit or kernel test coverage. Then review and commit.
Manual testing
- To check DropbuttonBuilder: go to
/admin/content
, check that the dropbutton display correctly - To check ImageBuilder: go to
http://drupal.local/en/admin/help/contextual
, make sure the icon displays in the help text
User interface changes
None
API changes
Creates a new optional way to create render elements.