On my "teaser" view mode I want to display my Image field but if the Image field is empty I want to display my Title field instead.
I have tried using hook_preprocess_node but it appears that this is not called when rendering the node in the "teaser" display mode when using Display Suite.
Another thought I had was to create a custom DsField plugin... but in that case I do not have the context of the other fields (unless I do?) so I cannot say "if img is empty display title, else display img" Using the suggestion below I came up with:
class ImageElseTitle extends DsFieldBase {
public function build() {
/** @var /Drupal/node/Entity/node $node */
$node = $this->entity();
if ($node->get('field_event_image')->isEmpty()) {
return $node->get('title')->view('teaser');
}
else {
return $node->get('field_event_image')->view('teaser');
}
}
}
But in this case the settings for the title field are not obeyed. For example, it is wrapped in a span instead of an h2 as specified in the display settings. Similarly it is not a link even though "link" is checked in the display settings...
I tried adding a preprocess to the title field that checks if the image field is empty, but I think the preprocess function is too late to say "the image field is not empty, so never mind, dont display the title"
Thoughts?
-- Continued --
I also tried this, but the fields are not hidden as I'd expect them to be:
function mymodule_ds_pre_render_alter(&$layout_render_array, $context, &$vars) {
if ($context['entity_type'] == 'node' && $context['bundle'] == 'event' && $context['view_mode'] == 'teaser') {
if ($context['entity']->get('field_event_image')->isEmpty()) {
$layout_render_array['field_event_image']['#access'] == FALSE;
}
else {
$layout_render_array['node_title']['#access'] = FALSE;
$layout_render_array['title']['#access'] = FALSE;
}
}
}