I'm taking my first steps in understanding how Drupal 8 works under the hood by developing a custom form widget module. My goal is to show a referenced node's image field value, instead of its node title in a radio button list (available in core). This will allow website admins to select a picture instead of text when choosing a background image for a node.
Here's how my form looks without a custom work, using Drupal 8's built-in "Check boxes/radio buttons" widget:
Here's a Photoshop mockup of how I want my custom widget to appear (at least to start):
So far I've been able to create a starting module that extends the "Check boxes/radio buttons" widget, referencing the Examples for Developers module and traversing core. This has at helped me understand Drupal 8's module structure a little better at the least.
Module structure:
modules
custom
back_image_widget
back_image_widget.info.yml
back_image_widget.module
src
Plugin
Field
Field Widget
BackImageWidget.php
back_image_widget.info.yml:
name: Background Image Entity Widget
type: module
description: Used to list Background Image entities as images instead of text labels in the Text Message content type form.
package: Custom
core: 8.x
back_image_widget.module:
<?php
/**
* @file
* Used to list Background Image entities as images instead of text labels in the Text Message content type form.
*/
BackImageWidget.php:
<?php
/**
* @file
* Contains \Drupal\back_image_widget\Plugin\Field\FieldWidget.
*/
namespace Drupal\back_image_widget\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsButtonsWidget;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'field_back_image' widget.
*
* @FieldWidget(
* id = "field_back_image",
* module = "back_image_widget",
* label = @Translation("Background Image Entity"),
* field_types = {
* "entity_reference"
* },
* multiple_values = FALSE
* )
*/
class BackImageWidget extends OptionsButtonsWidget {
//Here we go!
}
With that, I'm able to install the module, select the new widget, and have all expected functionality that core offers to start.
From here, I'm having troubles identifying the best pieces from parent classes to alter so that I can replace titles with other entity values. The most helpful functions seem to be protected. The resulting options return protected titles (without other information available such as node ids to play with). Do I need to inherit a great grandparent and start fresh? I'm guessing I'll need to further explore dependency injections? Any thoughts on how to proceed in general or in detail? I'm flexible with answers as long as it helps me overcome this stuck point.

