37

I have a question about getting a path to an image in a Twig template. The image is not assigned to a field or something. Just a static image which is stored in "MYTHEME/image/icon/my-icon.png".

In Drupal 7 I get the path in my node.template with the following code:

<img src="<?php print base_path() . path_to_theme(); ?>/image/icons">/my-icon.png

How does it work with in Drupal 8? I tried to pass a variable in template_preprocess_node().

MYTHEME.theme:

$variables['images_path'] = \Drupal::theme()->getActiveTheme()->getPath() . '/image/';

Twig template:

<img src="{{ images_path  ~ 'icons/' ~ 'my-icon.png' }}">

It doesn't work. There is no PHP error, but the path is wrongly said to be http://localhost/node/themes/template/image/icons/my-icon.png.

0

5 Answers 5

71

you can use {{ base_path ~ directory }} which will fix the absolute problem, no need to do any preprocessing, both of these variables are included by core.

For example

<img src="{{ base_path ~ directory }}/images/logo.png" alt="My Logo" />

PS. the ~ helper in twig is concatenate.

Edit: at least in the page*.html.twig templates base_path variable is included, possibly you will need to do preprocessing for other templates, you can easily check with {{ dump() }} if the variables are present

// File: THEMENAME.theme in your theme's root directory
function THEMENAME_preprocess(&$variables, $hook)
{
    $variables['base_path'] = base_path();
}
4
  • 3
    Thanks for sharing your solution. One quick comment: I had to explicitly add $variables['base_path'] = base_path(); to my THEME_preprocess_html theme hook to make it available to the html.html.twig template file. Feb 23, 2017 at 9:53
  • 3
    Be careful about using {{ directory }} Twig variable in a theme that you intend to use as a base theme and create sub-themes for: drupal.stackexchange.com/questions/277278 Mar 4, 2019 at 20:45
  • 1
    The twig template suggestions module provides {{ base_bath }} to every template; otherwise for some templates you'll have to do as Marcos Buarque did in the above comment, or Matoeil did in drupal.stackexchange.com/a/238535/4195
    – mlncn
    Nov 18, 2019 at 21:41
  • And no one taught that naming this "theme_directory" would have been better than "directory"?
    – gagarine
    Jul 15, 2022 at 0:06
18
<img src="/{{ directory }}/images/logo.png"/> 

worked for me when

<img src="{{ base_path ~ directory }}/images/logo.png" alt="My Logo" />

did not

for content template, i had to use in .module

   function hook_preprocess(&$variables, $hook) {

  $module_handler = Drupal::service('module_handler');
  $path = $module_handler->getModule('myModuleName')->getPath();

  if(isset($variables['region']) && $variables['region'] == 'content'){
    $variables['module_path'] = $path;
    $variables['http_host'] = $_SERVER['HTTP_HOST'];

and

  <img src="{{ module_path }}/images/error404.png" />
  <img src="//{{ http_host }}/{{ module_path }}/images/error403.png" />
1
  • 3
    This answer should be marked as correct instead Oct 8, 2018 at 15:18
11

There is by default a {{ directory }} variable that you can use that points to your theme directory. The problem is, it's not absolute, just like the one you added. I think that's a bug in core because it should include the base path, but changing that would of course break existing sites that use it.

So you need to add a / in front of it; this would break if Drupal is installed in a subfolder. You can either hardcode that in your template or keep using base_path() as you did in 7.x in a custom variable.

2
  • How to use image from /sites/default/files/MyFolder ? I have a image MyImage.jpg in MyFolder. Now, in twig template if i wrote <img src={{ url }} alt={{ text }}> Here url variable has the path /MyFolder/MyImage.jpg but, it is not working. May 27, 2016 at 9:29
  • 3
    As Berdir wrote: one can simply use <img src="/{{ directory }}/path/to/image"/> to get an absolute path.
    – daniels
    May 11, 2017 at 20:38
5

To print an image url that is inside your custom theme use the following construction:

{% set icon_path = [
  url('<front>')|render|trim('/', 'right'),
  active_theme_path(),
  'relative/path/to/image.png'
]|join('/') %}

<img src="{{ icon_path }}" alt="uncategorized"/>

If you have already installed twig_tweak module then you can reuse drupal_url function:

<img src="{{ drupal_url(active_theme_path() ~ '/relative/path/to/image.png', {absolute: true}) }}" alt="uncategorized"/>
1
  • This is the most up to date and complete response. Aug 12, 2022 at 5:20
0
<img src="{{ base_path ~ '/modules/custom/YOUR_MODULE_NAME/images/logo.png' }}" />

The above line works for loading images in Twig template where both are placed in your custom module without any need to add $base_path to hook_preprocess.

1
  • Used on Drupal 9.4
    – Ales Rebec
    Jan 24 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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