Obtenir l'URL de l'image dans Twig

22

Je veux rendre une image comme image d'arrière-plan via un style en ligne dans twig. J'ai créé un champ appelé bg_image et je l'ai attaché à la page standard standard.

Après avoir tripoté pendant des heures, j'ai pu obtenir l'URL de l'image dans node.html.twig

{{ file_url(node.field_bg_image.0.entity.uri.value) }}

mais je ne pouvais pas le faire fonctionner à l'intérieur du champ - field-bg_image.html.twig

Puis-je obtenir le nœud à partir de là de toute façon, afin que je puisse ensuite obtenir l'image?

Comment puis-je obtenir l'URL de l'image à utiliser comme style en ligne? J'ai pensé que je pourrais peut-être passer une variable de field - field-bg_image.html.twig à image.html.twig et ensuite simplement rendre

{{ uri }}

au lieu de

<img{{ attributes.addClass(classes) }} />

mais je ne pouvais pas le faire passer la variable à moins que j'utilise comprend

{% include 'image.html.twig' with {'image': image, 'isFromField': isFromField} %}

(isFromField est vrai, quand il vient du champ - field-bg_image.html.twig) Mais cela n'a pas fonctionné non plus. L'image n'a jamais été rendue de cette façon.

Serait très heureux si vous pouvez aider - mes connaissances php sont très basiques. Merci

Jannis Hell
la source

Réponses:

31

La variable noden'est préchargée que dans le modèle de nœud (et le modèle de page, si l'url contient le nœud). Maintenant, si vous souhaitez accéder aux champs de noeud dans un modèle de champ, vous devez regarder dans un endroit différent:

field.html.twig:

{{ file_url(element['#object'].field_image.0.entity.uri.value) }}

element['#object'] est l'entité parente dans un modèle de champ et vous pouvez accéder à n'importe quel champ à partir de cette entité (dans votre cas, le nœud).

Si vous souhaitez accéder aux valeurs brutes du champ réel, il est préférable de suivre la logique du rameau de champ et d'accéder à la valeur à l'intérieur de la boucle d'articles directement à partir de l'objet d'élément de champ #item:

{% for item in items %}
  {{ file_url(item.content['#item'].entity.uri.value) }}
{% endfor %}

Modifier: obtenez l'url d'un style d'image

Installez le module Twig Tweak et vous pouvez utiliser l'uri pour obtenir l'url d'un style d'image:

{% for item in items %}
  {{ item.content['#item'].entity.uri.value | image_style('thumbnail') }}
{% endfor %}
4k4
la source
Super ça marche! Merci. Est-il également possible de l'obtenir dans un style d'image spécifique? (grand ou miniature)
Jannis Hell
26

Juste pour mentionner que si vous voulez faire la même chose dans l'un des nouveaux blocs personnalisés, cela fonctionne:

{{ file_url(content.field_image['#items'].entity.uri.value) }}
Jonasdk
la source
Cela fonctionne pour le champ de bloc.
Alex
Et ce code fonctionne également pour le champ de paragraphe d'image dans le modèle de brindille du paragraphe.
Vadim Sudarikov
Oui! Merci. Cela fonctionne également lorsque vous essayez d'obtenir l'URL de l'image à partir du champ d'image de contenu sur les modèles de paragraphe.
Robb Davis
Ne fonctionne pas pour les vues
Jignesh Rawal
3

J'utilise ce code dans mon fichier .theme:

function THEMENAME_preprocess_node(&$variables) {

  if ($variables['node']->field_image->entity) {
      $variables['image_url'] = $url = entity_load('image_style', 'medium')->buildUrl($variables['node']->field_image->entity->getFileUri());
  }
}

Cela pourrait être amélioré. Je vérifie le champ d'image et charge son URL avec un style d'image.

Ensuite, dans mon fichier node - page.html.twig, j'ai ceci:

{% if image_url is not empty %}
    <div class="featured-thumb">
        <img src="{{ image_url }}"/>
    </div>
{% endif %}

<div>{{ content.body|without('field_image') }}</div>

Encore une fois, cela pourrait nécessiter certaines améliorations. Merci

bennash
la source
1
Cela fonctionne pour un champ de téléchargement d'image régulier. Mais cela ne fonctionne pas pour un champ d'image de référence d'entité.
paulcap1
1

Je le ferais d'une autre manière. Dans votre fonction de prétraitement de nœud:

use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset($node->get('field_image')->entity)){
        $image_style = 'large'; // Or whatever your image style's machine name is.
        $style = ImageStyle::load($style);
        $variables['image'] = $style->buildUrl($node->get('field_image')->entity->getFileUri()); // Generates file url.
    }
}

Ensuite, dans votre modèle (node ​​- NODETYPE.html.twig), rendez simplement l'image de cette façon:

{% if image %}
    <img src="{{ image }}" />
{% endif %}

Bien que, si vous devez rendre une grande quantité d'images, je vous conseille de charger les styles dans un tableau avant de boucler sur chaque image. Je dis que parce que j'ai rencontré de sérieux problèmes de temps de chargement parce que je devais charger plus de 300 images et pour chaque image, je chargeais le style individuellement au lieu de les charger toutes avant, voici un exemple, même base que ci-dessus:

use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset(node->get('field_images')[0]->entity)){ // Notice how, this time, I check if the FIRST image is set (if it's true, then u'll allow the loop for at least 1 element)
        $images_styles = [
            'large' => ImageStyle::load('large'),
            'thumbnail' => ImageStyle::load('thumbnail')
        ];
        $count = 0;

        foreach($node->get('field_images') as $image){
            $variables['images'][$count]['large'] = $images_styles['large']->buildUrl($image->getFileUri());
            $variables['images'][$count]['thumbnail'] = $images_styles['thumbnail']->buildUrl($image->getFileUri());
            $count++;
        }
    }
}

Ensuite, dans votre modèle (node ​​- NODETYPE.html.twig), rendez simplement les images de cette façon:

{% if images %}
    <ul>
        {% for image in images %}
            <li>
                <img src="{{ image.large }}" /> // Large image url.
                <img src="{{ image.thumbnail }}" /> // Thumbnail image url.
            </li>   
        {% endfor %}
    </ul>
{% endif %}

Je ne l'ai pas vraiment testé et je retire tout ça de ma tête donc ça peut contenir des erreurs, n'hésitez pas à me prévenir donc je vais corriger ça :-).

ZyDucksLover
la source
-1

J'ai eu un certain succès en utilisant le module Image d'arrière - plan lorsque le cas d'utilisation le permet. J'utilise l'une de ces options de code lorsque j'ai besoin d'une structure DOM personnalisée.

Mat
la source