Get assets urls from assetic group in controller (not template) Symfony2 - php

I wonder if how could I load an assetic group of assets from inside my controller.
my config.yml:
assetic:
assets:
systemassets:
inputs:
- 'bundles/belkapanel/js/*.js'
- 'bundles/belkapanel/router.js'
Using twig, the solution is very simple:
{% javascripts '#systemassets'%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
it will resolve the path wildcard and generate an single .js file with the content of all files found inside "systemassets".
However, I want to get the generated .js file inside an controller. I know it is possible, but reading the symfony's assetic-bundle I only found AsseticHelper with "javascripts" method, but I don't know how to use it, I think it is used after the packagename and wildcards are resolved.
/** #var DynamicAsseticHelper $asseticDynamic */
$asseticDynamic = $this->get('assetic.helper.dynamic');
$assets = $asseticDynamic->javascripts('systemassets'); // Doesn't work!
I'm looking at AsseticTokenParser, I think it is the solution, am I right? can someone help me find the solution?

This should work:
$assets = $asseticDynamic->javascripts(array('#systemassets'));
See this documentation chapter for more details (check PHP version).

Related

How to use multiple routes to one controllerAction with Symfony3

I would like to configure multiple URLs to one Action in Controller (internationalization purposes).
According to this answer it was surely possible in symfony2 to:
Make double annotation route.
Use 3rd party Bundle (for example "BeSimple's").
But I'm using Symfony 3.0.3 which prohibits me from doing so until I change the route's name (example):
/**
* #Route("/welcome", name="welcome", defaults={"_locale" = "en"})
* #Route("/bienvenue", name="welcomeFR", defaults={"_locale" = "fr"})
* #Route("/willkommen", name="welcomeDE", defaults={"_locale" = "de"})
*/
But adding additional "FR/DE" chars to routes change their presence and ruins my URL generating logic in template, I'm forced to make on all links:
{# homepage example #}
{% if _locale = 'en' %}
{{ path('welcome') }} {# Routes from set only for "en" #}
{% elseif _locale = 'fr' %}
{{ path('welcomeFR') }} {# "fr" only links #}
{% endif %} {# and so on #}
Anyone found the proper solution for this problem?
AFAIK, this is the preferred way to point multiple routes to an unique controller action. So, your current problem is to regenerate the current path, depending on which route is being used
Maybe you don't have to modify your logic if you use {{ app.request.get('_route') }} to get the name of your current routing. This way, you could use:
{{ path(app.request.get('_route')) }}
UPDATE:
What about create an action per route and forwarding them to the main language action? Maybe it is not the best practice, but could work fine
/**
* #Route("/welcome", name="welcome", defaults={"_locale" = "en"})
*/
public function welcomeAction()
{
/* code here */
}
/**
* #Route("/bienvenue", name="welcomeFR", defaults={"_locale" = "fr"})
*/
public function welcomeFrAction()
{
$response = $this->forward('AppBundle:ControllerName:welcome');
}
/*
* #Route("/willkommen", name="welcomeDE", defaults={"_locale" = "de"})
*/
public function welcomeDeAction()
{
$response = $this->forward('AppBundle:ControllerName:welcome');
}
After wasting 10 hours on finding solution on Symfony3 I've made those assumptions:
None of the route trick with exactly same "name" wouldn't work,
Any kind like double annotation, double "routing.yml" importing, host based matching gives the same effect - only one route is matched, usually the last one. Would be ("/willkommen", name="welcomeDE") in my example.
Both of the i18n bundles does not work on Symfony3 through the versioning constraints,
Composer wouldn't even let us install the bundle.
Locale Listener and Loader (Routing Component) is dying on caching.
My solution to match the "_locale" and pass it to the LocaleLoader in order to load "routing_en.yml/routing_fr.yml" etc. files respectively is cached on the first match by the Symfony and after that, changing the "_locale" does not affect route's mapping.
In conclusion
Symfony3 seems not supporting route "example" with more than one "url" at all. Through the constraints and caching.
After the disappointment I'm considering going back to Symfony 2.8, have no idea what was pointing Symony's masters to block "double annotation" solution and what is their current idea on links internationalization.
Hope someday it will be possible to achieve with S3, as link i18n is quite common SEO practice.
EDIT: Confirmed, working like a charm on 2.8.5 with BeSimple's i18n.

Using locateResource inside Twig Extension

I wish to use the following inside of a Twig Extension
$kernel = $container->getService('kernel');
$path = $kernel->locateResource('#AdmeDemoBundle/path/to/file/Foo.png');
but this involved passing in the Kernel, which is bad. Plus I could not get it to work anyway when trying this method.
How can I access a resources path within a Twig Extension?
The Extension is already a Service. I can use Assetic to give me the URL, but I really want the path.
I had a similar need: i needed to pass to the filter the url of an image to display it in a for loop and build a string.
I passed the URL directly to the filter in this way:
{% image '#AppBundle/Resources/public/images/my_asset.png' %}
{% set resolved_asset_url = asset_url %}
{% endimage %}
{{ my_var|filter_name(resolved_asset_url)|raw(html) }}
In this way the Twig template resolve the correct resource's URL, sets it as a variable, and then I pass it to the filter from inside the template itself, without having to deal with kernel or something else.
If you want just to serve a download, you should create a Route that accomplishes that task.
In this way, you'll call the locator inside the route, and a simple
{{ path('route_that_does_the_locator_thing') }}
will be fine.
If you need instead to include a file in your template (ex. CSS, JS..), you need to declare your file as an asset, maybe using Assetic.

Is It Possible to Register or Publish Asset Files css,js from Bundle in Symfony 2

How to register js,css file to head tag from inside bundle automatically? so we don't need to add it manually to layout.
In zend framework there is HeadScript and InlineScript Helper, prepend or append method to do this. How about symfony2 ? is it possible too?
In zend framework we can register it like this from module bootstrap :
public function onBootstrap($e) {
$sm = $e->getApplication()->getServiceManager();
$headLink = $sm->get('viewhelpermanager')->get('headLink');
$headLink->appendStylesheet('/assets/MyModule/css/mystylesheet.css');
}
I mean, I want register it from e.g AcmeBlogBundle.php so we don't need to add manually to <head></head> in layout.
I'm not sure if this is what you are looking for, but check this out, this shows you how to include every js-file inside a directory, without listing them all manually.
You can't do it like in Zend. But you can define the appropriate block with js in base layout only once. And then from any template you can put anything you want into this block. Symfony implements a bit different logic than Zend does.
In your layout:
<head>
{% block custom_head_js %}
<some basic js files for all the pages>
{% endblock%}
</head>
In your templeate:
{% block custom_head_js
'#YourBundleNamespace/YourBundleName/Resources/public/js/your_js_filename.js'
%}
<script src="{{ asset_url }}"></script>
{% endblock %}
So, as I said it's not necessary to change base layout every time you want to add js into 'head' js files - you have to do it only once.

How to reference named Assetic assets in a Twig template?

AsseticBundle gives a possibility to define named assets in the Symfony's configuration file. How can I reference them in Twig templates, with {% javascripts %} and {% stylesheets %} Twig tags?
Symfony's own Assetic documentation mentions only special notation for #BundleName/Resources/file.cs to include bundle assets, but tells nothing about the named assets.
Question Symfony2: How to properly include assets in conjunction with Twig template inheritance? has a short mention in the comments that this is possible, but does not tell how to do it.
Using only the asset's given name (like jquery in the Assetic's own Readme) does not work. Assetic tries to look the file web/jquery that apparently does not exist.
The short version:
Use "#name" in your templates:
The longer version:
If your assetic configuration looks like this :
[config.yml]
assetic:
assets:
bootstrap_css:
inputs:
- %kernel.root_dir%/../web/components/bootstrap/css/bootstrap.css
- %kernel.root_dir%/../web/components/bootstrap/css/bootstrap-theme.css
jquery_ui_css:
....
Now you can use this in your templates, for example in your base.html.twig
<html><head>
...
{% stylesheets output='compiled/main.css'
"#bootstrap_css"
"#jqueryui_css"
...etc
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
</head></html
This one also defines that all css that is in there should be concatenated into one main.css file in the compiled directory.

Symfony2 - Include template from current bundle

I've not been able to find anything useful about this in the Twig or Symfony2 documentation, so thought I would ask here.
Does anybody know if it's possible to include a Twig template in Symfony2 relative to the current bundle, without specifying the name? Something along these lines:
{% include .:Foo:bar.html.twig %}
I'm just a bit fed up of having to enter the long, ugly bundle name when they're all in the same bundle. Also means if the bundle name ever changed for whatever reason, I'd have to find & replace every single include.
Back in the days when I was using bundles, I came up with a quick solution that you could base upon:
{% set bundle = app.request.get('_template').get('bundle') %}
{% set controller = app.request.get('_template').get('controller') %}
{% include bundle ~ ':' ~ controller ~ ':foo.html.twig' %}

Categories