Obtener URL de imagen en Twig

22

Quiero representar una imagen como imagen de fondo a través de un estilo en línea en twig. Creé un campo llamado bg_image y lo adjunté a la página normal estándar.

Después de jugar durante horas, pude obtener la URL de la imagen en node.html.twig

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

pero no pude hacerlo funcionar dentro del campo - field-bg_image.html.twig

¿Puedo obtener el nodo desde allí de todos modos, para poder obtener la imagen?

¿Cómo puedo obtener la URL de la imagen para usarla como estilo en línea? Pensé que tal vez podría pasar una variable de campo - field-bg_image.html.twig a image.html.twig y luego simplemente renderizar

{{ uri }}

en lugar de

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

pero no pude hacer que pasara la variable allí a menos que use incluye

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

(isFromField es verdadero, cuando viene del campo - field-bg_image.html.twig) Pero eso tampoco funcionó. La imagen nunca fue renderizada de esa manera.

Estaría muy contento si puede ayudar, mi conocimiento de php es muy básico. Gracias

Jannis Hell
fuente

Respuestas:

31

La variable nodesolo está precargada en la plantilla de nodo (y la plantilla de página, si la url contiene el nodo). Ahora, si desea acceder a los campos de nodo en una plantilla de campo, debe buscar en un lugar diferente:

field.html.twig:

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

element['#object'] es la entidad principal en una plantilla de campo y puede acceder a cualquier campo desde esta entidad (en su caso, el nodo).

Si desea acceder a valores sin procesar desde el campo real, es mejor seguir la lógica de la ramita de campo y acceder al valor dentro del bucle de elementos directamente desde el objeto de elemento de campo #item:

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

Editar: obtener la URL de un estilo de imagen

Instale el módulo Twig Tweak y puede usar la uri para obtener la url de un estilo de imagen:

{% for item in items %}
  {{ item.content['#item'].entity.uri.value | image_style('thumbnail') }}
{% endfor %}
4k4
fuente
Genial que funciona! Gracias. ¿También es posible obtenerlo en un estilo de imagen específico? (grande o miniatura)
Jannis Hell
26

Solo para mencionar que si desea hacer lo mismo en uno de los nuevos bloques personalizados, esto funciona:

{{ file_url(content.field_image['#items'].entity.uri.value) }}
Jonasdk
fuente
Esto funciona para el campo de bloque.
Alex
Y también este código funciona para el campo de párrafo de imagen en la plantilla de ramita del párrafo.
Vadim Sudarikov
¡Sí! Gracias. Esto funciona cuando intenta obtener la URL de la imagen del campo de imagen de contenido en las plantillas de párrafo también.
Robb Davis
No funciona para las vistas
Jignesh Rawal
3

Yo uso este código en mi archivo .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());
  }
}

Se podría mejorar. Estoy buscando el campo de imagen y cargando su url con un estilo de imagen.

Luego, en mi nodo - archivo page.html.twig tengo esto:

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

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

Nuevamente, eso podría mejorar. Gracias

bennash
fuente
1
Esto funciona para un campo de carga de imagen normal. Pero no funciona para un campo de imagen de referencia de entidad.
paulcap1
1

Lo haría de otra manera. En su función de preproceso de nodo:

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.
    }
}

Luego, en su plantilla (nodo - NODETYPE.html.twig), simplemente renderice la imagen de esa manera:

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

Sin embargo, si alguna vez tiene que renderizar una gran cantidad de imágenes, le aconsejo que cargue los estilos en una matriz antes de hacer un bucle en cada imagen. Digo que debido a que me he encontrado con serios problemas de tiempo de carga porque tuve que cargar más de 300 imágenes y para cada imagen, estaba cargando el estilo individualmente en lugar de cargarlas todas antes, aquí hay un ejemplo, la misma base que arriba:

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++;
        }
    }
}

Por otra parte, en su plantilla (nodo - NODETYPE.html.twig), simplemente renderice las imágenes de esa manera:

{% 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 %}

Realmente no lo he probado y me estoy sacando todo esto de la cabeza, por lo que podría contener errores, no dudes en advertirme, así que corregiré esto :-).

ZyDucksLover
fuente
-1

He tenido éxito al usar el Módulo de imagen de fondo cuando el caso de uso lo permite. Uso una de estas opciones de código cuando necesito una estructura DOM personalizada.

Mate
fuente