2

We have a custom module mymodule where we call mymodule_tokens so that we can assign custom token values from the current node. These custom tokens are used to insert values in the Article's MetaTag fields.

Problem

When fetching the default value based on an Image Style (e.g. medium), I cannot get the Height and Width based on the Configuration for the Image Style. How can I get the height and width from the Image Style?

What I have tried, but cannot get the height and width:

function mymodule_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {
  $replacements = [];
  $node = $data['node'];
  $node_image = $node->field_image;
  $field_image_style = 'medium';

  if($node_image->isEmpty()) {
    $field_info = FieldConfig::loadByName('node', 'article, 'field_image');
    $image_uuid = $field_info->getSetting('default_image')['uuid'];
    $image = Drupal::service('entity.repository')->loadEntityByUuid('file', $image_uuid);
    $field_image_url = ImageStyle::load($field_image_style)->buildUrl($image->getFileUri());
    $image_style = ImageStyle::load($field_image_style)->getEffects()->getConfiguration();

    // Both give me error messages.
    $image_style_height = $image_style->get('height');
    $image_style_width = $image_style->get('width');
  }
  else {
    $field_image_url = $node_field_image->entity->getFileUri();
    $image_style = ImageStyle::load($field_image_style)->getEffects()->getConfiguration();

    // Both give me error messages.
    $image_style_height = $image_style->get('height');
    $image_style_width = $image_style->get('width');
  }

  foreach($tokens as $name => $original) {
    switch ($name) {
      case 'custom_image_url':
        $replacements[$original] = $field_image_url;
        break;
      case 'custom_image_height':
        $replacements[$original] = $image_style_height;
        break;
      case 'custom_image_width':
        $replacements[$original] = $image_style_width;
       break;
    }
  }    

  return $replacements;
}

Error Message

Error: Call to a member function get() on array in mymodule_tokens()

When printing ImageStyle::load($field_image_style) using Kint this is what we get.

image style array

When printing $image_style, I get the following.

image_style

Using core or contrib tokens rather than custom tokens

Using the following tokens only work when there is a value added to the field_image field, but when the field_image is not populated, the token is not able to return the default image that is populated on the field's settings page.

[node:field_image:medium:height]
[node:field_image:medium:url]
[node:field_image:medium:width]
  • Have you installed the Devel sub-module Kint and then did ksm($image_style) to show you the available methods? I doubt that the $image_style object holds the finalized image properties. – leymannx Jun 20 '18 at 21:39
  • @leymannx i have updated the question with screenshots using kint() (same output when using ksm()). I can see that in the 'data' array the width and height are there. I wonder if it has to do with being protected. – usernameabc Jun 20 '18 at 22:12
  • 1
    Everything under "image_scale_and_crop" is protected, so you won't be able to read those values. What are you trying to do, exactly? – Kevin Jun 20 '18 at 23:02
  • @Kevin The Image Style medium performs a scale and crop where width => 400 and height => 260. I wanted to query that setting and use it to assign values to the custom tokens (see updated code) rather than hard coding the 400 and 260 in case those values are changed. Tokens such as [node:field_image:medium:height] does not return a value when the field_image is empty, hence the custom tokens. – usernameabc Jun 20 '18 at 23:36
2

You'll need to click on the Available Methods tab and see if there is an method for width and height.

enter image description here

When you click on it, searching for width or height should come up empty. I can tell this by looking at the ImageStyle Class.

But there will be a getEffects() method that you can use, which should contain the width and height.

$style = ImageStyle::load($field_image_style);

So do kint($style->getEffects());

I'll let you take it from here.


If you want to go the $image_style route then you can get the value with

$image_style[0]['1aa.......']['data']['width'];
$image_style[0]['1aa.......']['data']['height'];

PS:

I suggest you read my answer to What is easiest way to debug variables in nodes, views, blocks and page twig templates? to learn how to use kint properly.

  • 1
    If you see my answer below, i was able to iterate through it in a loop using the answer you provided. – usernameabc Jun 22 '18 at 15:45
4

No Sssweat's answer inspired this.

I added this before if statement (if($node_image->isEmpty())) to get the height and width.

$image_style_config = (ImageStyle::load('medium')->getEffects()->getConfiguration());

foreach($image_style_config as $config) { 
  if(isset($config['data'])) {
    if(isset($config['data']['height'])) {
      $image_style_height = $config['data']['height'];
    }
    if(isset($config['data']['width'])) {
      $image_style_width = $config['data']['width'];
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.