2

After 3 hours of searching the web for this I gave up...

I have added a "banner image" field to the basic page. I want to use the image as a background. I wanted to capture the image path in a preprocess_field function but I tried every possible methods on the \Drupal\image\Plugin\Field\FieldType\ImageItem object and can't seem to find the way to get the path.

mytheme.theme:

function mytheme_preprocess_field(&$variables){
  if($variables['field_name'] == 'field_banner_image'){
    /** @var \Drupal\image\Plugin\Field\FieldType\ImageItem $field */
    $field = $variables['element']['#items'][0];        
    $variables['banner_url'] = $field->getValue(); // not working, tried everything...
  }
}

Then in my field--field-banner-image.html.twig:

<div class="field--name-field-banner-image" style="background: transparent url({{ banner_url }})"></div>
4
  • @Clive It is not a duplicate. I am trying to get the image path in a preprocess_field function, not in a twig template. Jul 11, 2016 at 12:17
  • What about this one?
    – Clive
    Jul 11, 2016 at 12:27
  • @Clive the variables is not the same in preprocess_field as in preprocess_node. i am able to get the field object which is a \Drupal\image\Plugin\Field\FieldType\ImageItem with $field = $variables['element']['#items'][0]; but $field doesn't have the method getFileUri! Jul 11, 2016 at 14:21
  • My mistake, I've re-opened it
    – Clive
    Jul 11, 2016 at 14:32

2 Answers 2

5

You can do this more simply

$uri = \Drupal\file\Entity\File::load($variables['items'][0]['content']['#item']->getValue()['target_id'])->getFileUri()

Or for a field with multiple items

foreach ($variables['items'] as $delta => $item) {
  $uri = \Drupal\file\Entity\File::load($variables['items'][$delta]['content']['#item']->getValue()['target_id'])->getFileUri()
}

And then apply an image style to get the url

$variables['banner_url'] = ImageStyle::load('image_style_name')->buildUrl($uri);
4

I found the answer. One thing weird is that you have to go to the parent entity and from this point go back to the field, only then you can get the url.

function mytheme_preprocess_field(&$variables){
  if($variables['field_name'] == 'field_banner_image'){
    /** @var \Drupal\image\Plugin\Field\FieldType\ImageItem $field */
    $field = $variables['element']['#items'][0];
    $field_image_url = get_image_uri($field->getEntity(), 'field_banner_image');
    $variables['banner_url'] = file_create_url($field_image_url);
  }
}

with

/**
 * Get the set or default image uri for a file image field (if either
 * exist).
 * @param $entity
 * @param $fieldName
 * @return null|string
 */
function get_image_uri($entity, $fieldName){
  $image_uri = NULL;
  if($entity->hasField($fieldName)){
    try{
      $field = $entity->{$fieldName}; // Try loading from field values first.
      if($field && $field->target_id){
        $file = \Drupal\file\Entity\File::load($field->target_id);
        if($file){
          $image_uri = $file->getFileUri();
        }
      }
    } catch(\Exception $e){
      \Drupal::logger('get_image_uri')->notice($e->getMessage(), []);
    }
    // If a set value above wasn't found, try the default image.
    if(is_null($image_uri)){
      try{
        $field = $entity->get($fieldName); // Loading from field definition
        if($field){
          // From the image module /core/modules/image/ImageFormatterBase.php
          // $default_image = $test->fieldDefinition->getFieldStorageDefinition()->getSetting('default_image');
          $default_image = $field->getSetting('default_image');
          if($default_image && $default_image['uuid']){
            // $defaultImageFile = \Drupal::entityManager()->loadEntityByUuid('file', $default_image['uuid']));
            // See https://www.drupal.org/node/2549139  entityManager is deprecated.
            // Use entity.repository instead.
            $entityrepository = Drupal::service('entity.repository');
            $defaultImageFile = $entityrepository->loadEntityByUuid('file', $default_image['uuid']);
            if($defaultImageFile){
              $image_uri = $defaultImageFile->getFileUri();
            }
          }
        }
      } catch(\Exception $e){
        \Drupal::logger('get_image_uri')->notice($e->getMessage(), []);
      }
    }
  }
  return $image_uri;
}

Also another weird thing I noticed while trying stuff:

$field->entity

and

$field->getEntity()

does not give the same object

Your Answer

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

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