Symfony asset url when running from console - php

I want to add a asset (image) full url (with domain and base) in a twig template when running from a command line (Console Command). It's meant to be sent to email.
The problem is, using absolute_url(asset()) doesn't include the host and base path when running on console.
Also, as specificed in http://symfony.com/doc/current/console/request_context.html, it just works for urls, not for assets.
I've also tried to set the router context when running from console:
$context = $this->getContainer()->get('router')->getContext();
$context->setHost($defaultDomain);
$context->setScheme($scheme);
With no success. Any idea?

To configure the Request Context - which is used by the URL Generator - you can redefine the parameters it uses as default values to change the default host (localhost) and scheme (http)
# app/config/parameters.yml
parameters:
router.request_context.host: example.org
router.request_context.scheme: https
router.request_context.base_url: my/path
http://symfony.com/doc/current/console/request_context.html
#command
/** #var \Twig_Environment $twig */
$twig = $this->getContainer()->get('twig');
die($twig->render('view.html.twig'));
#view.html.twig
{{ absolute_url(asset('images/logo.png')) }}
#output
https://example.org/images/logo.png

In my application, special for this situation with emails, i added global variable into Twig configuration:
# app/config/config.yml
twig:
globals:
site_addr: "%site_addr%"
And setting this variable in parameters.yml
# app/config/parameters.yml
site_addr: https://some.site
And at last, in each email template i used this:
# AppBundle/Resources/views/Emails/layout.html.twig
<img src="{{ site_addr ~ asset('SomeAssetName') }}"/>

You have to define base_urls parameter.
framework:
assets:
base_urls: ['http://localhost:8000']

You can use this solution which doesn't require adding any variable or parameter on config and is the same function that is used by Twig for {{ absolute_url() }}
public function yourAction(AssetsHelper $assetsHelper, HttpFoundationExtension $httpExtension)
{
$assetsPath = $assetsHelper->getUrl('/img/test.jpg');
$assetFullUrl = $httpExtension->generateAbsoluteUrl($assetPath);
}
The complete url of your asset will be on $assetFullUrl

Related

Change the host (and port) generated by the symfony/twig url helper

My Symfony app runs as a docker service. So internally it listens to localhost:80. But to reach it from the host machine (on osx, so using docker-machine) I reach it via http://192.168.99.100:8080
Whenever I let twig generate a full url ({{ url('register') }} for example), it generates a url with localhost as the host.
How can I change that to the ip:port combo I need?
You can achieve it by override router context params (host, port) in event listener of kernel.request.
Check this answer https://stackoverflow.com/a/31859779/1007620
Your onRequest() method should looks like this:
public function onRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$this->router->getContext()->setHost('192.168.99.100');
$this->router->getContext()->setHttpPort('8080');
$this->router->getContext()->setHttpsPort('8080');
}
In my question I didn't specify the url was being generated from a Command, because I didn't think it was relevant.
Based on the answer by #brevis I now know what to search for (router context), which brought me to this page: https://symfony.com/doc/current/console/request_context.html
On that page it says you should should add this:
# config/services.yaml
parameters:
router.request_context.host: 'example.org'
router.request_context.scheme: 'https'
router.request_context.base_url: 'my/path'
asset.request_context.base_path: '%router.request_context.base_url%'
asset.request_context.secure: true
Which is the simpler answer for this specific problem.

How to pass a variable to routing defaults in Symfony?

I have a Symfony2 project with multiple brandings (subdomains). Each subdomain should use the same site functions and the same routes (with different hostname). Therefor I want to make the subdomain in the route path to a variable. Now it looks like:
mybundle_route:
resource: "#MyProjectBundle/Controller/"
type: annotation
prefix: /
host: "{subdomain}.%base_host%"
requirements:
subdomain: sub1|sub2
and the routing itself works. But if I try to generate some routes (e.g. in twig), I get following error because no subdomain variable is set:
Some mandatory parameters are missing ("subdomain") to generate a URL for route "company_route".
I don't want to add the parameter to each path() function in the project.
It works perfekt for one subdomain if I add the defaults like this:
defaults:
subdomain: sub1
but the routes are wrong for the other subdomains. Also it doesn't work with
defaults:
subdomain: "%subdomain%"
All I need is to pass the %subdomain% variable to the defaults or to set it somewhere in the controller constructor. But I can't find the way how it is going. I would appreciate any help.
If there is no better solution you could try to set %subdomain% parameter inside configuration file:
Create subdomain_parameter.php inside config folder.
Inside this file you have access to ther $container so you can manually retrieve current subdomain from the url and pass it to the container.
Import subdomain_parameter.php in the config.yml

Symfony2: LiipImagineBundle - Exception: Unable to generate a URL for the named route "_imagine_image_upload_thumbnail" as such route does not exist

I am using LiipImagineBundle
I have followed installing instruction as in the documentation
in AppKernel.php
new Liip\ImagineBundle\LiipImagineBundle(),
and in routing.yml
# app/config/routing.yml
_imagine:
resource: .
type: imagine
And in config.yml
#app/config/config.yml
liip_imagine:
filter_sets:
image_upload_thumbnail:
quality: 85
filters:
thumbnail: { size: [150, 150], mode: outbound }
and in my twig file
<img alt="{{ media.title|default('untitled') }}" src="{{ media.getWebPath | imagine_filter('image_upload_thumbnail') }}"/>
I get this error
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "_imagine_image_upload_thumbnail" as such route does not exist.")
What i have tried :
Cache clear
php app/console router:debug | grep imagine found none
Route dosen't exist and not registered
Validated that i have media/cache folder with the right permissions
Try the following:
remove the spaces:
{{ media.webPath|imagine_filter('...') }}
... or invoke as a function:
{{ imagine_filter( media.webPath, 'filtername', false ) }}
Twig seems to invoke imagine_filter as a twig function instead of as a twig filter.
You end up with media.webPath not being passed as an argument.
( tip: just use media.webPath instead of media.getWebPath - twig will automatically call the getter for you )
Actually the underlying function filter() accepts the image-path as the first and the filter-name as it's second argument.
The third argument (boolean) determines wether to generate a relative or absolute url - defaults to false (relative).
Curently imagine uses the filter-name as a route-name and tries to generate a url ... which of course doesn't work :)

how to access base url in twig from symfony 2 console?

I am porting my website which is in Kohana to Symfony 2 gradually. Right now I am writing backend command in Symfony2, e.g. cron to send email notifications.
How can I access base url in twig. Can I do some configuration so that accessing urls in twig from console and from http request to be same ?
I have already reffered to this,
http://symfony.com/doc/current/cookbook/console/sending_emails.html
http://symfony.com/doc/current/cookbook/templating/global_variables.html
here, it is given how to configure it, but it is not mentioned how to access it, I assume I have to use {{ router.request_context.host }}.
But my question is, isn't there any way to be consistent between console and HTTP ?
e.g. {{ url }} ?
Add following setting in parameters.yml,
router.request_context.scheme: http
router.request_context.host: domain.com
base_url: '%router.request_context.scheme%://%router.request_context.host%/'
and inside console command controller you can access like,
$host = $this->getContainer()->get('router')->getContext()->getHost();
$scheme = $this->getContainer()->get('router')->getContext()->getScheme();
$baseURL = $this->getContainer()->getParameter('base_url');
First, you must set the url (you're calling it base_url) in a route by adding the following lines to /app/config/routing.yml:
base_url:
pattern: /
After that, you must set the router.request_context parameters as mentioned in the Symfony cookbook.
Now that everything's setup, you can simply use the same url functions in Twig as you would do in your webpages:
{{ url('base_url') }}
This worked for me.
In config.yml:
twig:
globals:
base_url: "http://www.example.com/"
In twig template:
{{ base_url }}

symfony2: how to access service from template

If I created a service is there a way to access it from twig, without creating a twig.extension?
You can set the service a twig global variable in config.yml, e.g
#app/config/config.yml
twig:
globals:
your_service: "#your_service"
And in your template.html.twig file you can invoke your service this way:
{{ your_service.someMethod(twig_variable) }}
See here.
To get this done in Symfony 5, first you must declare the service in services.yaml, for example:
App\Service\NavigationHelper:
arguments:
foo: bar
Then you can declare the service for its use in Twig. To achieve this, you must add it as a variable in the "globals" section of the Yaml file located in packages/twig.yaml:
globals:
navHelper: '#App\Service\NavigationHelper'
Now you can use your service methods from the templates as Mun Mun Das suggested in his last code snippet.

Categories