72

I have an application with Symfony2 (2.2). When I want to send a mail, I'm having trouble with the paths, which are all relative paths and obviously aren't working inside emails

for rendering the paths I'm using:

<a href="{{ path('route_name', {'param' : value}) }}">A link</a>

and for assets:

<img src="{{ asset('bundle/myname/img/image.gif') }}" alt="Title"/>

The previous examples work fine but the paths are relative therefore I need to append the domain. I can do something like:

<a href="http://example.com{{ path('route_name', {'param' => param1}) }}">A link</a>

but this is not the best solution for my problem, as I have different domains.

I found the solution for paths with the url function but I still need a solution for assets.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
rkmax
  • 17,633
  • 23
  • 91
  • 176

10 Answers10

137

Symfony 2.7 has a new absolute_url which can be used to generate the absolute url. http://symfony.com/blog/new-in-symfony-2-7-the-new-asset-component#template-function-changes

It will work on those both cases or a path string:

<a href="{{ absolute_url(path('route_name', {'param' : value})) }}">A link</a>

and for assets:

<img src="{{ absolute_url(asset('bundle/myname/img/image.gif')) }}" alt="Title"/>

Or for any string path

<img src="{{ absolute_url('my/absolute/path') }}" alt="Title"/>

on those tree cases you will end up with an absolute URL like

http://www.example.com/my/absolute/path
Neto Buenrostro
  • 1,477
  • 1
  • 10
  • 10
85

For Symfony 2.7 and newer

See this answer here.

1st working option

{{ app.request.scheme ~'://' ~ app.request.httpHost ~ asset('bundles/acmedemo/images/search.png') }}

2nd working option - preferred

Just made a quick test with a clean new Symfony copy. There is also another option which combines scheme and httpHost:

{{ app.request.getSchemeAndHttpHost() ~ asset('bundles/acmedemo/images/search.png') }}
{# outputs #}
{# http://localhost/Symfony/web/bundles/acmedemo/css/demo.css  #}
Community
  • 1
  • 1
SirDerpington
  • 11,260
  • 4
  • 49
  • 55
  • 4
    you can shortcut this to {{ app.request.getSchemeAndHttpHost ~ asset('images/foo.jpg') }} ah didnt see your update :D – john Smith May 12 '14 at 09:33
  • 4
    This answer seems to be somewhat outdated. See the answer from Neto form Sep 24 '15. – BHarms May 16 '16 at 21:46
53

From Symfony2 documentation: Absolute URLs for assets were introduced in Symfony 2.5.

If you need absolute URLs for assets, you can set the third argument (or the absolute argument) to true:

Example:

<img src="{{ asset('images/logo.png', absolute=true) }}" alt="Symfony!" />
Daniel
  • 531
  • 4
  • 4
27

Daniel's answer seems to work fine for now, but please note that generating absolute urls using twig's asset function is now deprecated:

DEPRECATED - Generating absolute URLs with the Twig asset() function was deprecated in 2.7 and will be removed in 3.0. Please use absolute_url() instead.

Here's the official announcement: http://symfony.com/blog/new-in-symfony-2-7-the-new-asset-component#template-function-changes

You have to use the absolute_url twig function:

{# Symfony 2.6 #}
{{ asset('logo.png', absolute = true) }}

{# Symfony 2.7 #}
{{ absolute_url(asset('logo.png')) }}

It is interesting to note that it also works with path function:

{{ absolute_url(path('index')) }}
Quentin S.
  • 1,462
  • 20
  • 18
13

You probably want to use the assets_base_urls configuration.

framework:
    templating:
        assets_base_urls:
            http:   [http://www.example.com]
            ssl:   [https://www.example.com]

http://symfony.com/doc/current/reference/configuration/framework.html#assets


Note that the configuration is different since Symfony 2.7:

framework:
    # ...
    assets:
        base_urls:
            - 'http://cdn.example.com/'
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
cheesemacfly
  • 11,622
  • 11
  • 53
  • 72
4

It's possible to have http://test.example and https://production.example. Then hard coding the URL is a bad idea. I would suggest this:

{{app.request.scheme ~ '://' ~ app.request.host ~ asset('bundle/myname/img/image.gif')}}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Iliya Kolev
  • 406
  • 3
  • 4
3

The following works for me:

<img src="{{ asset('bundle/myname/img/image.gif', null, true) }}" />
Indivision Dev
  • 1,097
  • 11
  • 16
3

This is working at least in newer Symfony projects:

{{ absolute_url(asset('bundle/myname/img/image.gif')) }}
Johannes Reiners
  • 570
  • 5
  • 11
2

Additional info to generate absolute URL using a command (to send an email for instance)

In a command, {{ absolute_url(path('index')) }} is not working out of the box.

You will need to add the additional configuration shown in antongorodezkiy's answer.

But in case you don't want to change the configuration because you are not sure how it could impact the whole app, you can configure the router in the command.

Here is the doc :

https://symfony.com/doc/3.4/console/request_context.html

Here is the code :

use Symfony\Component\Routing\RouterInterface;
// ...

class DemoCommand extends Command
{
    private $router;

    public function __construct(RouterInterface $router)
    {
        parent::__construct();

        $this->router = $router;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $context = $this->router->getContext();
        $context->setHost('example.com');
        $context->setScheme('https');
        $context->setBaseUrl('my/path');

        $url = $this->router->generate('route-name', ['param-name' => 'param-value']);
        // ...
    }
}

To generate the URL in the Twig template

<a href="{{ absolute_url(path(...)) }}"></a>

You can fetch the HOST and SCHEME from your env file

$context = $this->router->getContext();
$context->setHost($_ENV['NL_HOST']);
$context->setScheme($_ENV['NL_SCHEME']);

Just define the variable in .env and .env.local files

NL_HOST=mydomain.com
NL_SCHEME=https
Kaizoku Gambare
  • 3,143
  • 3
  • 29
  • 41
1

I've used the following advice from the docs https://symfony.com/doc/current/console/request_context.html to get absolute urls in emails:

# config/services.yaml
parameters:
    router.request_context.host: 'example.org'
    router.request_context.scheme: 'https'
gorodezkiy
  • 3,299
  • 2
  • 34
  • 42