Is it possible on Symfony2 use assets_version by file?
We are using assets_version and assets_version_format to
An easy and quick workaround is something like this:
{% set asset_version = 'xyz' %}
{% javascripts 'bundles/webapp/js/app.js'
'bundles/webapp/js/utils.js'
filter='?closure' %}
<script src="{{ asset_url }}?{{ asset_version }}"></script>
{% endjavascripts %}
But you might want to move the logic to a twig extension receiving asset_url as argument.
The normal procedure would be to generate hashes of the files which will then be stored in a user cache.
You could then compare all the hashes against their current ones in a custom command and append the latest hash or something else to the filename to force a cache update.
The following solution will append a timestamp instead of a version number. The important part is that he timestamp will only change when you clear your cache.
First create a compiler pass:
<?php
namespace App\Bundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
/**
* Created by PhpStorm.
* User: hpenny
* Date: 15/03/17
* Time: 2:33 PM
*/
class AssetCompilerPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
$container->removeDefinition('assets._version__default');
$decorator = new DefinitionDecorator('assets.static_version_strategy');
$decorator->replaceArgument(0, time());
$container->setDefinition('assets._version__default', $decorator);
}
}
Then add it to your main bundle:
namespace App\Bundle;
use App\Bundle\DependencyInjection\Compiler\AssetCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new AssetCompilerPass());
}
}
This will only work on the default asset package. You would need to loop through the different package definitions you have set up if you are using that feature.
You would need to replace assets._version_<package name>
instead of assets._version__default
After many days searching I found the packages option on AsseticBundle
http://symfony.com/doc/2.0/reference/configuration/framework.html#full-default-configuration
Using that config option I could do something like this:
{% javascripts file package='packageName' %}
or
{{asset(file,packageName)}}
config.yml
framework:
templating:
engines: ['twig']
assets_version: %assets_version%
assets_version_format: "stv%%2$s/%%1$s"
packages:
css:
version: 6.1
version_format: "stv%%2$s/%%1$s"
jsApp:
version: 4.2
version_format: "stv%%2$s/%%1$s"
sometemplate.html.twig
<link rel=stylesheet href='{{ asset('bundles/webapp/css/funCommon.css','css') }}'>
{% javascripts 'bundles/webapp/js/app.js'
'bundles/webapp/js/utils.js'
filter='?closure'
package='jsApp'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
The output of this is:
<link rel=stylesheet href="http://static.domain.com/stv6.1/css/HASH.css">
<script src="http://static.domain.com/stv4.2/js/HASH.js"></script>
For me that was the simplest way to manage assets version by file.
If you're trying to use the assets_version parameter with the javascripts or stylesheets helpers, you still need to use the asset helper as well.
{% javascripts 'bundles/webapp/app.js'
'bundles/webapp/utils.js'
filter='?closure' %}
<script src="{{ asset(asset_url) }}" type="text/javascript"></script>
{% endjavascripts %}
It is not added to asset_url automatically (which is a good thing).