Fix Nodes’ Language Field Output
Have you ever tried to display the node’s language field with your own custom formatter? Well, I tried it for the first time yesterday. I spent half an hour searching for why it didn’t do what I wanted (and expected).
Story in short
First, let’s clarify why you cannot only use a custom formatter to change the output of the Language (langcode
) field of nodes:
Because NodeViewBuilder
will override the field’s formatted markup, no matter what you do.
It will be f…ed up right here:
1
2
3
4
5
6
7
8
9
10
// Add Language field text element to node render array.
if ($display->getComponent('langcode')) {
$build[$id]['langcode'] = [
'#type' => 'item',
'#title' => t('Language'),
'#markup' => $entity->language()->getName(),
'#prefix' => '<div id="field-language-display">',
'#suffix' => '</div>',
];
}
Do you say “add”? But it was there already!!! 🤬
How to work this around
Well, set up the (custom) field formatter for the langcode
field like you would do normally. And right after that, implement the hook_ENTITY_TYPE_view_alter()
hook for the node entity type, and in that hook, do this:
1
2
3
4
5
6
7
8
9
/**
* Implements hook_ENTITY_TYPE_view_alter() for node.
*/
function nodeviewbuilder_fixer_node_view_alter(&$build, NodeInterface $entity, EntityViewDisplayInterface $display) {
// Re-add the expected Language field output to the render array.
if ($display->getComponent('langcode')) {
$build['langcode'] = $entity->get('langcode')->view($build['#view_mode']);
}
}
That’s it.