I have an Entity Product entity where one of the fields is:

  • reference field on Media type with name Media Product Image

Media Product Image has fields:

  • Image
  • Custom color id

And in the developers tools of the browser, the <img> looks like this:

<img loading="lazy src="/sites/default/files/styles...." width="300" height="550" typeof=foaf:Image>

I need to add the data-color attribute to the <img> tag and pass the value from the Custom Color id field to it. This can be done with:

For example:

function my_theme_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if (isset($element['#field_name'])) {
    if ($element['#field_name'] == 'field_image') {
      // do something

But the problem is that when I write the word media in the .module file in my entity_product_admin module in the function name:

function entity_product_admin_preprocess_media(&$variables, $hook) {

I can't get the value of field_custom_color_id because there is no method in the API of the media entity with which I can get the value of this field:

enter image description here

Also, I don't have access to the image attributes and I can't add the data-color attribute with the value of the Custom color id field.

If I write the word image in the name of the function:

function entity_product_admin_preprocess_image(&$variables, $hook) {

Then I already have access to the image attributes, but I do not have access to the field_custom_color_id field: enter image description here

I tried to write just field in the function name, but then I can get through anywhere.
How then should this function look like?

2 Answers 2


Field preprocess to preprocess a field, and it has no access generally to any other field.
A) You create a custom field type, formatter and widget. In that case, you can have the image and the colour in the same field. (if you created the field like that) but migration may be needed if you already have content.
B) Create a field formatter. In the field formatter, you can say how to render the field and you have access to the whole parent entity.

And an additional tip. Try to minimalise the usage of hook functions. They are fragile and easy to break. i.e. You write a preprocess where you read a field. You enable the layout or DS module, which will definitely break your preprocess as it changes the structure of the array in that hook as it adds the layout to it. You can extend plugins via OOP.


Try something like this:

 * Implements hook_preprocess_field().
function YOUR_THEME_preprocess_field(&$variables) {
  // Get the node object.
  $node = $variables['element']['#object'];

  // Limit the following changes to one specific node type.
  if ($node->bundle() != 'image_map') {
  $element = $variables['element'];
  $field_name = $element['#field_name'] ?? NULL;

  // We only want to apply this to one specific field.
  if ($field_name != 'field_imagemap') {

  // Set some variables based on the node values.
  if ($node->get('field_state_links')->getString() != '') {
    $variables['field_state_links'] = $node->get('field_state_links')->getValue();
  if ($node->get('field_image_map_type')->getString() != '') {
    $variables['field_image_map_type'] = $node->get('field_image_map_type')->getValue();

  // Test for a specific value of another field and modify "field_imagemap" field output as needed.
  if (strtolower($node->get('field_image_map_type')->getString()) == 'usa') {
    // Your code for mocking about with the field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.