27

I want to use the base path in a Drupal 8 template file. I tried the following, but I don't get the correct result.

{{ app.request.baseUrl  }}

{{base_path}}

What I need is the absolute path to the node {{ app.request.baseUrl }}/{{ url }}.

One solution I found is putting this code in a preprocess hook, and pass it to the theme.

 $host = \Drupal::request()->getHost(); 
$response = \Drupal::httpClient()

I am looking for a better solution. What could should I use instead of the one I am using?

8 Answers 8

49

You can use url() to generate a base url to any route in Drupal. You can supply the <front> route which, in effect, will be your base URL.

{{ url('<front>') }}

But, render it first if you're concatenating it:

{{ url('<front>')|render ~ file_url('public://image.jpg') }}

For example:

{{ url('<front>') ~ file_url('public://image.jpg') }}
# Outputs: "Array/sites/all/default/files/image.jpg"

{{ url('<front>')|render ~ file_url('public://image.jpg') }}
# Outputs: "http://example.com/sites/all/default/files/image.jpg"
3
  • 2
    and if I want get node absolute path?
    – Yuseferi
    Commented Jun 26, 2016 at 17:28
  • 3
    In a node context, the path() function can be applied to retrieve node route: {{ path('entity.node.canonical', {'node': node.id}) }}
    – Shawn Conn
    Commented Jun 26, 2016 at 17:39
  • when i try {{ url('<front>')|render ~ file_url('public://image.jpg') }} i get example.com//sites/mysite/files/image.jpg - NOTE, the double // between front and public file path.
    – liquidcms
    Commented Apr 21, 2020 at 21:53
17

In page.html.twig you will have a working {{ base_path }} variable. Why it isn't available in every template, i have no idea. As i think it should be and everything else looks messy, my preferred solution is to do exactly as Drupal does in the preprocess page function for any place i need it.

To make {{ base_path }} available to block templates in a theme named example, add this code to the example.theme file:

/**
 * Implements hook_preprocess_block().
 */
function example_preprocess_block(&$variables) {

  $variables['base_path'] = base_path();
}

As noted in the accepted answer provided by MPD, if getting a node's or other entity's URL there are methods to do it all for you.

However, there are reasons for getting the base_path, such as when displaying images that live in your theme folder. {{ directory }} provides the path to the theme folder, but it leaves off the base path (usually just a / but in order to preserve Drupal's proper functioning from a subdirectory of a domain that shouldn't be hardcoded). On page.html.twig or in any template which has the above preprocesser, this will work for that purpose:

<img src="{{ base_path ~ directory }}/images/nsf1.svg"
     alt="National Science Foundation logo" height="80" width="80" />

And of course Shawn Conn's answer works fine if you can suppress your desire for pretty templates, but i couldn't.

1
  • base_path() is returning "/" in the "hook_preprocess_block" but if I use it in "hook_preprocess" I get the absolute url of my domain, why is this?
    – DarkteK
    Commented Mar 28, 2021 at 22:41
13

You almost never need to explicitly build up paths from parts in Drupal 8. I would go with something like this:

function FOO_preprocess_node(&$variables) {
  /** @var \Drupal\node\NodeInterface $node */
  $node = $variables['node'];
  $variables['url'] = $node->toUrl('canonical', [
    'absolute' => TRUE,
    'language' => $node->language(),
  ])->toString();
}
4
  • pologize me to edit your answer, but url now is a object, we should convert it to string.
    – Yuseferi
    Commented Jun 27, 2016 at 7:32
  • 2
    No, you don't need to do that, the template can handle the url object.It is nice to other modules to keep the object, so that anyone can change it it at any stage, before it gets rendered finally in twig.
    – 4uk4
    Commented Jun 27, 2016 at 9:21
  • @4k4 but I tried without toString but noting show, then I tried kint(url) and saw it is object.
    – Yuseferi
    Commented Jun 27, 2016 at 9:38
  • I agree with @4k4 that it should not be converted into string and left as object so that other methods/functions consuming it are not affected. Commented Jan 26, 2019 at 15:43
12

All of the above failed for me, because I have language paths setup, so my front page URL looks like https://example.com/en.

I ended up using this code to get the actual base URL for my site:

{% set base_url = url('<front>')|render|split('/', -1)|join('/') %}
0
4

And According to Page Documentation on 8.2.x , two global variables added to return front page and Base Path Urls :

front_page: The URL of the front page. Use this instead of base_path when linking to the front page. This includes the language domain or prefix.

base_path: The base URL path of the Drupal installation. Will usually be "/" unless you have installed Drupal in a sub-directory.

So you can get font page Url with front_page and base Url with base_url

Note

getting front page url with {{ url('<front>') }} has a issue when you want concat it with other path, as example

{%  set base_url = url('<front>')  %}
{% set url = [ base_url,'/landing-page?invitecode=' ,invite_code] | join  %}
{{ url }}

return

Array/landing-page?invitecode= 

this mean by default is not text and return a render able array to twig

4

So far this thread doesn't bring any proper solution. We can concatenate it by using render_val()

Here is the way I used it, to get the absolute path of an entity image:

{% set base_url = render_var(url('<front>'))  %}
{% set url = base_url|trim('/', 'right')~file_url(content.field_media[0]['#media'].get('field_image').entity.uri.value)  %}

1st we get the base URL of the site. Then we need to remove an extra /. Then we concatenate our base path with our image relative path.

3

In

function hook_preprocess(&$variables) {
  $variables['base_path'] = base_path();
}

& in template file u can call via

{{ base_path ~ directory }}
2
{{ path('<front>') }}

I know you've already marked this as correct, but this can be used as a twig element in a template file without any extra work. I found this in the block--system-branding-block.html.twig from the Classy theme. So you can use it like this:

<a href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>

Your Answer

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

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