web-dev-qa-db-fra.com

Obtenir l'URL de l'image en Twig

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

21
Jannis Hell

La variable node n'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 champ twig 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 %}

Edit: 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 %}
32
4k4

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) }}
26
Jonasdk

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

3
bennash

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 j'ai dû 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++;
        }
    }
}

Là encore, 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 alors je vais corriger ça :-).

1
ZyDucksLover

Après avoir passé deux jours, j'ai trouvé une réponse à mon code similaire. Avec inclusion et exclusion de certains champs.

{%
set classes = [
'block',
'block-' ~ configuration.provider|clean_class,
'block-' ~ plugin_id|clean_class,
'cover-image',
]
%}

{% set background_image = file_url(content.field_banner_image['#items'].entity.uri.value) %}

<div{{ attributes.addClass(classes) }} style="background-image: 
url({{background_image}})">

<div class="block-inner">
{{ title_prefix }}
{% if label %}
<h2{{ title_attributes }}>{{ label }}</h2>
{% endif %}
{{ title_suffix }}
{% block content %}
{{ content.field_media_image }}
<div class="summary">
{{ content|without('field_banner_image') }}
</div>
{% endblock %}
</div>
</div>

nom fin dans le bloc de thème - bundle - banner-block.html.twig Ce code est pour un bloc personnalisé avec des images.

Un autre exemple pour un fichier simple. pas Pesting code entier, mais seulement essentiel.

<a href="{{file_url(node.field_attachment1.entity.uri.value)  }}" ><h3> 
{{content.field_short_information}} </h3></a>

Ces extraits de code pour le nœud de nœud - all_notice.html.twig. Tout fonctionne actuellement dans drupal 8.8.3

0
Pradeep