在Twig中获取图像URL


22

我想通过树枝中的嵌入式样式将图像渲染为背景图像。我创建了一个名为bg_image的字段,并将其附加到标准普通页面上。

摆弄了几个小时后,我能够在node.html.twig中获得图像URL

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

但我无法在field--bg_image.html.twig中使用

我是否可以从那里获取节点,然后获取图像?

如何获得用作内联样式的图像URL?我以为我可以将变量从field-bg_image.html.twig传递到image.html.twig,然后渲染

{{ uri }}

代替

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

但是除非我使用include,否则我无法通过它传递变量

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

(isFromField是真实的,当它来自字段时–field-bg_image.html.twig)但这也不起作用。图像从未以这种方式渲染。

如果您能提供帮助,将非常高兴-我的PHP知识非常基础。谢谢


Answers:


31

node仅在节点模板(如果URL包含节点,则在页面模板)中预加载变量。现在,如果要访问字段模板中的节点字段,则必须在其他位置查找:

field.html.twig:

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

element['#object'] 是字段模板中的父实体,您可以从该实体(在您的情况下为节点)访问任何字段。

如果要访问实际字段的原始值,最好遵循字段细枝的逻辑,并直接从字段item对象访问items循环内的值#item

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

编辑:获取图像样式的URL

安装模块Twig Tweak,您可以使用uri获取图像样式的url:

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

伟大的作品!谢谢。是否有可能以特定的图像样式获得它?(大图或缩略图)
Jannis Hell 2015年

26

只需提及一下,如果您想在新的自定义块之一中执行相同的操作,则可以这样做:

{{ file_url(content.field_image['#items'].entity.uri.value) }}

这适用于块字段。
亚历克斯

该代码也适用于段落的树枝模板中的图像段落字段。
Vadim Sudarikov

是! 谢谢。当您尝试从段落模板的内容图片字段中获取图片网址时,此方法也适用。
Robb Davis

不适用于视图
Jignesh Rawal '18

3

我在我的.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());
  }
}

可以改进。我正在检查图片字段,并使用图片样式加载其网址。

然后在我的node.page.html.twig文件中,我有以下内容:

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

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

同样,这可以使用一些改进。谢谢


1
这适用于常规图像上传字段。但这不适用于实体参考图像字段。
paulcap1

1

我会做另一种方式。在您的节点预处理功能中:

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

然后,在您的模板(node--NODETYPE.html.twig)中,以这种方式渲染图像:

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

虽然,如果您不得不渲染大量图像,我建议您在循环播放每个图像之前将样式加载到数组中。我说这是因为我遇到了严重的加载时间问题,因为我必须加载300幅图像,并且对于每个图像,我是分别加载样式而不是之前全部加载样式,这是一个示例,与上面相同:

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

然后,再次在您的模板(node--NODETYPE.html.twig)中,以这种方式渲染图像:

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

我还没有真正测试过它,所以我想不通,所以它可能包含错误,可以随时警告我,以便我纠正此问题:-)。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.