Problem/Motivation

To add a new twig function for rendering image with a style

Steps to reproduce

NA

Proposed resolution

Add new twig function for rendering image with style.

Remaining tasks

Add test coverage
Review
Commit

User interface changes

NA

API changes

NA

Data model changes

NA

Release notes snippet

NA

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

wilei’s picture

+1 for this one.

I can come up with some cases when this feature is needed. At least when working with custom entities when views and/or fields may not be available, this feature would be very nice.

star-szr’s picture

It's going to be a bit more complicated than some of the other Twig extensions we have but shouldn't be too bad, I think you'd end up with something like this in a Twig extension (rough pseudo code):

$style = entity_load('image_style', $style);
return $style->buildUrl($uri);

This should also be doable in preprocess, so I'm not sure about this: "the task can only be accomplished through the use of contrib modules in conjunction with views."

dmdewey’s picture

Issue summary: View changes

removed "and the task can only be accomplished through the use of contrib modules in conjunction with views"

star-szr’s picture

Title: Twig image style filter » Twig image style filter/function
Parent issue: » #2168231: Twig Functions needed in templates
dawehner’s picture

Its not really clear for me why we don't just expose image_style_url, as it is. It would be great to document that in the issue summary.

star-szr’s picture

Because the function doesn't exist in D8.

image_style_url()

dawehner’s picture

Ups :) Well, maybe its also enough to wrap


$style = entity_load('image_style', $style);
return $style->buildUrl($uri);

in some nice little helper function?

dawehner’s picture

This issue as marked as feature request, but at the same time it blocks #2168231: Twig Functions needed in templates.
Does this mean this issue is also a bug?

mortendk’s picture

Issue tags: +image

any progress on this or did i miss something ?
it would be pretty amazing if we could do something like this inside of a template

<a href="#">{{ content.image|image-size('small')}}</a>
<div class="secret-hidden-will-be-shown-later-with-css-cause-we-want-a-imagegallery">
  {{ content.image|image-size('large')}}
</div>
JeroenT’s picture

Assigned: Unassigned » JeroenT

Will work on this tomorrow. If anyone beats me to it, feel free to unassign me.

harshil.maradiya’s picture

I would like to work on this but before this i want to discus my approach

Please correct me if i am wrong

  • Introduce filters in twigextenstion.php
  • And declare method in twigextenstion.php

Regards
Harshil Maradiya

JeroenT’s picture

Assigned: JeroenT » Unassigned
Status: Active » Needs review
FileSize
1.11 KB

First attempt on creating the twig filter.

Patch attached.

mortendk’s picture

Status: Needs review » Needs work
Issue tags: +needs manua

created a image.html.twig template

<img{{ attributes|without('src')}} src="{{ attributes.src|style('medium') }}" />

unfortunately it dosnt render the image

<img property="schema:image" width="480" height="320" alt="coffee" typeof="foaf:Image" src="http://styles/medium/http/drupal8.dev/sites/default/files/styles/large/public/field/image/coffee.jpg?itok=nJshh3GG&amp;itok=03bZfNJF">

cause this is the return path to the image
http://styles/medium/http/drupal8.dev/sites/default/files/styles/large/public/field/image/coffee.jpg?itok=nJshh3GG&itok=03bZfNJF

guess something needs to get done to that path (styles/medium/http/)?

JeroenT’s picture

Status: Needs work » Needs review
FileSize
2.17 KB
1.54 KB

Created a new patch that a size filter like this:

<a href="#">{{ content.image|image-size('small')}}</a>
<div class="secret-hidden-will-be-shown-later-with-css-cause-we-want-a-imagegallery">
  {{ content.image|image-size('large')}}
</div>

I haven't addressed the bug in #13.

The following code passes an absolute url in the twig filter but \Drupal\image\Entity\ImageStyle::buildUrl() expects an uri. Not sure how to solve this.

<img{{ attributes|without('src')}} src="{{ attributes.src|style('medium') }}" />
JeroenT’s picture

Issue tags: -needs manua +Needs manual testing
mortendk’s picture

Issue summary: View changes
Status: Needs review » Needs work
FileSize
269.36 KB

@JeroenT i tested it out lemme know if i do something stupid ;)

use the image.html.twig template wonder if im doing something wrong ?

andriyun’s picture

Issue tags: -Needs manual testing

Manual testing done. So I remove proper tag

oakulm’s picture

Issue summary: View changes

Ok some thoughts after DC Baltics sprint about this issue. My idea is that to use these filters you should send original image to template and in the template decide what preset to use (instead of in the field setting). Am I correct?

The main issue is (I think) the fact that attributes.src returns absolute path to file. What I set out to do and failed was to find a method that finds file object from filename or absolute url (or what ever is the method in D8) and parses file path to schema:// format. Does anyone know does this exist? If it does than I think this problem is trivial to fix.

oakulm’s picture

+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -513,4 +516,47 @@ public function renderVar($arg) {
+   * @param string $style
...
+   * @param string $uri

These parameters are not strings at the moment if used with {{ attributes.src|style('example') }}

oakulm’s picture

Ok this patch works with:

{{ attributes.src|style('large')}}
<img{{ attributes|without('src', 'height', 'width')}} src="{{ attributes.src|style('large') }}" />

Don't really know if this is the right direction to take?

oakulm’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 20: twig_image_style-2361299-20.patch, failed testing.

Anonymous’s picture

I think the mechanic of fetching the file based on the filename is flawed. What would happen when two images have the same name, but are different?

  1. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +   * Wrapper around \Drupal\image\ImageStyleInterface::buildUrl().
    

    This comment is no longer relevant?

  2. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +   * @param string $style
    +   *   The image style.
    

    This is not a string, but a Drupal\image\Entity\ImageStyle object.

  3. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +   * @param string $uri
    +   *   Url to image.
    

    This is not a string but a \Drupal\Core\Template\AttributeString object.

  4. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +   * @return mixed
    

    This would be a string or nothing at all.

  5. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +      ->condition('filename', basename($uri), '=')
    

    The basename() function could return myfile.png?foo=bar, which would make that query fail?

  6. +++ b/core/lib/Drupal/Core/Template/TwigExtension.php
    @@ -514,4 +518,56 @@ public function renderVar($arg) {
    +    $query = \Drupal::entityQuery('file')
    ...
    +      ->range(0,1);
    

    Actually, what happens when you have to different images with the same filename? I don't think this would work as expected?

tuutti’s picture

I spoke with @lauriii little bit about this and one possible way to implement this would be by adding 'original_uri' (or something similar) render array item and populate it with file uri.

lauriii’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 24: 2361299-24.patch, failed testing.

The last submitted patch, 24: 2361299-24.patch, failed testing.

pwolanin’s picture

Version: 8.0.x-dev » 8.1.x-dev
Issue tags: +Needs issue summary update

features need to go to 8.1 now

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Virang’s picture

Can we override this TwigExtension.php with custom module? as above mentioned path for patch is core/lib/Drupal/Core/Template/TwigExtension.php.

Please suggest me I just started learning Drupal 8.

morbidick’s picture

I just tried patch #14 and modified it for the current version 8.1.2. For now I only could test the size filter which works fine.
A custom module or to get the filter in to core would be awesome.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

pounard’s picture

I have no particular opinion about this patch except the fact that entity_load() procedural call is done inside a service, you should probably add the entity.manager service injection instead.

kamalMaroc’s picture

To get image by style, first you need to create an extension of twig, that can load image by your parameters (large, thumbnail ...etc) :

1- In your custom module create file "Image.php" in "/modules/custom/your_module/src/TwigExtension

<?php
namespace Drupal\your_module\TwigExtension;

use Drupal\node\Entity\Node;
use Drupal\Core\Link;
use Drupal\Core\Url;

use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

class Images extends \Twig_Extension {
  /**
   * Generates a list of all Twig functions that this extension defines.
   */
  public function getFunctions(){
    return array(
      new \Twig_SimpleFunction('image_style', array($this, 'imageStyle'), array('is_safe' => array('html'))),
    );
  }

  /**
   * Gets a unique identifier for this Twig extension.
   */
  public function getName() {
    return 'your_module.twig.images';
  }


  /**
   * Generate images styles for given image
   */
  public static function imageStyle($file_id, $styles) {
    $file = File::load($file_id);
    $transform = array();
    if (isset($file->uri->value)) {
      $transform['source'] = $file->url();
      foreach ($styles as $style) {
        $transform[$style] = ImageStyle::load($style)->buildUrl($file->uri->value);
      }
    }
    return $transform;
  }
}

2- In root folder create file service "/modules/custom/your_module/your_module.services.yml

services:
  your_module.twig.images:
    #arguments: ['@renderer']
    class: Drupal\your_module\TwigExtension\Images
    tags:
      - { name: twig.extension }

3- Delete a cache

4- Finally you can use extension in twig file like this :

{% set image = image_style(node.field_image.entity.fid.value, ['large']) %}
<img src="{{ image.large }}" >

Good Luck.

ichionid’s picture

"/modules/custom/your_module/your_module.services.yml.php" @kamalMaroc this should not have a php ending. Pretty nice and detailed guide :-)

harry_nc’s picture

1- In your custom module create file "Image.php" in "/modules/custom/your_module/src/TwigExtension

- Images.php**

With that and #36, works a treat thanks man!

featherbelly’s picture

@kamalMaroc This works great!

#35 + #36 + #37

Rene Bakx’s picture

If you want a installable solution, I am willing to add the code of Kamel or improved version to the Themers Little Helper project.
There is a similar twig function in TFD7, and I do think having a plain file to image style mapper can come in handy sometimes.

The only thing I would probably change is signature of the method, instead of relying on the fid.value, I would prefer to just pass the entire field to twig function and let the function figure out if it got a FID, File entity or renderable array)

<img src="{{ image_style(content.field_image,'large') }}">

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

basvanderheijden’s picture

gaurav.kapoor’s picture

Status: Needs work » Needs review

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

leisurman’s picture

@kamalMaroc Thank you!
#35 + #36 + #37

This does work for a regular image upload field. But it does not work if the field is a entity reference media field.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

gagarine’s picture

This features is still in consideration?

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

jcnventura’s picture

jcnventura’s picture

Code in #41 required a bit more than a re-roll, since entity_load no longer exists in Drupal 9.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work

For issue summary update.

NivethaSubramaniyan’s picture

Added patch for 10.1

Ankit.Gupta’s picture

Status: Needs work » Needs review
FileSize
3.67 KB
jcnventura’s picture

@NivethaSubramaniyan: When re-rolling, please don't make coding standard changes 50 lines away from the code you're changing..

smustgrave’s picture

@Ankit.Gupta you should test your patch for failing CI before uploading. The script is in core/scripts.

smustgrave’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs Review Queue Initiative

Self review

This will need test coverage.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.