1

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>
  • @Clive It is not a duplicate. I am trying to get the image path in a preprocess_field function, not in a twig template. – Guillaume Bois Jul 11 '16 at 12:17
  • What about this one? – Clive Jul 11 '16 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! – Guillaume Bois Jul 11 '16 at 14:21
  • My mistake, I've re-opened it – Clive Jul 11 '16 at 14:32
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

| improve this answer | |
4

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);
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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