Obter URL da imagem no Twig

22

Quero renderizar uma imagem como imagem de fundo por meio de um estilo embutido no galho. Criei um campo chamado bg_image e o anexei à página simples padrão.

Depois de mexer por horas, consegui obter o URL da imagem em node.html.twig

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

mas não consegui fazê-lo funcionar dentro do campo - field-bg_image.html.twig

Posso obter o nó de qualquer maneira para obter a imagem?

Como posso obter o URL da imagem para usar como estilo embutido? Eu pensei que talvez eu possa passar uma variável do campo - field-bg_image.html.twig para image.html.twig e depois apenas renderizar

{{ uri }}

ao invés de

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

mas não consegui passar a variável para lá, a menos que eu use include

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

(isFromField é verdadeiro quando se trata do campo - field-bg_image.html.twig) Mas isso também não funcionou. A imagem nunca foi renderizada dessa maneira.

Ficaria muito feliz se você puder ajudar - meu conhecimento de php é muito básico. obrigado

Jannis Hell
fonte

Respostas:

31

A variável nodeé pré-carregada apenas no modelo do nó (e no modelo da página, se o URL contiver o nó). Agora, se você quiser acessar os campos dos nós em um modelo de campo, precisará procurar em um local diferente:

field.html.twig:

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

element['#object'] é a entidade pai em um modelo de campo e você pode acessar qualquer campo dessa entidade (no seu caso, o nó).

Se você deseja acessar valores brutos a partir do campo real, é melhor seguir a lógica do galho do campo e acessar o valor dentro do loop de itens diretamente do objeto do item de campo #item:

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

Editar: obter o URL de um estilo de imagem

Instale o módulo Twig Tweak e você pode usar a uri para obter a URL de um estilo de imagem:

{% for item in items %}
  {{ item.content['#item'].entity.uri.value | image_style('thumbnail') }}
{% endfor %}
4k4
fonte
Ótimo que funciona! Obrigado. Também é possível obtê-lo em um estilo de imagem específico? (grande ou miniatura)
Jannis Hell
26

Apenas para mencionar que se você quiser fazer o mesmo em um dos novos blocos personalizados, isso funcionará:

{{ file_url(content.field_image['#items'].entity.uri.value) }}
Jonasdk
fonte
Isso funciona para o campo de bloco.
Alex
E também esse código funciona para o campo de parágrafo da imagem no modelo de galho do parágrafo.
Vadim Sudarikov 13/03/19
Sim! Obrigado. Isso funciona quando você está tentando obter o URL da imagem no campo Imagem do conteúdo também nos modelos de parágrafo.
21418 Robb Davis #
Não funciona para vistas
Jignesh Rawal
3

Eu uso esse código no meu arquivo .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());
  }
}

Pode ser melhorado. Estou verificando o campo da imagem e carregando seu URL com um estilo de imagem.

Então, no meu nó - arquivo page.html.twig, tenho o seguinte:

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

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

Novamente, isso poderia melhorar. obrigado

bennash
fonte
1
Isso funciona para um campo regular de upload de imagens. Mas não funciona para um campo de imagem de referência da entidade.
paulcap1
1

Eu faria de outra maneira. Na função de pré-processo do nó:

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

Em seguida, em seu modelo (nó - NODETYPE.html.twig), apenas renderize a imagem dessa maneira:

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

Embora, se você precisar renderizar uma grande quantidade de imagens, recomendo que você carregue os estilos em uma matriz antes de repetir cada imagem. Estou dizendo que, como tive problemas sérios no tempo de carregamento, porque precisei carregar mais de 300 imagens e, para cada imagem, carregava o estilo individualmente, em vez de carregá-las todas antes, aqui está um exemplo, a mesma base acima:

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

Então, novamente, em seu modelo (nó - NODETYPE.html.twig), apenas renderize as imagens dessa maneira:

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

Eu realmente não testei e estou tirando tudo isso da minha cabeça para que possa conter erros, fique à vontade para me avisar para corrigir isso :-).

ZyDucksLover
fonte
-1

Eu tive algum sucesso usando o Módulo de Imagem de Fundo quando o caso de uso permite. Uso uma dessas opções de código quando preciso de uma estrutura DOM personalizada.

Matt
fonte